Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)