@@ -31,21 +31,28 @@ IdentifierLookup plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL;
3131 *
3232 * We keep reserved and unreserved keywords in separate arrays. The
3333 * reserved keywords are passed to the core scanner, so they will be
34- * recognized before (and instead of) any variable name. Unreserved
35- *words are checked for separately, after determining that the identifier
34+ * recognized before (and instead of) any variable name. Unreserved words
35+ * are checked for separately, usually after determining that the identifier
3636 * isn't a known variable name. If plpgsql_IdentifierLookup is DECLARE then
3737 * no variable names will be recognized, so the unreserved words always work.
3838 * (Note in particular that this helps us avoid reserving keywords that are
3939 * only needed in DECLARE sections.)
4040 *
4141 * In certain contexts it is desirable to prefer recognizing an unreserved
42- * keyword over recognizing a variable name. Those cases are handled in
43- * pl_gram.y using tok_is_keyword().
42+ * keyword over recognizing a variable name. In particular, at the start
43+ * of a statement we should prefer unreserved keywords unless the statement
44+ * looks like an assignment (i.e., first token is followed by ':=' or '[').
45+ * This rule allows most statement-introducing keywords to be kept unreserved.
46+ * (We still have to reserve initial keywords that might follow a block
47+ * label, unfortunately, since the method used to determine if we are at
48+ * start of statement doesn't recognize such cases. We'd also have to
49+ * reserve any keyword that could legitimately be followed by ':=' or '['.)
50+ * Some additional cases are handled in pl_gram.y using tok_is_keyword().
4451 *
45- *For the most part, the reserved keywordsare those that start a PL/pgSQL
46- *statement (and so would conflict with an assignment to a variable of the
47- *same name). We also don't sweat it much about reserving keywords that
48- *are reserved in the core grammar. Try to avoid reserving other words.
52+ *We try to avoid reserving more keywordsthan we have to; but there's
53+ *little point in not reserving a word if it's reserved in the core grammar.
54+ *Currently, the following words are reserved here but not in the core:
55+ *BEGIN BY DECLARE EXECUTE FOREACH IF LOOP STRICT WHILE
4956 */
5057
5158/*
@@ -63,37 +70,20 @@ static const ScanKeyword reserved_keywords[] = {
6370PG_KEYWORD ("begin" ,K_BEGIN ,RESERVED_KEYWORD )
6471PG_KEYWORD ("by" ,K_BY ,RESERVED_KEYWORD )
6572PG_KEYWORD ("case" ,K_CASE ,RESERVED_KEYWORD )
66- PG_KEYWORD ("close" ,K_CLOSE ,RESERVED_KEYWORD )
67- PG_KEYWORD ("collate" ,K_COLLATE ,RESERVED_KEYWORD )
68- PG_KEYWORD ("continue" ,K_CONTINUE ,RESERVED_KEYWORD )
6973PG_KEYWORD ("declare" ,K_DECLARE ,RESERVED_KEYWORD )
70- PG_KEYWORD ("default" ,K_DEFAULT ,RESERVED_KEYWORD )
71- PG_KEYWORD ("diagnostics" ,K_DIAGNOSTICS ,RESERVED_KEYWORD )
7274PG_KEYWORD ("else" ,K_ELSE ,RESERVED_KEYWORD )
73- PG_KEYWORD ("elseif" ,K_ELSIF ,RESERVED_KEYWORD )
74- PG_KEYWORD ("elsif" ,K_ELSIF ,RESERVED_KEYWORD )
7575PG_KEYWORD ("end" ,K_END ,RESERVED_KEYWORD )
76- PG_KEYWORD ("exception" ,K_EXCEPTION ,RESERVED_KEYWORD )
7776PG_KEYWORD ("execute" ,K_EXECUTE ,RESERVED_KEYWORD )
78- PG_KEYWORD ("exit" ,K_EXIT ,RESERVED_KEYWORD )
79- PG_KEYWORD ("fetch" ,K_FETCH ,RESERVED_KEYWORD )
8077PG_KEYWORD ("for" ,K_FOR ,RESERVED_KEYWORD )
8178PG_KEYWORD ("foreach" ,K_FOREACH ,RESERVED_KEYWORD )
8279PG_KEYWORD ("from" ,K_FROM ,RESERVED_KEYWORD )
83- PG_KEYWORD ("get" ,K_GET ,RESERVED_KEYWORD )
8480PG_KEYWORD ("if" ,K_IF ,RESERVED_KEYWORD )
8581PG_KEYWORD ("in" ,K_IN ,RESERVED_KEYWORD )
86- PG_KEYWORD ("insert" ,K_INSERT ,RESERVED_KEYWORD )
8782PG_KEYWORD ("into" ,K_INTO ,RESERVED_KEYWORD )
8883PG_KEYWORD ("loop" ,K_LOOP ,RESERVED_KEYWORD )
89- PG_KEYWORD ("move" ,K_MOVE ,RESERVED_KEYWORD )
9084PG_KEYWORD ("not" ,K_NOT ,RESERVED_KEYWORD )
9185PG_KEYWORD ("null" ,K_NULL ,RESERVED_KEYWORD )
92- PG_KEYWORD ("open" ,K_OPEN ,RESERVED_KEYWORD )
9386PG_KEYWORD ("or" ,K_OR ,RESERVED_KEYWORD )
94- PG_KEYWORD ("perform" ,K_PERFORM ,RESERVED_KEYWORD )
95- PG_KEYWORD ("raise" ,K_RAISE ,RESERVED_KEYWORD )
96- PG_KEYWORD ("return" ,K_RETURN ,RESERVED_KEYWORD )
9787PG_KEYWORD ("strict" ,K_STRICT ,RESERVED_KEYWORD )
9888PG_KEYWORD ("then" ,K_THEN ,RESERVED_KEYWORD )
9989PG_KEYWORD ("to" ,K_TO ,RESERVED_KEYWORD )
@@ -109,32 +99,47 @@ static const ScanKeyword unreserved_keywords[] = {
10999PG_KEYWORD ("alias" ,K_ALIAS ,UNRESERVED_KEYWORD )
110100PG_KEYWORD ("array" ,K_ARRAY ,UNRESERVED_KEYWORD )
111101PG_KEYWORD ("backward" ,K_BACKWARD ,UNRESERVED_KEYWORD )
102+ PG_KEYWORD ("close" ,K_CLOSE ,UNRESERVED_KEYWORD )
103+ PG_KEYWORD ("collate" ,K_COLLATE ,UNRESERVED_KEYWORD )
112104PG_KEYWORD ("column" ,K_COLUMN ,UNRESERVED_KEYWORD )
113105PG_KEYWORD ("column_name" ,K_COLUMN_NAME ,UNRESERVED_KEYWORD )
114106PG_KEYWORD ("constant" ,K_CONSTANT ,UNRESERVED_KEYWORD )
115107PG_KEYWORD ("constraint" ,K_CONSTRAINT ,UNRESERVED_KEYWORD )
116108PG_KEYWORD ("constraint_name" ,K_CONSTRAINT_NAME ,UNRESERVED_KEYWORD )
109+ PG_KEYWORD ("continue" ,K_CONTINUE ,UNRESERVED_KEYWORD )
117110PG_KEYWORD ("current" ,K_CURRENT ,UNRESERVED_KEYWORD )
118111PG_KEYWORD ("cursor" ,K_CURSOR ,UNRESERVED_KEYWORD )
119112PG_KEYWORD ("datatype" ,K_DATATYPE ,UNRESERVED_KEYWORD )
120113PG_KEYWORD ("debug" ,K_DEBUG ,UNRESERVED_KEYWORD )
114+ PG_KEYWORD ("default" ,K_DEFAULT ,UNRESERVED_KEYWORD )
121115PG_KEYWORD ("detail" ,K_DETAIL ,UNRESERVED_KEYWORD )
116+ PG_KEYWORD ("diagnostics" ,K_DIAGNOSTICS ,UNRESERVED_KEYWORD )
122117PG_KEYWORD ("dump" ,K_DUMP ,UNRESERVED_KEYWORD )
118+ PG_KEYWORD ("elseif" ,K_ELSIF ,UNRESERVED_KEYWORD )
119+ PG_KEYWORD ("elsif" ,K_ELSIF ,UNRESERVED_KEYWORD )
123120PG_KEYWORD ("errcode" ,K_ERRCODE ,UNRESERVED_KEYWORD )
124121PG_KEYWORD ("error" ,K_ERROR ,UNRESERVED_KEYWORD )
122+ PG_KEYWORD ("exception" ,K_EXCEPTION ,UNRESERVED_KEYWORD )
123+ PG_KEYWORD ("exit" ,K_EXIT ,UNRESERVED_KEYWORD )
124+ PG_KEYWORD ("fetch" ,K_FETCH ,UNRESERVED_KEYWORD )
125125PG_KEYWORD ("first" ,K_FIRST ,UNRESERVED_KEYWORD )
126126PG_KEYWORD ("forward" ,K_FORWARD ,UNRESERVED_KEYWORD )
127+ PG_KEYWORD ("get" ,K_GET ,UNRESERVED_KEYWORD )
127128PG_KEYWORD ("hint" ,K_HINT ,UNRESERVED_KEYWORD )
128129PG_KEYWORD ("info" ,K_INFO ,UNRESERVED_KEYWORD )
130+ PG_KEYWORD ("insert" ,K_INSERT ,UNRESERVED_KEYWORD )
129131PG_KEYWORD ("is" ,K_IS ,UNRESERVED_KEYWORD )
130132PG_KEYWORD ("last" ,K_LAST ,UNRESERVED_KEYWORD )
131133PG_KEYWORD ("log" ,K_LOG ,UNRESERVED_KEYWORD )
132134PG_KEYWORD ("message" ,K_MESSAGE ,UNRESERVED_KEYWORD )
133135PG_KEYWORD ("message_text" ,K_MESSAGE_TEXT ,UNRESERVED_KEYWORD )
136+ PG_KEYWORD ("move" ,K_MOVE ,UNRESERVED_KEYWORD )
134137PG_KEYWORD ("next" ,K_NEXT ,UNRESERVED_KEYWORD )
135138PG_KEYWORD ("no" ,K_NO ,UNRESERVED_KEYWORD )
136139PG_KEYWORD ("notice" ,K_NOTICE ,UNRESERVED_KEYWORD )
140+ PG_KEYWORD ("open" ,K_OPEN ,UNRESERVED_KEYWORD )
137141PG_KEYWORD ("option" ,K_OPTION ,UNRESERVED_KEYWORD )
142+ PG_KEYWORD ("perform" ,K_PERFORM ,UNRESERVED_KEYWORD )
138143PG_KEYWORD ("pg_context" ,K_PG_CONTEXT ,UNRESERVED_KEYWORD )
139144PG_KEYWORD ("pg_datatype_name" ,K_PG_DATATYPE_NAME ,UNRESERVED_KEYWORD )
140145PG_KEYWORD ("pg_exception_context" ,K_PG_EXCEPTION_CONTEXT ,UNRESERVED_KEYWORD )
@@ -143,8 +148,10 @@ static const ScanKeyword unreserved_keywords[] = {
143148PG_KEYWORD ("print_strict_params" ,K_PRINT_STRICT_PARAMS ,UNRESERVED_KEYWORD )
144149PG_KEYWORD ("prior" ,K_PRIOR ,UNRESERVED_KEYWORD )
145150PG_KEYWORD ("query" ,K_QUERY ,UNRESERVED_KEYWORD )
151+ PG_KEYWORD ("raise" ,K_RAISE ,UNRESERVED_KEYWORD )
146152PG_KEYWORD ("relative" ,K_RELATIVE ,UNRESERVED_KEYWORD )
147153PG_KEYWORD ("result_oid" ,K_RESULT_OID ,UNRESERVED_KEYWORD )
154+ PG_KEYWORD ("return" ,K_RETURN ,UNRESERVED_KEYWORD )
148155PG_KEYWORD ("returned_sqlstate" ,K_RETURNED_SQLSTATE ,UNRESERVED_KEYWORD )
149156PG_KEYWORD ("reverse" ,K_REVERSE ,UNRESERVED_KEYWORD )
150157PG_KEYWORD ("row_count" ,K_ROW_COUNT ,UNRESERVED_KEYWORD )
@@ -166,6 +173,19 @@ static const ScanKeyword unreserved_keywords[] = {
166173
167174static const int num_unreserved_keywords = lengthof (unreserved_keywords );
168175
176+ /*
177+ * This macro must recognize all tokens that can immediately precede a
178+ * PL/pgSQL executable statement (that is, proc_sect or proc_stmt in the
179+ * grammar). Fortunately, there are not very many, so hard-coding in this
180+ * fashion seems sufficient.
181+ */
182+ #define AT_STMT_START (prev_token ) \
183+ ((prev_token) == ';' || \
184+ (prev_token) == K_BEGIN || \
185+ (prev_token) == K_THEN || \
186+ (prev_token) == K_ELSE || \
187+ (prev_token) == K_LOOP)
188+
169189
170190/* Auxiliary data about a token (other than the token type) */
171191typedef struct
@@ -192,6 +212,9 @@ static const char *scanorig;
192212/* Current token's length (corresponds to plpgsql_yylval and plpgsql_yylloc) */
193213static int plpgsql_yyleng ;
194214
215+ /* Current token's code (corresponds to plpgsql_yylval and plpgsql_yylloc) */
216+ static int plpgsql_yytoken ;
217+
195218/* Token pushback stack */
196219#define MAX_PUSHBACKS 4
197220
@@ -315,31 +338,75 @@ plpgsql_yylex(void)
315338{
316339/* not A.B, so just process A */
317340push_back_token (tok2 ,& aux2 );
318- if (plpgsql_parse_word (aux1 .lval .str ,
319- core_yy .scanbuf + aux1 .lloc ,
320- & aux1 .lval .wdatum ,
321- & aux1 .lval .word ))
322- tok1 = T_DATUM ;
323- else if (!aux1 .lval .word .quoted &&
324- (kw = ScanKeywordLookup (aux1 .lval .word .ident ,
325- unreserved_keywords ,
326- num_unreserved_keywords )))
341+
342+ /*
343+ * If we are at start of statement, prefer unreserved keywords
344+ * over variable names, unless the next token is assignment or
345+ * '[', in which case prefer variable names. (Note we need not
346+ * consider '.' as the next token; that case was handled above,
347+ * and we always prefer variable names in that case.) If we are
348+ * not at start of statement, always prefer variable names over
349+ * unreserved keywords.
350+ */
351+ if (AT_STMT_START (plpgsql_yytoken )&&
352+ !(tok2 == '=' || tok2 == COLON_EQUALS || tok2 == '[' ))
327353{
328- aux1 .lval .keyword = kw -> name ;
329- tok1 = kw -> value ;
354+ /* try for unreserved keyword, then for variable name */
355+ if (core_yy .scanbuf [aux1 .lloc ]!= '"' &&
356+ (kw = ScanKeywordLookup (aux1 .lval .str ,
357+ unreserved_keywords ,
358+ num_unreserved_keywords )))
359+ {
360+ aux1 .lval .keyword = kw -> name ;
361+ tok1 = kw -> value ;
362+ }
363+ else if (plpgsql_parse_word (aux1 .lval .str ,
364+ core_yy .scanbuf + aux1 .lloc ,
365+ & aux1 .lval .wdatum ,
366+ & aux1 .lval .word ))
367+ tok1 = T_DATUM ;
368+ else
369+ tok1 = T_WORD ;
330370}
331371else
332- tok1 = T_WORD ;
372+ {
373+ /* try for variable name, then for unreserved keyword */
374+ if (plpgsql_parse_word (aux1 .lval .str ,
375+ core_yy .scanbuf + aux1 .lloc ,
376+ & aux1 .lval .wdatum ,
377+ & aux1 .lval .word ))
378+ tok1 = T_DATUM ;
379+ else if (!aux1 .lval .word .quoted &&
380+ (kw = ScanKeywordLookup (aux1 .lval .word .ident ,
381+ unreserved_keywords ,
382+ num_unreserved_keywords )))
383+ {
384+ aux1 .lval .keyword = kw -> name ;
385+ tok1 = kw -> value ;
386+ }
387+ else
388+ tok1 = T_WORD ;
389+ }
333390}
334391}
335392else
336393{
337- /* Not a potential plpgsql variable name, just return the data */
394+ /*
395+ * Not a potential plpgsql variable name, just return the data.
396+ *
397+ * Note that we also come through here if the grammar pushed back a
398+ * T_DATUM, T_CWORD, T_WORD, or unreserved-keyword token returned by a
399+ * previous lookup cycle; thus, pushbacks do not incur extra lookup
400+ * work, since we'll never do the above code twice for the same token.
401+ * This property also makes it safe to rely on the old value of
402+ * plpgsql_yytoken in the is-this-start-of-statement test above.
403+ */
338404}
339405
340406plpgsql_yylval = aux1 .lval ;
341407plpgsql_yylloc = aux1 .lloc ;
342408plpgsql_yyleng = aux1 .leng ;
409+ plpgsql_yytoken = tok1 ;
343410return tok1 ;
344411}
345412
@@ -645,6 +712,7 @@ plpgsql_scanner_init(const char *str)
645712
646713/* Other setup */
647714plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL ;
715+ plpgsql_yytoken = 0 ;
648716
649717num_pushbacks = 0 ;
650718