aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2012-09-26 22:27:36 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2012-09-26 22:27:36 -0400
commitbac95fd4740e3ac13baf5c2ad38b9c9dc26f9c9d (patch)
tree90f0303ee1be33cac6a93c5b0f2e75739193eebf /src
parentfc68ac86b1c8b19ec6a2064c8a24e1c124f77f7f (diff)
downloadpostgresql-bac95fd4740e3ac13baf5c2ad38b9c9dc26f9c9d.tar.gz
postgresql-bac95fd4740e3ac13baf5c2ad38b9c9dc26f9c9d.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/pl/plpgsql/src/gram.y57
-rw-r--r--src/pl/plpgsql/src/pl_scanner.c19
-rw-r--r--src/pl/plpgsql/src/plpgsql.h1
3 files changed, 74 insertions, 3 deletions
diff --git a/src/pl/plpgsql/src/gram.y b/src/pl/plpgsql/src/gram.y
index 4967a2a6a79..9c3d254a0f7 100644
--- a/src/pl/plpgsql/src/gram.y
+++ b/src/pl/plpgsql/src/gram.y
@@ -642,6 +642,21 @@ decl_aliasitem : T_WORD
parser_errposition(@1)));
$$ = nsi;
}
+ | unreserved_keyword
+ {
+ PLpgSQL_nsitem *nsi;
+
+ nsi = plpgsql_ns_lookup(plpgsql_ns_top(), false,
+ $1, NULL, NULL,
+ NULL);
+ if (nsi == NULL)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("variable \"%s\" does not exist",
+ $1),
+ parser_errposition(@1)));
+ $$ = nsi;
+ }
| T_CWORD
{
PLpgSQL_nsitem *nsi;
@@ -722,6 +737,11 @@ decl_collate :
$$ = get_collation_oid(list_make1(makeString($2.ident)),
false);
}
+ | K_COLLATE unreserved_keyword
+ {
+ $$ = get_collation_oid(list_make1(makeString(pstrdup($2))),
+ false);
+ }
| K_COLLATE T_CWORD
{
$$ = get_collation_oid($2.idents, false);
@@ -1720,9 +1740,12 @@ stmt_raise : K_RAISE
}
else
{
- if (tok != T_WORD)
+ if (tok == T_WORD)
+ new->condname = yylval.word.ident;
+ else if (plpgsql_token_is_unreserved_keyword(tok))
+ new->condname = pstrdup(yylval.keyword);
+ else
yyerror("syntax error");
- new->condname = yylval.word.ident;
plpgsql_recognize_err_condition(new->condname,
false);
}
@@ -2185,12 +2208,16 @@ opt_exitcond : ';'
;
/*
- * need both options because scanner will have tried to resolve as variable
+ * need to allow DATUM because scanner will have tried to resolve as variable
*/
any_identifier : T_WORD
{
$$ = $1.ident;
}
+ | unreserved_keyword
+ {
+ $$ = pstrdup($1);
+ }
| T_DATUM
{
if ($1.ident == NULL) /* composite name not OK */
@@ -2513,6 +2540,30 @@ read_datatype(int tok)
}
}
}
+ else if (plpgsql_token_is_unreserved_keyword(tok))
+ {
+ char *dtname = pstrdup(yylval.keyword);
+
+ tok = yylex();
+ if (tok == '%')
+ {
+ tok = yylex();
+ if (tok_is_keyword(tok, &yylval,
+ K_TYPE, "type"))
+ {
+ result = plpgsql_parse_wordtype(dtname);
+ if (result)
+ return result;
+ }
+ else if (tok_is_keyword(tok, &yylval,
+ K_ROWTYPE, "rowtype"))
+ {
+ result = plpgsql_parse_wordrowtype(dtname);
+ if (result)
+ return result;
+ }
+ }
+ }
else if (tok == T_CWORD)
{
List *dtnames = yylval.cword.idents;
diff --git a/src/pl/plpgsql/src/pl_scanner.c b/src/pl/plpgsql/src/pl_scanner.c
index ebce3fd860b..c78527c309a 100644
--- a/src/pl/plpgsql/src/pl_scanner.c
+++ b/src/pl/plpgsql/src/pl_scanner.c
@@ -411,6 +411,25 @@ plpgsql_push_back_token(int token)
}
/*
+ * Tell whether a token is an unreserved keyword.
+ *
+ * (If it is, its lowercased form was returned as the token value, so we
+ * do not need to offer that data here.)
+ */
+bool
+plpgsql_token_is_unreserved_keyword(int token)
+{
+ int i;
+
+ for (i = 0; i < num_unreserved_keywords; i++)
+ {
+ if (unreserved_keywords[i].value == token)
+ return true;
+ }
+ return false;
+}
+
+/*
* Append the function text starting at startlocation and extending to
* (not including) endlocation onto the existing contents of "buf".
*/
diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h
index dcf80743b88..7ea696033bb 100644
--- a/src/pl/plpgsql/src/plpgsql.h
+++ b/src/pl/plpgsql/src/plpgsql.h
@@ -973,6 +973,7 @@ extern void plpgsql_dumptree(PLpgSQL_function *func);
extern int plpgsql_base_yylex(void);
extern int plpgsql_yylex(void);
extern void plpgsql_push_back_token(int token);
+extern bool plpgsql_token_is_unreserved_keyword(int token);
extern void plpgsql_append_source_text(StringInfo buf,
int startlocation, int endlocation);
extern void plpgsql_peek2(int *tok1_p, int *tok2_p, int *tok1_loc,