From 399da7d882dff22b7ad926fb07aafeda2feab999 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 25 Jun 2010 16:40:13 +0000 Subject: [PATCH] Fix thinko in tok_is_keyword(): it was looking at the wrong union variant of YYSTYPE, and hence returning the wrong answer for cases where a plpgsql "unreserved keyword" really does conflict with a variable name. Obviously I didn't test this enough :-(. Per bug #5524 from Peter Gagarinov. --- src/pl/plpgsql/src/gram.y | 6 +++--- src/test/regress/expected/plpgsql.out | 14 ++++++++++++++ src/test/regress/sql/plpgsql.sql | 14 ++++++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/pl/plpgsql/src/gram.y b/src/pl/plpgsql/src/gram.y index e866d10a65..3a78fe69c7 100644 --- a/src/pl/plpgsql/src/gram.y +++ b/src/pl/plpgsql/src/gram.y @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.142 2010/03/03 01:53:17 tgl Exp $ + * $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.143 2010/06/25 16:40:13 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -2080,8 +2080,8 @@ tok_is_keyword(int token, union YYSTYPE *lval, * match composite names (hence an unreserved word followed by "." * will not be recognized). */ - if (!lval->word.quoted && lval->word.ident != NULL && - strcmp(lval->word.ident, kw_str) == 0) + if (!lval->wdatum.quoted && lval->wdatum.ident != NULL && + strcmp(lval->wdatum.ident, kw_str) == 0) return true; } return false; /* not the keyword */ diff --git a/src/test/regress/expected/plpgsql.out b/src/test/regress/expected/plpgsql.out index 619939ffa3..a22e2bfd0f 100644 --- a/src/test/regress/expected/plpgsql.out +++ b/src/test/regress/expected/plpgsql.out @@ -3578,6 +3578,20 @@ $$ language plpgsql; select raise_test(); ERROR: RAISE without parameters cannot be used outside an exception handler CONTEXT: PL/pgSQL function "raise_test" +-- check cases where implicit SQLSTATE variable could be confused with +-- SQLSTATE as a keyword, cf bug #5524 +create or replace function raise_test() returns void as $$ +begin + perform 1/0; +exception + when sqlstate '22012' then + raise notice using message = sqlstate; + raise sqlstate '22012' using message = 'substitute message'; +end; +$$ language plpgsql; +select raise_test(); +NOTICE: 22012 +ERROR: substitute message drop function raise_test(); -- test CASE statement create or replace function case_test(bigint) returns text as $$ diff --git a/src/test/regress/sql/plpgsql.sql b/src/test/regress/sql/plpgsql.sql index e181b10898..612e92d21b 100644 --- a/src/test/regress/sql/plpgsql.sql +++ b/src/test/regress/sql/plpgsql.sql @@ -2916,6 +2916,20 @@ $$ language plpgsql; select raise_test(); +-- check cases where implicit SQLSTATE variable could be confused with +-- SQLSTATE as a keyword, cf bug #5524 +create or replace function raise_test() returns void as $$ +begin + perform 1/0; +exception + when sqlstate '22012' then + raise notice using message = sqlstate; + raise sqlstate '22012' using message = 'substitute message'; +end; +$$ language plpgsql; + +select raise_test(); + drop function raise_test(); -- test CASE statement