Skip to content

Commit bac95fd

Browse files
committed
Make plpgsql's unreserved keywords more unreserved.
There were assorted places where unreserved keywords were not treated the same as T_WORD (that is, a random unrecognized identifier). Fix them. It might not always be possible to allow this, but it is in all these places, so I don't see any downside. Per gripe from Jim Wilson. Arguably this is a bug fix, but given the lack of other complaints and the ease of working around it (just quote the word), I won't risk back-patching.
1 parent fc68ac8 commit bac95fd

File tree

3 files changed

+74
-3
lines changed

3 files changed

+74
-3
lines changed

src/pl/plpgsql/src/gram.y

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,21 @@ decl_aliasitem : T_WORD
642642
parser_errposition(@1)));
643643
$$ = nsi;
644644
}
645+
| unreserved_keyword
646+
{
647+
PLpgSQL_nsitem *nsi;
648+
649+
nsi = plpgsql_ns_lookup(plpgsql_ns_top(), false,
650+
$1, NULL, NULL,
651+
NULL);
652+
if (nsi == NULL)
653+
ereport(ERROR,
654+
(errcode(ERRCODE_UNDEFINED_OBJECT),
655+
errmsg("variable \"%s\" does not exist",
656+
$1),
657+
parser_errposition(@1)));
658+
$$ = nsi;
659+
}
645660
| T_CWORD
646661
{
647662
PLpgSQL_nsitem *nsi;
@@ -722,6 +737,11 @@ decl_collate :
722737
$$ = get_collation_oid(list_make1(makeString($2.ident)),
723738
false);
724739
}
740+
| K_COLLATE unreserved_keyword
741+
{
742+
$$ = get_collation_oid(list_make1(makeString(pstrdup($2))),
743+
false);
744+
}
725745
| K_COLLATE T_CWORD
726746
{
727747
$$ = get_collation_oid($2.idents, false);
@@ -1720,9 +1740,12 @@ stmt_raise : K_RAISE
17201740
}
17211741
else
17221742
{
1723-
if (tok != T_WORD)
1743+
if (tok == T_WORD)
1744+
new->condname = yylval.word.ident;
1745+
else if (plpgsql_token_is_unreserved_keyword(tok))
1746+
new->condname = pstrdup(yylval.keyword);
1747+
else
17241748
yyerror("syntax error");
1725-
new->condname = yylval.word.ident;
17261749
plpgsql_recognize_err_condition(new->condname,
17271750
false);
17281751
}
@@ -2185,12 +2208,16 @@ opt_exitcond : ';'
21852208
;
21862209

21872210
/*
2188-
* need both options because scanner will have tried to resolve as variable
2211+
* need to allow DATUM because scanner will have tried to resolve as variable
21892212
*/
21902213
any_identifier : T_WORD
21912214
{
21922215
$$ = $1.ident;
21932216
}
2217+
| unreserved_keyword
2218+
{
2219+
$$ = pstrdup($1);
2220+
}
21942221
| T_DATUM
21952222
{
21962223
if ($1.ident == NULL) /* composite name not OK */
@@ -2513,6 +2540,30 @@ read_datatype(int tok)
25132540
}
25142541
}
25152542
}
2543+
else if (plpgsql_token_is_unreserved_keyword(tok))
2544+
{
2545+
char *dtname = pstrdup(yylval.keyword);
2546+
2547+
tok = yylex();
2548+
if (tok == '%')
2549+
{
2550+
tok = yylex();
2551+
if (tok_is_keyword(tok, &yylval,
2552+
K_TYPE, "type"))
2553+
{
2554+
result = plpgsql_parse_wordtype(dtname);
2555+
if (result)
2556+
return result;
2557+
}
2558+
else if (tok_is_keyword(tok, &yylval,
2559+
K_ROWTYPE, "rowtype"))
2560+
{
2561+
result = plpgsql_parse_wordrowtype(dtname);
2562+
if (result)
2563+
return result;
2564+
}
2565+
}
2566+
}
25162567
else if (tok == T_CWORD)
25172568
{
25182569
List *dtnames = yylval.cword.idents;

src/pl/plpgsql/src/pl_scanner.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,25 @@ plpgsql_push_back_token(int token)
410410
push_back_token(token, &auxdata);
411411
}
412412

413+
/*
414+
* Tell whether a token is an unreserved keyword.
415+
*
416+
* (If it is, its lowercased form was returned as the token value, so we
417+
* do not need to offer that data here.)
418+
*/
419+
bool
420+
plpgsql_token_is_unreserved_keyword(int token)
421+
{
422+
int i;
423+
424+
for (i = 0; i < num_unreserved_keywords; i++)
425+
{
426+
if (unreserved_keywords[i].value == token)
427+
return true;
428+
}
429+
return false;
430+
}
431+
413432
/*
414433
* Append the function text starting at startlocation and extending to
415434
* (not including) endlocation onto the existing contents of "buf".

src/pl/plpgsql/src/plpgsql.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -973,6 +973,7 @@ extern void plpgsql_dumptree(PLpgSQL_function *func);
973973
extern int plpgsql_base_yylex(void);
974974
extern int plpgsql_yylex(void);
975975
extern void plpgsql_push_back_token(int token);
976+
extern bool plpgsql_token_is_unreserved_keyword(int token);
976977
extern void plpgsql_append_source_text(StringInfo buf,
977978
int startlocation, int endlocation);
978979
extern void plpgsql_peek2(int *tok1_p, int *tok2_p, int *tok1_loc,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy