1 %{
2 /*-------------------------------------------------------------------------
3 *
4 * pl_gram.y - Parser for the PL/pgSQL procedural language
5 *
6 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/pl/plpgsql/src/pl_gram.y
12 *
13 *-------------------------------------------------------------------------
14 */
15
16 #include "postgres.h"
17
18 #include "catalog/namespace.h"
19 #include "catalog/pg_proc.h"
20 #include "catalog/pg_type.h"
21 #include "parser/parser.h"
22 #include "parser/parse_type.h"
23 #include "parser/scanner.h"
24 #include "parser/scansup.h"
25 #include "utils/builtins.h"
26
27 #include "plpgsql.h"
28
29
30 /* Location tracking support --- simpler than bison's default */
31 #define YYLLOC_DEFAULT(Current, Rhs, N) \
32 do { \
33 if (N) \
34 (Current) = (Rhs)[1]; \
35 else \
36 (Current) = (Rhs)[0]; \
37 } while (0)
38
39 /*
40 * Bison doesn't allocate anything that needs to live across parser calls,
41 * so we can easily have it use palloc instead of malloc. This prevents
42 * memory leaks if we error out during parsing. Note this only works with
43 * bison >= 2.0. However, in bison 1.875 the default is to use alloca()
44 * if possible, so there's not really much problem anyhow, at least if
45 * you're building with gcc.
46 */
47 #define YYMALLOC palloc
48 #define YYFREE pfree
49
50
51 typedef struct
52 {
53 int location;
54 int leaderlen;
55 } sql_error_callback_arg;
56
57 #define parser_errposition(pos) plpgsql_scanner_errposition(pos)
58
59 union YYSTYPE; /* need forward reference for tok_is_keyword */
60
61 static bool tok_is_keyword(int token, union YYSTYPE *lval,
62 int kw_token, const char *kw_str);
63 static void word_is_not_variable(PLword *word, int location);
64 static void cword_is_not_variable(PLcword *cword, int location);
65 static void current_token_is_not_variable(int tok);
66 static PLpgSQL_expr *read_sql_construct(int until,
67 int until2,
68 int until3,
69 const char *expected,
70 const char *sqlstart,
71 bool isexpression,
72 bool valid_sql,
73 bool trim,
74 int *startloc,
75 int *endtoken);
76 static PLpgSQL_expr *read_sql_expression(int until,
77 const char *expected);
78 static PLpgSQL_expr *read_sql_expression2(int until, int until2,
79 const char *expected,
80 int *endtoken);
81 static PLpgSQL_expr *read_sql_stmt(const char *sqlstart);
82 static PLpgSQL_type *read_datatype(int tok);
83 static PLpgSQL_stmt *make_execsql_stmt(int firsttoken, int location);
84 static PLpgSQL_stmt_fetch *read_fetch_direction(void);
85 static void complete_direction(PLpgSQL_stmt_fetch *fetch,
86 bool *check_FROM);
87 static PLpgSQL_stmt *make_return_stmt(int location);
88 static PLpgSQL_stmt *make_return_next_stmt(int location);
89 static PLpgSQL_stmt *make_return_query_stmt(int location);
90 static PLpgSQL_stmt *make_case(int location, PLpgSQL_expr *t_expr,
91 List *case_when_list, List *else_stmts);
92 static char *NameOfDatum(PLwdatum *wdatum);
93 static void check_assignable(PLpgSQL_datum *datum, int location);
94 static void read_into_target(PLpgSQL_variable **target,
95 bool *strict);
96 static PLpgSQL_row *read_into_scalar_list(char *initial_name,
97 PLpgSQL_datum *initial_datum,
98 int initial_location);
99 static PLpgSQL_row *make_scalar_list1(char *initial_name,
100 PLpgSQL_datum *initial_datum,
101 int lineno, int location);
102 static void check_sql_expr(const char *stmt, int location,
103 int leaderlen);
104 static void plpgsql_sql_error_callback(void *arg);
105 static PLpgSQL_type *parse_datatype(const char *string, int location);
106 static void check_labels(const char *start_label,
107 const char *end_label,
108 int end_location);
109 static PLpgSQL_expr *read_cursor_args(PLpgSQL_var *cursor,
110 int until, const char *expected);
111 static List *read_raise_options(void);
112 static void check_raise_parameters(PLpgSQL_stmt_raise *stmt);
113
114 %}
115
116 %expect 0
117 %name-prefix="plpgsql_yy"
118 %locations
119
120 %union {
121 core_YYSTYPE core_yystype;
122 /* these fields must match core_YYSTYPE: */
123 int ival;
124 char *str;
125 const char *keyword;
126
127 PLword word;
128 PLcword cword;
129 PLwdatum wdatum;
130 bool boolean;
131 Oid oid;
132 struct
133 {
134 char *name;
135 int lineno;
136 } varname;
137 struct
138 {
139 char *name;
140 int lineno;
141 PLpgSQL_datum *scalar;
142 PLpgSQL_datum *row;
143 } forvariable;
144 struct
145 {
146 char *label;
147 int n_initvars;
148 int *initvarnos;
149 } declhdr;
150 struct
151 {
152 List *stmts;
153 char *end_label;
154 int end_label_location;
155 } loop_body;
156 List *list;
157 PLpgSQL_type *dtype;
158 PLpgSQL_datum *datum;
159 PLpgSQL_var *var;
160 PLpgSQL_expr *expr;
161 PLpgSQL_stmt *stmt;
162 PLpgSQL_condition *condition;
163 PLpgSQL_exception *exception;
164 PLpgSQL_exception_block *exception_block;
165 PLpgSQL_nsitem *nsitem;
166 PLpgSQL_diag_item *diagitem;
167 PLpgSQL_stmt_fetch *fetch;
168 PLpgSQL_case_when *casewhen;
169 }
170
171 %type <declhdr> decl_sect
172 %type <varname> decl_varname
173 %type <boolean> decl_const decl_notnull exit_type
174 %type <expr> decl_defval decl_cursor_query
175 %type <dtype> decl_datatype
176 %type <oid> decl_collate
177 %type <datum> decl_cursor_args
178 %type <list> decl_cursor_arglist
179 %type <nsitem> decl_aliasitem
180
181 %type <expr> expr_until_semi expr_until_rightbracket
182 %type <expr> expr_until_then expr_until_loop opt_expr_until_when
183 %type <expr> opt_exitcond
184
185 %type <datum> assign_var
186 %type <var> cursor_variable
187 %type <datum> decl_cursor_arg
188 %type <forvariable> for_variable
189 %type <ival> foreach_slice
190 %type <stmt> for_control
191
192 %type <str> any_identifier opt_block_label opt_loop_label opt_label
193 %type <str> option_value
194
195 %type <list> proc_sect stmt_elsifs stmt_else
196 %type <loop_body> loop_body
197 %type <stmt> proc_stmt pl_block
198 %type <stmt> stmt_assign stmt_if stmt_loop stmt_while stmt_exit
199 %type <stmt> stmt_return stmt_raise stmt_assert stmt_execsql
200 %type <stmt> stmt_dynexecute stmt_for stmt_perform stmt_call stmt_getdiag
201 %type <stmt> stmt_open stmt_fetch stmt_move stmt_close stmt_null
202 %type <stmt> stmt_commit stmt_rollback stmt_set
203 %type <stmt> stmt_case stmt_foreach_a
204
205 %type <list> proc_exceptions
206 %type <exception_block> exception_sect
207 %type <exception> proc_exception
208 %type <condition> proc_conditions proc_condition
209
210 %type <casewhen> case_when
211 %type <list> case_when_list opt_case_else
212
213 %type <boolean> getdiag_area_opt
214 %type <list> getdiag_list
215 %type <diagitem> getdiag_list_item
216 %type <datum> getdiag_target
217 %type <ival> getdiag_item
218
219 %type <ival> opt_scrollable
220 %type <fetch> opt_fetch_direction
221
222 %type <ival> opt_transaction_chain
223
224 %type <keyword> unreserved_keyword
225
226
227 /*
228 * Basic non-keyword token types. These are hard-wired into the core lexer.
229 * They must be listed first so that their numeric codes do not depend on
230 * the set of keywords. Keep this list in sync with backend/parser/gram.y!
231 *
232 * Some of these are not directly referenced in this file, but they must be
233 * here anyway.
234 */
235 %token <str> IDENT FCONST SCONST BCONST XCONST Op
236 %token <ival> ICONST PARAM
237 %token TYPECAST DOT_DOT COLON_EQUALS EQUALS_GREATER
238 %token LESS_EQUALS GREATER_EQUALS NOT_EQUALS
239
240 /*
241 * Other tokens recognized by plpgsql's lexer interface layer (pl_scanner.c).
242 */
243 %token <word> T_WORD /* unrecognized simple identifier */
244 %token <cword> T_CWORD /* unrecognized composite identifier */
245 %token <wdatum> T_DATUM /* a VAR, ROW, REC, or RECFIELD variable */
246 %token LESS_LESS
247 %token GREATER_GREATER
248
249 /*
250 * Keyword tokens. Some of these are reserved and some are not;
251 * see pl_scanner.c for info. Be sure unreserved keywords are listed
252 * in the "unreserved_keyword" production below.
253 */
254 %token <keyword> K_ABSOLUTE
255 %token <keyword> K_ALIAS
256 %token <keyword> K_ALL
257 %token <keyword> K_AND
258 %token <keyword> K_ARRAY
259 %token <keyword> K_ASSERT
260 %token <keyword> K_BACKWARD
261 %token <keyword> K_BEGIN
262 %token <keyword> K_BY
263 %token <keyword> K_CALL
264 %token <keyword> K_CASE
265 %token <keyword> K_CHAIN
266 %token <keyword> K_CLOSE
267 %token <keyword> K_COLLATE
268 %token <keyword> K_COLUMN
269 %token <keyword> K_COLUMN_NAME
270 %token <keyword> K_COMMIT
271 %token <keyword> K_CONSTANT
272 %token <keyword> K_CONSTRAINT
273 %token <keyword> K_CONSTRAINT_NAME
274 %token <keyword> K_CONTINUE
275 %token <keyword> K_CURRENT
276 %token <keyword> K_CURSOR
277 %token <keyword> K_DATATYPE
278 %token <keyword> K_DEBUG
279 %token <keyword> K_DECLARE
280 %token <keyword> K_DEFAULT
281 %token <keyword> K_DETAIL
282 %token <keyword> K_DIAGNOSTICS
283 %token <keyword> K_DO
284 %token <keyword> K_DUMP
285 %token <keyword> K_ELSE
286 %token <keyword> K_ELSIF
287 %token <keyword> K_END
288 %token <keyword> K_ERRCODE
289 %token <keyword> K_ERROR
290 %token <keyword> K_EXCEPTION
291 %token <keyword> K_EXECUTE
292 %token <keyword> K_EXIT
293 %token <keyword> K_FETCH
294 %token <keyword> K_FIRST
295 %token <keyword> K_FOR
296 %token <keyword> K_FOREACH
297 %token <keyword> K_FORWARD
298 %token <keyword> K_FROM
299 %token <keyword> K_GET
300 %token <keyword> K_HINT
301 %token <keyword> K_IF
302 %token <keyword> K_IMPORT
303 %token <keyword> K_IN
304 %token <keyword> K_INFO
305 %token <keyword> K_INSERT
306 %token <keyword> K_INTO
307 %token <keyword> K_IS
308 %token <keyword> K_LAST
309 %token <keyword> K_LOG
310 %token <keyword> K_LOOP
311 %token <keyword> K_MESSAGE
312 %token <keyword> K_MESSAGE_TEXT
313 %token <keyword> K_MOVE
314 %token <keyword> K_NEXT
315 %token <keyword> K_NO
316 %token <keyword> K_NOT
317 %token <keyword> K_NOTICE
318 %token <keyword> K_NULL
319 %token <keyword> K_OPEN
320 %token <keyword> K_OPTION
321 %token <keyword> K_OR
322 %token <keyword> K_PERFORM
323 %token <keyword> K_PG_CONTEXT
324 %token <keyword> K_PG_DATATYPE_NAME
325 %token <keyword> K_PG_EXCEPTION_CONTEXT
326 %token <keyword> K_PG_EXCEPTION_DETAIL
327 %token <keyword> K_PG_EXCEPTION_HINT
328 %token <keyword> K_PRINT_STRICT_PARAMS
329 %token <keyword> K_PRIOR
330 %token <keyword> K_QUERY
331 %token <keyword> K_RAISE
332 %token <keyword> K_RELATIVE
333 %token <keyword> K_RESET
334 %token <keyword> K_RETURN
335 %token <keyword> K_RETURNED_SQLSTATE
336 %token <keyword> K_REVERSE
337 %token <keyword> K_ROLLBACK
338 %token <keyword> K_ROW_COUNT
339 %token <keyword> K_ROWTYPE
340 %token <keyword> K_SCHEMA
341 %token <keyword> K_SCHEMA_NAME
342 %token <keyword> K_SCROLL
343 %token <keyword> K_SET
344 %token <keyword> K_SLICE
345 %token <keyword> K_SQLSTATE
346 %token <keyword> K_STACKED
347 %token <keyword> K_STRICT
348 %token <keyword> K_TABLE
349 %token <keyword> K_TABLE_NAME
350 %token <keyword> K_THEN
351 %token <keyword> K_TO
352 %token <keyword> K_TYPE
353 %token <keyword> K_USE_COLUMN
354 %token <keyword> K_USE_VARIABLE
355 %token <keyword> K_USING
356 %token <keyword> K_VARIABLE_CONFLICT
357 %token <keyword> K_WARNING
358 %token <keyword> K_WHEN
359 %token <keyword> K_WHILE
360
361 %%
362
363 pl_function : comp_options pl_block opt_semi
364 {
365 plpgsql_parse_result = (PLpgSQL_stmt_block *) $2;
366 }
367 ;
368
369 comp_options :
370 | comp_options comp_option
371 ;
372
373 comp_option : '#' K_OPTION K_DUMP
374 {
375 plpgsql_DumpExecTree = true;
376 }
377 | '#' K_PRINT_STRICT_PARAMS option_value
378 {
379 if (strcmp($3, "on") == 0)
380 plpgsql_curr_compile->print_strict_params = true;
381 else if (strcmp($3, "off") == 0)
382 plpgsql_curr_compile->print_strict_params = false;
383 else
384 elog(ERROR, "unrecognized print_strict_params option %s", $3);
385 }
386 | '#' K_VARIABLE_CONFLICT K_ERROR
387 {
388 plpgsql_curr_compile->resolve_option = PLPGSQL_RESOLVE_ERROR;
389 }
390 | '#' K_VARIABLE_CONFLICT K_USE_VARIABLE
391 {
392 plpgsql_curr_compile->resolve_option = PLPGSQL_RESOLVE_VARIABLE;
393 }
394 | '#' K_VARIABLE_CONFLICT K_USE_COLUMN
395 {
396 plpgsql_curr_compile->resolve_option = PLPGSQL_RESOLVE_COLUMN;
397 }
398 ;
399
400 option_value : T_WORD
401 {
402 $$ = $1.ident;
403 }
404 | unreserved_keyword
405 {
406 $$ = pstrdup($1);
407 }
408
409 opt_semi :
410 | ';'
411 ;
412
413 pl_block : decl_sect K_BEGIN proc_sect exception_sect K_END opt_label
414 {
415 PLpgSQL_stmt_block *new;
416
417 new = palloc0(sizeof(PLpgSQL_stmt_block));
418
419 new->cmd_type = PLPGSQL_STMT_BLOCK;
420 new->lineno = plpgsql_location_to_lineno(@2);
421 new->stmtid = ++plpgsql_curr_compile->nstatements;
422 new->label = $1.label;
423 new->n_initvars = $1.n_initvars;
424 new->initvarnos = $1.initvarnos;
425 new->body = $3;
426 new->exceptions = $4;
427
428 check_labels($1.label, $6, @6);
429 plpgsql_ns_pop();
430
431 $$ = (PLpgSQL_stmt *)new;
432 }
433 ;
434
435
436 decl_sect : opt_block_label
437 {
438 /* done with decls, so resume identifier lookup */
439 plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL;
440 $$.label = $1;
441 $$.n_initvars = 0;
442 $$.initvarnos = NULL;
443 }
444 | opt_block_label decl_start
445 {
446 plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL;
447 $$.label = $1;
448 $$.n_initvars = 0;
449 $$.initvarnos = NULL;
450 }
451 | opt_block_label decl_start decl_stmts
452 {
453 plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL;
454 $$.label = $1;
455 /* Remember variables declared in decl_stmts */
456 $$.n_initvars = plpgsql_add_initdatums(&($$.initvarnos));
457 }
458 ;
459
460 decl_start : K_DECLARE
461 {
462 /* Forget any variables created before block */
463 plpgsql_add_initdatums(NULL);
464 /*
465 * Disable scanner lookup of identifiers while
466 * we process the decl_stmts
467 */
468 plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_DECLARE;
469 }
470 ;
471
472 decl_stmts : decl_stmts decl_stmt
473 | decl_stmt
474 ;
475
476 decl_stmt : decl_statement
477 | K_DECLARE
478 {
479 /* We allow useless extra DECLAREs */
480 }
481 | LESS_LESS any_identifier GREATER_GREATER
482 {
483 /*
484 * Throw a helpful error if user tries to put block
485 * label just before BEGIN, instead of before DECLARE.
486 */
487 ereport(ERROR,
488 (errcode(ERRCODE_SYNTAX_ERROR),
489 errmsg("block label must be placed before DECLARE, not after"),
490 parser_errposition(@1)));
491 }
492 ;
493
494 decl_statement : decl_varname decl_const decl_datatype decl_collate decl_notnull decl_defval
495 {
496 PLpgSQL_variable *var;
497
498 /*
499 * If a collation is supplied, insert it into the
500 * datatype. We assume decl_datatype always returns
501 * a freshly built struct not shared with other
502 * variables.
503 */
504 if (OidIsValid($4))
505 {
506 if (!OidIsValid($3->collation))
507 ereport(ERROR,
508 (errcode(ERRCODE_DATATYPE_MISMATCH),
509 errmsg("collations are not supported by type %s",
510 format_type_be($3->typoid)),
511 parser_errposition(@4)));
512 $3->collation = $4;
513 }
514
515 var = plpgsql_build_variable($1.name, $1.lineno,
516 $3, true);
517 var->isconst = $2;
518 var->notnull = $5;
519 var->default_val = $6;
520
521 /*
522 * The combination of NOT NULL without an initializer
523 * can't work, so let's reject it at compile time.
524 */
525 if (var->notnull && var->default_val == NULL)
526 ereport(ERROR,
527 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
528 errmsg("variable \"%s\" must have a default value, since it's declared NOT NULL",
529 var->refname),
530 parser_errposition(@5)));
531 }
532 | decl_varname K_ALIAS K_FOR decl_aliasitem ';'
533 {
534 plpgsql_ns_additem($4->itemtype,
535 $4->itemno, $1.name);
536 }
537 | decl_varname opt_scrollable K_CURSOR
538 { plpgsql_ns_push($1.name, PLPGSQL_LABEL_OTHER); }
539 decl_cursor_args decl_is_for decl_cursor_query
540 {
541 PLpgSQL_var *new;
542 PLpgSQL_expr *curname_def;
543 char buf[1024];
544 char *cp1;
545 char *cp2;
546
547 /* pop local namespace for cursor args */
548 plpgsql_ns_pop();
549
550 new = (PLpgSQL_var *)
551 plpgsql_build_variable($1.name, $1.lineno,
552 plpgsql_build_datatype(REFCURSOROID,
553 -1,
554 InvalidOid,
555 NULL),
556 true);
557
558 curname_def = palloc0(sizeof(PLpgSQL_expr));
559
560 strcpy(buf, "SELECT ");
561 cp1 = new->refname;
562 cp2 = buf + strlen(buf);
563 /*
564 * Don't trust standard_conforming_strings here;
565 * it might change before we use the string.
566 */
567 if (strchr(cp1, '\\') != NULL)
568 *cp2++ = ESCAPE_STRING_SYNTAX;
569 *cp2++ = '\'';
570 while (*cp1)
571 {
572 if (SQL_STR_DOUBLE(*cp1, true))
573 *cp2++ = *cp1;
574 *cp2++ = *cp1++;
575 }
576 strcpy(cp2, "'::pg_catalog.refcursor");
577 curname_def->query = pstrdup(buf);
578 new->default_val = curname_def;
579
580 new->cursor_explicit_expr = $7;
581 if ($5 == NULL)
582 new->cursor_explicit_argrow = -1;
583 else
584 new->cursor_explicit_argrow = $5->dno;
585 new->cursor_options = CURSOR_OPT_FAST_PLAN | $2;
586 }
587 ;
588
589 opt_scrollable :
590 {
591 $$ = 0;
592 }
593 | K_NO K_SCROLL
594 {
595 $$ = CURSOR_OPT_NO_SCROLL;
596 }
597 | K_SCROLL
598 {
599 $$ = CURSOR_OPT_SCROLL;
600 }
601 ;
602
603 decl_cursor_query :
604 {
605 $$ = read_sql_stmt("");
606 }
607 ;
608
609 decl_cursor_args :
610 {
611 $$ = NULL;
612 }
613 | '(' decl_cursor_arglist ')'
614 {
615 PLpgSQL_row *new;
616 int i;
617 ListCell *l;
618
619 new = palloc0(sizeof(PLpgSQL_row));
620 new->dtype = PLPGSQL_DTYPE_ROW;
621 new->refname = "(unnamed row)";
622 new->lineno = plpgsql_location_to_lineno(@1);
623 new->rowtupdesc = NULL;
624 new->nfields = list_length($2);
625 new->fieldnames = palloc(new->nfields * sizeof(char *));
626 new->varnos = palloc(new->nfields * sizeof(int));
627
628 i = 0;
foreach(l,$2)629 foreach (l, $2)
630 {
631 PLpgSQL_variable *arg = (PLpgSQL_variable *) lfirst(l);
632 Assert(!arg->isconst);
633 new->fieldnames[i] = arg->refname;
634 new->varnos[i] = arg->dno;
635 i++;
636 }
637 list_free($2);
638
639 plpgsql_adddatum((PLpgSQL_datum *) new);
640 $$ = (PLpgSQL_datum *) new;
641 }
642 ;
643
644 decl_cursor_arglist : decl_cursor_arg
645 {
646 $$ = list_make1($1);
647 }
648 | decl_cursor_arglist ',' decl_cursor_arg
649 {
650 $$ = lappend($1, $3);
651 }
652 ;
653
654 decl_cursor_arg : decl_varname decl_datatype
655 {
656 $$ = (PLpgSQL_datum *)
657 plpgsql_build_variable($1.name, $1.lineno,
658 $2, true);
659 }
660 ;
661
662 decl_is_for : K_IS | /* Oracle */
663 K_FOR; /* SQL standard */
664
665 decl_aliasitem : T_WORD
666 {
667 PLpgSQL_nsitem *nsi;
668
669 nsi = plpgsql_ns_lookup(plpgsql_ns_top(), false,
670 $1.ident, NULL, NULL,
671 NULL);
672 if (nsi == NULL)
673 ereport(ERROR,
674 (errcode(ERRCODE_UNDEFINED_OBJECT),
675 errmsg("variable \"%s\" does not exist",
676 $1.ident),
677 parser_errposition(@1)));
678 $$ = nsi;
679 }
680 | unreserved_keyword
681 {
682 PLpgSQL_nsitem *nsi;
683
684 nsi = plpgsql_ns_lookup(plpgsql_ns_top(), false,
685 $1, NULL, NULL,
686 NULL);
687 if (nsi == NULL)
688 ereport(ERROR,
689 (errcode(ERRCODE_UNDEFINED_OBJECT),
690 errmsg("variable \"%s\" does not exist",
691 $1),
692 parser_errposition(@1)));
693 $$ = nsi;
694 }
695 | T_CWORD
696 {
697 PLpgSQL_nsitem *nsi;
698
699 if (list_length($1.idents) == 2)
700 nsi = plpgsql_ns_lookup(plpgsql_ns_top(), false,
701 strVal(linitial($1.idents)),
702 strVal(lsecond($1.idents)),
703 NULL,
704 NULL);
705 else if (list_length($1.idents) == 3)
706 nsi = plpgsql_ns_lookup(plpgsql_ns_top(), false,
707 strVal(linitial($1.idents)),
708 strVal(lsecond($1.idents)),
709 strVal(lthird($1.idents)),
710 NULL);
711 else
712 nsi = NULL;
713 if (nsi == NULL)
714 ereport(ERROR,
715 (errcode(ERRCODE_UNDEFINED_OBJECT),
716 errmsg("variable \"%s\" does not exist",
717 NameListToString($1.idents)),
718 parser_errposition(@1)));
719 $$ = nsi;
720 }
721 ;
722
723 decl_varname : T_WORD
724 {
725 $$.name = $1.ident;
726 $$.lineno = plpgsql_location_to_lineno(@1);
727 /*
728 * Check to make sure name isn't already declared
729 * in the current block.
730 */
731 if (plpgsql_ns_lookup(plpgsql_ns_top(), true,
732 $1.ident, NULL, NULL,
733 NULL) != NULL)
734 yyerror("duplicate declaration");
735
736 if (plpgsql_curr_compile->extra_warnings & PLPGSQL_XCHECK_SHADOWVAR ||
737 plpgsql_curr_compile->extra_errors & PLPGSQL_XCHECK_SHADOWVAR)
738 {
739 PLpgSQL_nsitem *nsi;
740 nsi = plpgsql_ns_lookup(plpgsql_ns_top(), false,
741 $1.ident, NULL, NULL, NULL);
742 if (nsi != NULL)
743 ereport(plpgsql_curr_compile->extra_errors & PLPGSQL_XCHECK_SHADOWVAR ? ERROR : WARNING,
744 (errcode(ERRCODE_DUPLICATE_ALIAS),
745 errmsg("variable \"%s\" shadows a previously defined variable",
746 $1.ident),
747 parser_errposition(@1)));
748 }
749
750 }
751 | unreserved_keyword
752 {
753 $$.name = pstrdup($1);
754 $$.lineno = plpgsql_location_to_lineno(@1);
755 /*
756 * Check to make sure name isn't already declared
757 * in the current block.
758 */
759 if (plpgsql_ns_lookup(plpgsql_ns_top(), true,
760 $1, NULL, NULL,
761 NULL) != NULL)
762 yyerror("duplicate declaration");
763
764 if (plpgsql_curr_compile->extra_warnings & PLPGSQL_XCHECK_SHADOWVAR ||
765 plpgsql_curr_compile->extra_errors & PLPGSQL_XCHECK_SHADOWVAR)
766 {
767 PLpgSQL_nsitem *nsi;
768 nsi = plpgsql_ns_lookup(plpgsql_ns_top(), false,
769 $1, NULL, NULL, NULL);
770 if (nsi != NULL)
771 ereport(plpgsql_curr_compile->extra_errors & PLPGSQL_XCHECK_SHADOWVAR ? ERROR : WARNING,
772 (errcode(ERRCODE_DUPLICATE_ALIAS),
773 errmsg("variable \"%s\" shadows a previously defined variable",
774 $1),
775 parser_errposition(@1)));
776 }
777
778 }
779 ;
780
781 decl_const :
782 { $$ = false; }
783 | K_CONSTANT
784 { $$ = true; }
785 ;
786
787 decl_datatype :
788 {
789 /*
790 * If there's a lookahead token, read_datatype
791 * should consume it.
792 */
793 $$ = read_datatype(yychar);
794 yyclearin;
795 }
796 ;
797
798 decl_collate :
799 { $$ = InvalidOid; }
800 | K_COLLATE T_WORD
801 {
802 $$ = get_collation_oid(list_make1(makeString($2.ident)),
803 false);
804 }
805 | K_COLLATE unreserved_keyword
806 {
807 $$ = get_collation_oid(list_make1(makeString(pstrdup($2))),
808 false);
809 }
810 | K_COLLATE T_CWORD
811 {
812 $$ = get_collation_oid($2.idents, false);
813 }
814 ;
815
816 decl_notnull :
817 { $$ = false; }
818 | K_NOT K_NULL
819 { $$ = true; }
820 ;
821
822 decl_defval : ';'
823 { $$ = NULL; }
824 | decl_defkey
825 {
826 $$ = read_sql_expression(';', ";");
827 }
828 ;
829
830 decl_defkey : assign_operator
831 | K_DEFAULT
832 ;
833
834 /*
835 * Ada-based PL/SQL uses := for assignment and variable defaults, while
836 * the SQL standard uses equals for these cases and for GET
837 * DIAGNOSTICS, so we support both. FOR and OPEN only support :=.
838 */
839 assign_operator : '='
840 | COLON_EQUALS
841 ;
842
843 proc_sect :
844 { $$ = NIL; }
845 | proc_sect proc_stmt
846 {
847 /* don't bother linking null statements into list */
848 if ($2 == NULL)
849 $$ = $1;
850 else
851 $$ = lappend($1, $2);
852 }
853 ;
854
855 proc_stmt : pl_block ';'
856 { $$ = $1; }
857 | stmt_assign
858 { $$ = $1; }
859 | stmt_if
860 { $$ = $1; }
861 | stmt_case
862 { $$ = $1; }
863 | stmt_loop
864 { $$ = $1; }
865 | stmt_while
866 { $$ = $1; }
867 | stmt_for
868 { $$ = $1; }
869 | stmt_foreach_a
870 { $$ = $1; }
871 | stmt_exit
872 { $$ = $1; }
873 | stmt_return
874 { $$ = $1; }
875 | stmt_raise
876 { $$ = $1; }
877 | stmt_assert
878 { $$ = $1; }
879 | stmt_execsql
880 { $$ = $1; }
881 | stmt_dynexecute
882 { $$ = $1; }
883 | stmt_perform
884 { $$ = $1; }
885 | stmt_call
886 { $$ = $1; }
887 | stmt_getdiag
888 { $$ = $1; }
889 | stmt_open
890 { $$ = $1; }
891 | stmt_fetch
892 { $$ = $1; }
893 | stmt_move
894 { $$ = $1; }
895 | stmt_close
896 { $$ = $1; }
897 | stmt_null
898 { $$ = $1; }
899 | stmt_commit
900 { $$ = $1; }
901 | stmt_rollback
902 { $$ = $1; }
903 | stmt_set
904 { $$ = $1; }
905 ;
906
907 stmt_perform : K_PERFORM expr_until_semi
908 {
909 PLpgSQL_stmt_perform *new;
910
911 new = palloc0(sizeof(PLpgSQL_stmt_perform));
912 new->cmd_type = PLPGSQL_STMT_PERFORM;
913 new->lineno = plpgsql_location_to_lineno(@1);
914 new->stmtid = ++plpgsql_curr_compile->nstatements;
915 new->expr = $2;
916
917 $$ = (PLpgSQL_stmt *)new;
918 }
919 ;
920
921 stmt_call : K_CALL
922 {
923 PLpgSQL_stmt_call *new;
924
925 new = palloc0(sizeof(PLpgSQL_stmt_call));
926 new->cmd_type = PLPGSQL_STMT_CALL;
927 new->lineno = plpgsql_location_to_lineno(@1);
928 new->stmtid = ++plpgsql_curr_compile->nstatements;
929 new->expr = read_sql_stmt("CALL ");
930 new->is_call = true;
931
932 $$ = (PLpgSQL_stmt *)new;
933
934 }
935 | K_DO
936 {
937 /* use the same structures as for CALL, for simplicity */
938 PLpgSQL_stmt_call *new;
939
940 new = palloc0(sizeof(PLpgSQL_stmt_call));
941 new->cmd_type = PLPGSQL_STMT_CALL;
942 new->lineno = plpgsql_location_to_lineno(@1);
943 new->stmtid = ++plpgsql_curr_compile->nstatements;
944 new->expr = read_sql_stmt("DO ");
945 new->is_call = false;
946
947 $$ = (PLpgSQL_stmt *)new;
948
949 }
950 ;
951
952 stmt_assign : assign_var assign_operator expr_until_semi
953 {
954 PLpgSQL_stmt_assign *new;
955
956 new = palloc0(sizeof(PLpgSQL_stmt_assign));
957 new->cmd_type = PLPGSQL_STMT_ASSIGN;
958 new->lineno = plpgsql_location_to_lineno(@1);
959 new->stmtid = ++plpgsql_curr_compile->nstatements;
960 new->varno = $1->dno;
961 new->expr = $3;
962
963 $$ = (PLpgSQL_stmt *)new;
964 }
965 ;
966
967 stmt_getdiag : K_GET getdiag_area_opt K_DIAGNOSTICS getdiag_list ';'
968 {
969 PLpgSQL_stmt_getdiag *new;
970 ListCell *lc;
971
972 new = palloc0(sizeof(PLpgSQL_stmt_getdiag));
973 new->cmd_type = PLPGSQL_STMT_GETDIAG;
974 new->lineno = plpgsql_location_to_lineno(@1);
975 new->stmtid = ++plpgsql_curr_compile->nstatements;
976 new->is_stacked = $2;
977 new->diag_items = $4;
978
979 /*
980 * Check information items are valid for area option.
981 */
982 foreach(lc, new->diag_items)
983 {
984 PLpgSQL_diag_item *ditem = (PLpgSQL_diag_item *) lfirst(lc);
985
986 switch (ditem->kind)
987 {
988 /* these fields are disallowed in stacked case */
989 case PLPGSQL_GETDIAG_ROW_COUNT:
990 if (new->is_stacked)
991 ereport(ERROR,
992 (errcode(ERRCODE_SYNTAX_ERROR),
993 errmsg("diagnostics item %s is not allowed in GET STACKED DIAGNOSTICS",
994 plpgsql_getdiag_kindname(ditem->kind)),
995 parser_errposition(@1)));
996 break;
997 /* these fields are disallowed in current case */
998 case PLPGSQL_GETDIAG_ERROR_CONTEXT:
999 case PLPGSQL_GETDIAG_ERROR_DETAIL:
1000 case PLPGSQL_GETDIAG_ERROR_HINT:
1001 case PLPGSQL_GETDIAG_RETURNED_SQLSTATE:
1002 case PLPGSQL_GETDIAG_COLUMN_NAME:
1003 case PLPGSQL_GETDIAG_CONSTRAINT_NAME:
1004 case PLPGSQL_GETDIAG_DATATYPE_NAME:
1005 case PLPGSQL_GETDIAG_MESSAGE_TEXT:
1006 case PLPGSQL_GETDIAG_TABLE_NAME:
1007 case PLPGSQL_GETDIAG_SCHEMA_NAME:
1008 if (!new->is_stacked)
1009 ereport(ERROR,
1010 (errcode(ERRCODE_SYNTAX_ERROR),
1011 errmsg("diagnostics item %s is not allowed in GET CURRENT DIAGNOSTICS",
1012 plpgsql_getdiag_kindname(ditem->kind)),
1013 parser_errposition(@1)));
1014 break;
1015 /* these fields are allowed in either case */
1016 case PLPGSQL_GETDIAG_CONTEXT:
1017 break;
1018 default:
1019 elog(ERROR, "unrecognized diagnostic item kind: %d",
1020 ditem->kind);
1021 break;
1022 }
1023 }
1024
1025 $$ = (PLpgSQL_stmt *)new;
1026 }
1027 ;
1028
1029 getdiag_area_opt :
1030 {
1031 $$ = false;
1032 }
1033 | K_CURRENT
1034 {
1035 $$ = false;
1036 }
1037 | K_STACKED
1038 {
1039 $$ = true;
1040 }
1041 ;
1042
1043 getdiag_list : getdiag_list ',' getdiag_list_item
1044 {
1045 $$ = lappend($1, $3);
1046 }
1047 | getdiag_list_item
1048 {
1049 $$ = list_make1($1);
1050 }
1051 ;
1052
1053 getdiag_list_item : getdiag_target assign_operator getdiag_item
1054 {
1055 PLpgSQL_diag_item *new;
1056
1057 new = palloc(sizeof(PLpgSQL_diag_item));
1058 new->target = $1->dno;
1059 new->kind = $3;
1060
1061 $$ = new;
1062 }
1063 ;
1064
1065 getdiag_item :
1066 {
1067 int tok = yylex();
1068
1069 if (tok_is_keyword(tok, &yylval,
1070 K_ROW_COUNT, "row_count"))
1071 $$ = PLPGSQL_GETDIAG_ROW_COUNT;
1072 else if (tok_is_keyword(tok, &yylval,
1073 K_PG_CONTEXT, "pg_context"))
1074 $$ = PLPGSQL_GETDIAG_CONTEXT;
1075 else if (tok_is_keyword(tok, &yylval,
1076 K_PG_EXCEPTION_DETAIL, "pg_exception_detail"))
1077 $$ = PLPGSQL_GETDIAG_ERROR_DETAIL;
1078 else if (tok_is_keyword(tok, &yylval,
1079 K_PG_EXCEPTION_HINT, "pg_exception_hint"))
1080 $$ = PLPGSQL_GETDIAG_ERROR_HINT;
1081 else if (tok_is_keyword(tok, &yylval,
1082 K_PG_EXCEPTION_CONTEXT, "pg_exception_context"))
1083 $$ = PLPGSQL_GETDIAG_ERROR_CONTEXT;
1084 else if (tok_is_keyword(tok, &yylval,
1085 K_COLUMN_NAME, "column_name"))
1086 $$ = PLPGSQL_GETDIAG_COLUMN_NAME;
1087 else if (tok_is_keyword(tok, &yylval,
1088 K_CONSTRAINT_NAME, "constraint_name"))
1089 $$ = PLPGSQL_GETDIAG_CONSTRAINT_NAME;
1090 else if (tok_is_keyword(tok, &yylval,
1091 K_PG_DATATYPE_NAME, "pg_datatype_name"))
1092 $$ = PLPGSQL_GETDIAG_DATATYPE_NAME;
1093 else if (tok_is_keyword(tok, &yylval,
1094 K_MESSAGE_TEXT, "message_text"))
1095 $$ = PLPGSQL_GETDIAG_MESSAGE_TEXT;
1096 else if (tok_is_keyword(tok, &yylval,
1097 K_TABLE_NAME, "table_name"))
1098 $$ = PLPGSQL_GETDIAG_TABLE_NAME;
1099 else if (tok_is_keyword(tok, &yylval,
1100 K_SCHEMA_NAME, "schema_name"))
1101 $$ = PLPGSQL_GETDIAG_SCHEMA_NAME;
1102 else if (tok_is_keyword(tok, &yylval,
1103 K_RETURNED_SQLSTATE, "returned_sqlstate"))
1104 $$ = PLPGSQL_GETDIAG_RETURNED_SQLSTATE;
1105 else
1106 yyerror("unrecognized GET DIAGNOSTICS item");
1107 }
1108 ;
1109
1110 getdiag_target : assign_var
1111 {
1112 if ($1->dtype == PLPGSQL_DTYPE_ROW ||
1113 $1->dtype == PLPGSQL_DTYPE_REC)
1114 ereport(ERROR,
1115 (errcode(ERRCODE_SYNTAX_ERROR),
1116 errmsg("\"%s\" is not a scalar variable",
1117 ((PLpgSQL_variable *) $1)->refname),
1118 parser_errposition(@1)));
1119 $$ = $1;
1120 }
1121 | T_WORD
1122 {
1123 /* just to give a better message than "syntax error" */
1124 word_is_not_variable(&($1), @1);
1125 }
1126 | T_CWORD
1127 {
1128 /* just to give a better message than "syntax error" */
1129 cword_is_not_variable(&($1), @1);
1130 }
1131 ;
1132
1133
1134 assign_var : T_DATUM
1135 {
1136 check_assignable($1.datum, @1);
1137 $$ = $1.datum;
1138 }
1139 | assign_var '[' expr_until_rightbracket
1140 {
1141 PLpgSQL_arrayelem *new;
1142
1143 new = palloc0(sizeof(PLpgSQL_arrayelem));
1144 new->dtype = PLPGSQL_DTYPE_ARRAYELEM;
1145 new->subscript = $3;
1146 new->arrayparentno = $1->dno;
1147 /* initialize cached type data to "not valid" */
1148 new->parenttypoid = InvalidOid;
1149
1150 plpgsql_adddatum((PLpgSQL_datum *) new);
1151
1152 $$ = (PLpgSQL_datum *) new;
1153 }
1154 ;
1155
1156 stmt_if : K_IF expr_until_then proc_sect stmt_elsifs stmt_else K_END K_IF ';'
1157 {
1158 PLpgSQL_stmt_if *new;
1159
1160 new = palloc0(sizeof(PLpgSQL_stmt_if));
1161 new->cmd_type = PLPGSQL_STMT_IF;
1162 new->lineno = plpgsql_location_to_lineno(@1);
1163 new->stmtid = ++plpgsql_curr_compile->nstatements;
1164 new->cond = $2;
1165 new->then_body = $3;
1166 new->elsif_list = $4;
1167 new->else_body = $5;
1168
1169 $$ = (PLpgSQL_stmt *)new;
1170 }
1171 ;
1172
1173 stmt_elsifs :
1174 {
1175 $$ = NIL;
1176 }
1177 | stmt_elsifs K_ELSIF expr_until_then proc_sect
1178 {
1179 PLpgSQL_if_elsif *new;
1180
1181 new = palloc0(sizeof(PLpgSQL_if_elsif));
1182 new->lineno = plpgsql_location_to_lineno(@2);
1183 new->cond = $3;
1184 new->stmts = $4;
1185
1186 $$ = lappend($1, new);
1187 }
1188 ;
1189
1190 stmt_else :
1191 {
1192 $$ = NIL;
1193 }
1194 | K_ELSE proc_sect
1195 {
1196 $$ = $2;
1197 }
1198 ;
1199
1200 stmt_case : K_CASE opt_expr_until_when case_when_list opt_case_else K_END K_CASE ';'
1201 {
1202 $$ = make_case(@1, $2, $3, $4);
1203 }
1204 ;
1205
1206 opt_expr_until_when :
1207 {
1208 PLpgSQL_expr *expr = NULL;
1209 int tok = yylex();
1210
1211 if (tok != K_WHEN)
1212 {
1213 plpgsql_push_back_token(tok);
1214 expr = read_sql_expression(K_WHEN, "WHEN");
1215 }
1216 plpgsql_push_back_token(K_WHEN);
1217 $$ = expr;
1218 }
1219 ;
1220
1221 case_when_list : case_when_list case_when
1222 {
1223 $$ = lappend($1, $2);
1224 }
1225 | case_when
1226 {
1227 $$ = list_make1($1);
1228 }
1229 ;
1230
1231 case_when : K_WHEN expr_until_then proc_sect
1232 {
1233 PLpgSQL_case_when *new = palloc(sizeof(PLpgSQL_case_when));
1234
1235 new->lineno = plpgsql_location_to_lineno(@1);
1236 new->expr = $2;
1237 new->stmts = $3;
1238 $$ = new;
1239 }
1240 ;
1241
1242 opt_case_else :
1243 {
1244 $$ = NIL;
1245 }
1246 | K_ELSE proc_sect
1247 {
1248 /*
1249 * proc_sect could return an empty list, but we
1250 * must distinguish that from not having ELSE at all.
1251 * Simplest fix is to return a list with one NULL
1252 * pointer, which make_case() must take care of.
1253 */
1254 if ($2 != NIL)
1255 $$ = $2;
1256 else
1257 $$ = list_make1(NULL);
1258 }
1259 ;
1260
1261 stmt_loop : opt_loop_label K_LOOP loop_body
1262 {
1263 PLpgSQL_stmt_loop *new;
1264
1265 new = palloc0(sizeof(PLpgSQL_stmt_loop));
1266 new->cmd_type = PLPGSQL_STMT_LOOP;
1267 new->lineno = plpgsql_location_to_lineno(@2);
1268 new->stmtid = ++plpgsql_curr_compile->nstatements;
1269 new->label = $1;
1270 new->body = $3.stmts;
1271
1272 check_labels($1, $3.end_label, $3.end_label_location);
1273 plpgsql_ns_pop();
1274
1275 $$ = (PLpgSQL_stmt *)new;
1276 }
1277 ;
1278
1279 stmt_while : opt_loop_label K_WHILE expr_until_loop loop_body
1280 {
1281 PLpgSQL_stmt_while *new;
1282
1283 new = palloc0(sizeof(PLpgSQL_stmt_while));
1284 new->cmd_type = PLPGSQL_STMT_WHILE;
1285 new->lineno = plpgsql_location_to_lineno(@2);
1286 new->stmtid = ++plpgsql_curr_compile->nstatements;
1287 new->label = $1;
1288 new->cond = $3;
1289 new->body = $4.stmts;
1290
1291 check_labels($1, $4.end_label, $4.end_label_location);
1292 plpgsql_ns_pop();
1293
1294 $$ = (PLpgSQL_stmt *)new;
1295 }
1296 ;
1297
1298 stmt_for : opt_loop_label K_FOR for_control loop_body
1299 {
1300 /* This runs after we've scanned the loop body */
1301 if ($3->cmd_type == PLPGSQL_STMT_FORI)
1302 {
1303 PLpgSQL_stmt_fori *new;
1304
1305 new = (PLpgSQL_stmt_fori *) $3;
1306 new->lineno = plpgsql_location_to_lineno(@2);
1307 new->label = $1;
1308 new->body = $4.stmts;
1309 $$ = (PLpgSQL_stmt *) new;
1310 }
1311 else
1312 {
1313 PLpgSQL_stmt_forq *new;
1314
1315 Assert($3->cmd_type == PLPGSQL_STMT_FORS ||
1316 $3->cmd_type == PLPGSQL_STMT_FORC ||
1317 $3->cmd_type == PLPGSQL_STMT_DYNFORS);
1318 /* forq is the common supertype of all three */
1319 new = (PLpgSQL_stmt_forq *) $3;
1320 new->lineno = plpgsql_location_to_lineno(@2);
1321 new->label = $1;
1322 new->body = $4.stmts;
1323 $$ = (PLpgSQL_stmt *) new;
1324 }
1325
1326 check_labels($1, $4.end_label, $4.end_label_location);
1327 /* close namespace started in opt_loop_label */
1328 plpgsql_ns_pop();
1329 }
1330 ;
1331
1332 for_control : for_variable K_IN
1333 {
1334 int tok = yylex();
1335 int tokloc = yylloc;
1336
1337 if (tok == K_EXECUTE)
1338 {
1339 /* EXECUTE means it's a dynamic FOR loop */
1340 PLpgSQL_stmt_dynfors *new;
1341 PLpgSQL_expr *expr;
1342 int term;
1343
1344 expr = read_sql_expression2(K_LOOP, K_USING,
1345 "LOOP or USING",
1346 &term);
1347
1348 new = palloc0(sizeof(PLpgSQL_stmt_dynfors));
1349 new->cmd_type = PLPGSQL_STMT_DYNFORS;
1350 new->stmtid = ++plpgsql_curr_compile->nstatements;
1351 if ($1.row)
1352 {
1353 new->var = (PLpgSQL_variable *) $1.row;
1354 check_assignable($1.row, @1);
1355 }
1356 else if ($1.scalar)
1357 {
1358 /* convert single scalar to list */
1359 new->var = (PLpgSQL_variable *)
1360 make_scalar_list1($1.name, $1.scalar,
1361 $1.lineno, @1);
1362 /* make_scalar_list1 did check_assignable */
1363 }
1364 else
1365 {
1366 ereport(ERROR,
1367 (errcode(ERRCODE_DATATYPE_MISMATCH),
1368 errmsg("loop variable of loop over rows must be a record variable or list of scalar variables"),
1369 parser_errposition(@1)));
1370 }
1371 new->query = expr;
1372
1373 if (term == K_USING)
1374 {
1375 do
1376 {
1377 expr = read_sql_expression2(',', K_LOOP,
1378 ", or LOOP",
1379 &term);
1380 new->params = lappend(new->params, expr);
1381 } while (term == ',');
1382 }
1383
1384 $$ = (PLpgSQL_stmt *) new;
1385 }
1386 else if (tok == T_DATUM &&
1387 yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_VAR &&
1388 ((PLpgSQL_var *) yylval.wdatum.datum)->datatype->typoid == REFCURSOROID)
1389 {
1390 /* It's FOR var IN cursor */
1391 PLpgSQL_stmt_forc *new;
1392 PLpgSQL_var *cursor = (PLpgSQL_var *) yylval.wdatum.datum;
1393
1394 new = (PLpgSQL_stmt_forc *) palloc0(sizeof(PLpgSQL_stmt_forc));
1395 new->cmd_type = PLPGSQL_STMT_FORC;
1396 new->stmtid = ++plpgsql_curr_compile->nstatements;
1397 new->curvar = cursor->dno;
1398
1399 /* Should have had a single variable name */
1400 if ($1.scalar && $1.row)
1401 ereport(ERROR,
1402 (errcode(ERRCODE_SYNTAX_ERROR),
1403 errmsg("cursor FOR loop must have only one target variable"),
1404 parser_errposition(@1)));
1405
1406 /* can't use an unbound cursor this way */
1407 if (cursor->cursor_explicit_expr == NULL)
1408 ereport(ERROR,
1409 (errcode(ERRCODE_SYNTAX_ERROR),
1410 errmsg("cursor FOR loop must use a bound cursor variable"),
1411 parser_errposition(tokloc)));
1412
1413 /* collect cursor's parameters if any */
1414 new->argquery = read_cursor_args(cursor,
1415 K_LOOP,
1416 "LOOP");
1417
1418 /* create loop's private RECORD variable */
1419 new->var = (PLpgSQL_variable *)
1420 plpgsql_build_record($1.name,
1421 $1.lineno,
1422 NULL,
1423 RECORDOID,
1424 true);
1425
1426 $$ = (PLpgSQL_stmt *) new;
1427 }
1428 else
1429 {
1430 PLpgSQL_expr *expr1;
1431 int expr1loc;
1432 bool reverse = false;
1433
1434 /*
1435 * We have to distinguish between two
1436 * alternatives: FOR var IN a .. b and FOR
1437 * var IN query. Unfortunately this is
1438 * tricky, since the query in the second
1439 * form needn't start with a SELECT
1440 * keyword. We use the ugly hack of
1441 * looking for two periods after the first
1442 * token. We also check for the REVERSE
1443 * keyword, which means it must be an
1444 * integer loop.
1445 */
1446 if (tok_is_keyword(tok, &yylval,
1447 K_REVERSE, "reverse"))
1448 reverse = true;
1449 else
1450 plpgsql_push_back_token(tok);
1451
1452 /*
1453 * Read tokens until we see either a ".."
1454 * or a LOOP. The text we read may not
1455 * necessarily be a well-formed SQL
1456 * statement, so we need to invoke
1457 * read_sql_construct directly.
1458 */
1459 expr1 = read_sql_construct(DOT_DOT,
1460 K_LOOP,
1461 0,
1462 "LOOP",
1463 "SELECT ",
1464 true,
1465 false,
1466 true,
1467 &expr1loc,
1468 &tok);
1469
1470 if (tok == DOT_DOT)
1471 {
1472 /* Saw "..", so it must be an integer loop */
1473 PLpgSQL_expr *expr2;
1474 PLpgSQL_expr *expr_by;
1475 PLpgSQL_var *fvar;
1476 PLpgSQL_stmt_fori *new;
1477
1478 /* Check first expression is well-formed */
1479 check_sql_expr(expr1->query, expr1loc, 7);
1480
1481 /* Read and check the second one */
1482 expr2 = read_sql_expression2(K_LOOP, K_BY,
1483 "LOOP",
1484 &tok);
1485
1486 /* Get the BY clause if any */
1487 if (tok == K_BY)
1488 expr_by = read_sql_expression(K_LOOP,
1489 "LOOP");
1490 else
1491 expr_by = NULL;
1492
1493 /* Should have had a single variable name */
1494 if ($1.scalar && $1.row)
1495 ereport(ERROR,
1496 (errcode(ERRCODE_SYNTAX_ERROR),
1497 errmsg("integer FOR loop must have only one target variable"),
1498 parser_errposition(@1)));
1499
1500 /* create loop's private variable */
1501 fvar = (PLpgSQL_var *)
1502 plpgsql_build_variable($1.name,
1503 $1.lineno,
1504 plpgsql_build_datatype(INT4OID,
1505 -1,
1506 InvalidOid,
1507 NULL),
1508 true);
1509
1510 new = palloc0(sizeof(PLpgSQL_stmt_fori));
1511 new->cmd_type = PLPGSQL_STMT_FORI;
1512 new->stmtid = ++plpgsql_curr_compile->nstatements;
1513 new->var = fvar;
1514 new->reverse = reverse;
1515 new->lower = expr1;
1516 new->upper = expr2;
1517 new->step = expr_by;
1518
1519 $$ = (PLpgSQL_stmt *) new;
1520 }
1521 else
1522 {
1523 /*
1524 * No "..", so it must be a query loop. We've
1525 * prefixed an extra SELECT to the query text,
1526 * so we need to remove that before performing
1527 * syntax checking.
1528 */
1529 char *tmp_query;
1530 PLpgSQL_stmt_fors *new;
1531
1532 if (reverse)
1533 ereport(ERROR,
1534 (errcode(ERRCODE_SYNTAX_ERROR),
1535 errmsg("cannot specify REVERSE in query FOR loop"),
1536 parser_errposition(tokloc)));
1537
1538 Assert(strncmp(expr1->query, "SELECT ", 7) == 0);
1539 tmp_query = pstrdup(expr1->query + 7);
1540 pfree(expr1->query);
1541 expr1->query = tmp_query;
1542
1543 check_sql_expr(expr1->query, expr1loc, 0);
1544
1545 new = palloc0(sizeof(PLpgSQL_stmt_fors));
1546 new->cmd_type = PLPGSQL_STMT_FORS;
1547 new->stmtid = ++plpgsql_curr_compile->nstatements;
1548 if ($1.row)
1549 {
1550 new->var = (PLpgSQL_variable *) $1.row;
1551 check_assignable($1.row, @1);
1552 }
1553 else if ($1.scalar)
1554 {
1555 /* convert single scalar to list */
1556 new->var = (PLpgSQL_variable *)
1557 make_scalar_list1($1.name, $1.scalar,
1558 $1.lineno, @1);
1559 /* make_scalar_list1 did check_assignable */
1560 }
1561 else
1562 {
1563 ereport(ERROR,
1564 (errcode(ERRCODE_SYNTAX_ERROR),
1565 errmsg("loop variable of loop over rows must be a record variable or list of scalar variables"),
1566 parser_errposition(@1)));
1567 }
1568
1569 new->query = expr1;
1570 $$ = (PLpgSQL_stmt *) new;
1571 }
1572 }
1573 }
1574 ;
1575
1576 /*
1577 * Processing the for_variable is tricky because we don't yet know if the
1578 * FOR is an integer FOR loop or a loop over query results. In the former
1579 * case, the variable is just a name that we must instantiate as a loop
1580 * local variable, regardless of any other definition it might have.
1581 * Therefore, we always save the actual identifier into $$.name where it
1582 * can be used for that case. We also save the outer-variable definition,
1583 * if any, because that's what we need for the loop-over-query case. Note
1584 * that we must NOT apply check_assignable() or any other semantic check
1585 * until we know what's what.
1586 *
1587 * However, if we see a comma-separated list of names, we know that it
1588 * can't be an integer FOR loop and so it's OK to check the variables
1589 * immediately. In particular, for T_WORD followed by comma, we should
1590 * complain that the name is not known rather than say it's a syntax error.
1591 * Note that the non-error result of this case sets *both* $$.scalar and
1592 * $$.row; see the for_control production.
1593 */
1594 for_variable : T_DATUM
1595 {
1596 $$.name = NameOfDatum(&($1));
1597 $$.lineno = plpgsql_location_to_lineno(@1);
1598 if ($1.datum->dtype == PLPGSQL_DTYPE_ROW ||
1599 $1.datum->dtype == PLPGSQL_DTYPE_REC)
1600 {
1601 $$.scalar = NULL;
1602 $$.row = $1.datum;
1603 }
1604 else
1605 {
1606 int tok;
1607
1608 $$.scalar = $1.datum;
1609 $$.row = NULL;
1610 /* check for comma-separated list */
1611 tok = yylex();
1612 plpgsql_push_back_token(tok);
1613 if (tok == ',')
1614 $$.row = (PLpgSQL_datum *)
1615 read_into_scalar_list($$.name,
1616 $$.scalar,
1617 @1);
1618 }
1619 }
1620 | T_WORD
1621 {
1622 int tok;
1623
1624 $$.name = $1.ident;
1625 $$.lineno = plpgsql_location_to_lineno(@1);
1626 $$.scalar = NULL;
1627 $$.row = NULL;
1628 /* check for comma-separated list */
1629 tok = yylex();
1630 plpgsql_push_back_token(tok);
1631 if (tok == ',')
1632 word_is_not_variable(&($1), @1);
1633 }
1634 | T_CWORD
1635 {
1636 /* just to give a better message than "syntax error" */
1637 cword_is_not_variable(&($1), @1);
1638 }
1639 ;
1640
1641 stmt_foreach_a : opt_loop_label K_FOREACH for_variable foreach_slice K_IN K_ARRAY expr_until_loop loop_body
1642 {
1643 PLpgSQL_stmt_foreach_a *new;
1644
1645 new = palloc0(sizeof(PLpgSQL_stmt_foreach_a));
1646 new->cmd_type = PLPGSQL_STMT_FOREACH_A;
1647 new->lineno = plpgsql_location_to_lineno(@2);
1648 new->stmtid = ++plpgsql_curr_compile->nstatements;
1649 new->label = $1;
1650 new->slice = $4;
1651 new->expr = $7;
1652 new->body = $8.stmts;
1653
1654 if ($3.row)
1655 {
1656 new->varno = $3.row->dno;
1657 check_assignable($3.row, @3);
1658 }
1659 else if ($3.scalar)
1660 {
1661 new->varno = $3.scalar->dno;
1662 check_assignable($3.scalar, @3);
1663 }
1664 else
1665 {
1666 ereport(ERROR,
1667 (errcode(ERRCODE_SYNTAX_ERROR),
1668 errmsg("loop variable of FOREACH must be a known variable or list of variables"),
1669 parser_errposition(@3)));
1670 }
1671
1672 check_labels($1, $8.end_label, $8.end_label_location);
1673 plpgsql_ns_pop();
1674
1675 $$ = (PLpgSQL_stmt *) new;
1676 }
1677 ;
1678
1679 foreach_slice :
1680 {
1681 $$ = 0;
1682 }
1683 | K_SLICE ICONST
1684 {
1685 $$ = $2;
1686 }
1687 ;
1688
1689 stmt_exit : exit_type opt_label opt_exitcond
1690 {
1691 PLpgSQL_stmt_exit *new;
1692
1693 new = palloc0(sizeof(PLpgSQL_stmt_exit));
1694 new->cmd_type = PLPGSQL_STMT_EXIT;
1695 new->stmtid = ++plpgsql_curr_compile->nstatements;
1696 new->is_exit = $1;
1697 new->lineno = plpgsql_location_to_lineno(@1);
1698 new->label = $2;
1699 new->cond = $3;
1700
1701 if ($2)
1702 {
1703 /* We have a label, so verify it exists */
1704 PLpgSQL_nsitem *label;
1705
1706 label = plpgsql_ns_lookup_label(plpgsql_ns_top(), $2);
1707 if (label == NULL)
1708 ereport(ERROR,
1709 (errcode(ERRCODE_SYNTAX_ERROR),
1710 errmsg("there is no label \"%s\" "
1711 "attached to any block or loop enclosing this statement",
1712 $2),
1713 parser_errposition(@2)));
1714 /* CONTINUE only allows loop labels */
1715 if (label->itemno != PLPGSQL_LABEL_LOOP && !new->is_exit)
1716 ereport(ERROR,
1717 (errcode(ERRCODE_SYNTAX_ERROR),
1718 errmsg("block label \"%s\" cannot be used in CONTINUE",
1719 $2),
1720 parser_errposition(@2)));
1721 }
1722 else
1723 {
1724 /*
1725 * No label, so make sure there is some loop (an
1726 * unlabelled EXIT does not match a block, so this
1727 * is the same test for both EXIT and CONTINUE)
1728 */
1729 if (plpgsql_ns_find_nearest_loop(plpgsql_ns_top()) == NULL)
1730 ereport(ERROR,
1731 (errcode(ERRCODE_SYNTAX_ERROR),
1732 new->is_exit ?
1733 errmsg("EXIT cannot be used outside a loop, unless it has a label") :
1734 errmsg("CONTINUE cannot be used outside a loop"),
1735 parser_errposition(@1)));
1736 }
1737
1738 $$ = (PLpgSQL_stmt *)new;
1739 }
1740 ;
1741
1742 exit_type : K_EXIT
1743 {
1744 $$ = true;
1745 }
1746 | K_CONTINUE
1747 {
1748 $$ = false;
1749 }
1750 ;
1751
1752 stmt_return : K_RETURN
1753 {
1754 int tok;
1755
1756 tok = yylex();
1757 if (tok == 0)
1758 yyerror("unexpected end of function definition");
1759
1760 if (tok_is_keyword(tok, &yylval,
1761 K_NEXT, "next"))
1762 {
1763 $$ = make_return_next_stmt(@1);
1764 }
1765 else if (tok_is_keyword(tok, &yylval,
1766 K_QUERY, "query"))
1767 {
1768 $$ = make_return_query_stmt(@1);
1769 }
1770 else
1771 {
1772 plpgsql_push_back_token(tok);
1773 $$ = make_return_stmt(@1);
1774 }
1775 }
1776 ;
1777
1778 stmt_raise : K_RAISE
1779 {
1780 PLpgSQL_stmt_raise *new;
1781 int tok;
1782
1783 new = palloc(sizeof(PLpgSQL_stmt_raise));
1784
1785 new->cmd_type = PLPGSQL_STMT_RAISE;
1786 new->lineno = plpgsql_location_to_lineno(@1);
1787 new->stmtid = ++plpgsql_curr_compile->nstatements;
1788 new->elog_level = ERROR; /* default */
1789 new->condname = NULL;
1790 new->message = NULL;
1791 new->params = NIL;
1792 new->options = NIL;
1793
1794 tok = yylex();
1795 if (tok == 0)
1796 yyerror("unexpected end of function definition");
1797
1798 /*
1799 * We could have just RAISE, meaning to re-throw
1800 * the current error.
1801 */
1802 if (tok != ';')
1803 {
1804 /*
1805 * First is an optional elog severity level.
1806 */
1807 if (tok_is_keyword(tok, &yylval,
1808 K_EXCEPTION, "exception"))
1809 {
1810 new->elog_level = ERROR;
1811 tok = yylex();
1812 }
1813 else if (tok_is_keyword(tok, &yylval,
1814 K_WARNING, "warning"))
1815 {
1816 new->elog_level = WARNING;
1817 tok = yylex();
1818 }
1819 else if (tok_is_keyword(tok, &yylval,
1820 K_NOTICE, "notice"))
1821 {
1822 new->elog_level = NOTICE;
1823 tok = yylex();
1824 }
1825 else if (tok_is_keyword(tok, &yylval,
1826 K_INFO, "info"))
1827 {
1828 new->elog_level = INFO;
1829 tok = yylex();
1830 }
1831 else if (tok_is_keyword(tok, &yylval,
1832 K_LOG, "log"))
1833 {
1834 new->elog_level = LOG;
1835 tok = yylex();
1836 }
1837 else if (tok_is_keyword(tok, &yylval,
1838 K_DEBUG, "debug"))
1839 {
1840 new->elog_level = DEBUG1;
1841 tok = yylex();
1842 }
1843 if (tok == 0)
1844 yyerror("unexpected end of function definition");
1845
1846 /*
1847 * Next we can have a condition name, or
1848 * equivalently SQLSTATE 'xxxxx', or a string
1849 * literal that is the old-style message format,
1850 * or USING to start the option list immediately.
1851 */
1852 if (tok == SCONST)
1853 {
1854 /* old style message and parameters */
1855 new->message = yylval.str;
1856 /*
1857 * We expect either a semi-colon, which
1858 * indicates no parameters, or a comma that
1859 * begins the list of parameter expressions,
1860 * or USING to begin the options list.
1861 */
1862 tok = yylex();
1863 if (tok != ',' && tok != ';' && tok != K_USING)
1864 yyerror("syntax error");
1865
1866 while (tok == ',')
1867 {
1868 PLpgSQL_expr *expr;
1869
1870 expr = read_sql_construct(',', ';', K_USING,
1871 ", or ; or USING",
1872 "SELECT ",
1873 true, true, true,
1874 NULL, &tok);
1875 new->params = lappend(new->params, expr);
1876 }
1877 }
1878 else if (tok != K_USING)
1879 {
1880 /* must be condition name or SQLSTATE */
1881 if (tok_is_keyword(tok, &yylval,
1882 K_SQLSTATE, "sqlstate"))
1883 {
1884 /* next token should be a string literal */
1885 char *sqlstatestr;
1886
1887 if (yylex() != SCONST)
1888 yyerror("syntax error");
1889 sqlstatestr = yylval.str;
1890
1891 if (strlen(sqlstatestr) != 5)
1892 yyerror("invalid SQLSTATE code");
1893 if (strspn(sqlstatestr, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != 5)
1894 yyerror("invalid SQLSTATE code");
1895 new->condname = sqlstatestr;
1896 }
1897 else
1898 {
1899 if (tok == T_WORD)
1900 new->condname = yylval.word.ident;
1901 else if (plpgsql_token_is_unreserved_keyword(tok))
1902 new->condname = pstrdup(yylval.keyword);
1903 else
1904 yyerror("syntax error");
1905 plpgsql_recognize_err_condition(new->condname,
1906 false);
1907 }
1908 tok = yylex();
1909 if (tok != ';' && tok != K_USING)
1910 yyerror("syntax error");
1911 }
1912
1913 if (tok == K_USING)
1914 new->options = read_raise_options();
1915 }
1916
1917 check_raise_parameters(new);
1918
1919 $$ = (PLpgSQL_stmt *)new;
1920 }
1921 ;
1922
1923 stmt_assert : K_ASSERT
1924 {
1925 PLpgSQL_stmt_assert *new;
1926 int tok;
1927
1928 new = palloc(sizeof(PLpgSQL_stmt_assert));
1929
1930 new->cmd_type = PLPGSQL_STMT_ASSERT;
1931 new->lineno = plpgsql_location_to_lineno(@1);
1932 new->stmtid = ++plpgsql_curr_compile->nstatements;
1933
1934 new->cond = read_sql_expression2(',', ';',
1935 ", or ;",
1936 &tok);
1937
1938 if (tok == ',')
1939 new->message = read_sql_expression(';', ";");
1940 else
1941 new->message = NULL;
1942
1943 $$ = (PLpgSQL_stmt *) new;
1944 }
1945 ;
1946
1947 loop_body : proc_sect K_END K_LOOP opt_label ';'
1948 {
1949 $$.stmts = $1;
1950 $$.end_label = $4;
1951 $$.end_label_location = @4;
1952 }
1953 ;
1954
1955 /*
1956 * T_WORD+T_CWORD match any initial identifier that is not a known plpgsql
1957 * variable. (The composite case is probably a syntax error, but we'll let
1958 * the core parser decide that.) Normally, we should assume that such a
1959 * word is a SQL statement keyword that isn't also a plpgsql keyword.
1960 * However, if the next token is assignment or '[', it can't be a valid
1961 * SQL statement, and what we're probably looking at is an intended variable
1962 * assignment. Give an appropriate complaint for that, instead of letting
1963 * the core parser throw an unhelpful "syntax error".
1964 */
1965 stmt_execsql : K_IMPORT
1966 {
1967 $$ = make_execsql_stmt(K_IMPORT, @1);
1968 }
1969 | K_INSERT
1970 {
1971 $$ = make_execsql_stmt(K_INSERT, @1);
1972 }
1973 | T_WORD
1974 {
1975 int tok;
1976
1977 tok = yylex();
1978 plpgsql_push_back_token(tok);
1979 if (tok == '=' || tok == COLON_EQUALS || tok == '[')
1980 word_is_not_variable(&($1), @1);
1981 $$ = make_execsql_stmt(T_WORD, @1);
1982 }
1983 | T_CWORD
1984 {
1985 int tok;
1986
1987 tok = yylex();
1988 plpgsql_push_back_token(tok);
1989 if (tok == '=' || tok == COLON_EQUALS || tok == '[')
1990 cword_is_not_variable(&($1), @1);
1991 $$ = make_execsql_stmt(T_CWORD, @1);
1992 }
1993 ;
1994
1995 stmt_dynexecute : K_EXECUTE
1996 {
1997 PLpgSQL_stmt_dynexecute *new;
1998 PLpgSQL_expr *expr;
1999 int endtoken;
2000
2001 expr = read_sql_construct(K_INTO, K_USING, ';',
2002 "INTO or USING or ;",
2003 "SELECT ",
2004 true, true, true,
2005 NULL, &endtoken);
2006
2007 new = palloc(sizeof(PLpgSQL_stmt_dynexecute));
2008 new->cmd_type = PLPGSQL_STMT_DYNEXECUTE;
2009 new->lineno = plpgsql_location_to_lineno(@1);
2010 new->stmtid = ++plpgsql_curr_compile->nstatements;
2011 new->query = expr;
2012 new->into = false;
2013 new->strict = false;
2014 new->target = NULL;
2015 new->params = NIL;
2016
2017 /*
2018 * We loop to allow the INTO and USING clauses to
2019 * appear in either order, since people easily get
2020 * that wrong. This coding also prevents "INTO foo"
2021 * from getting absorbed into a USING expression,
2022 * which is *really* confusing.
2023 */
2024 for (;;)
2025 {
2026 if (endtoken == K_INTO)
2027 {
2028 if (new->into) /* multiple INTO */
2029 yyerror("syntax error");
2030 new->into = true;
2031 read_into_target(&new->target, &new->strict);
2032 endtoken = yylex();
2033 }
2034 else if (endtoken == K_USING)
2035 {
2036 if (new->params) /* multiple USING */
2037 yyerror("syntax error");
2038 do
2039 {
2040 expr = read_sql_construct(',', ';', K_INTO,
2041 ", or ; or INTO",
2042 "SELECT ",
2043 true, true, true,
2044 NULL, &endtoken);
2045 new->params = lappend(new->params, expr);
2046 } while (endtoken == ',');
2047 }
2048 else if (endtoken == ';')
2049 break;
2050 else
2051 yyerror("syntax error");
2052 }
2053
2054 $$ = (PLpgSQL_stmt *)new;
2055 }
2056 ;
2057
2058
2059 stmt_open : K_OPEN cursor_variable
2060 {
2061 PLpgSQL_stmt_open *new;
2062 int tok;
2063
2064 new = palloc0(sizeof(PLpgSQL_stmt_open));
2065 new->cmd_type = PLPGSQL_STMT_OPEN;
2066 new->lineno = plpgsql_location_to_lineno(@1);
2067 new->stmtid = ++plpgsql_curr_compile->nstatements;
2068 new->curvar = $2->dno;
2069 new->cursor_options = CURSOR_OPT_FAST_PLAN;
2070
2071 if ($2->cursor_explicit_expr == NULL)
2072 {
2073 /* be nice if we could use opt_scrollable here */
2074 tok = yylex();
2075 if (tok_is_keyword(tok, &yylval,
2076 K_NO, "no"))
2077 {
2078 tok = yylex();
2079 if (tok_is_keyword(tok, &yylval,
2080 K_SCROLL, "scroll"))
2081 {
2082 new->cursor_options |= CURSOR_OPT_NO_SCROLL;
2083 tok = yylex();
2084 }
2085 }
2086 else if (tok_is_keyword(tok, &yylval,
2087 K_SCROLL, "scroll"))
2088 {
2089 new->cursor_options |= CURSOR_OPT_SCROLL;
2090 tok = yylex();
2091 }
2092
2093 if (tok != K_FOR)
2094 yyerror("syntax error, expected \"FOR\"");
2095
2096 tok = yylex();
2097 if (tok == K_EXECUTE)
2098 {
2099 int endtoken;
2100
2101 new->dynquery =
2102 read_sql_expression2(K_USING, ';',
2103 "USING or ;",
2104 &endtoken);
2105
2106 /* If we found "USING", collect argument(s) */
2107 if (endtoken == K_USING)
2108 {
2109 PLpgSQL_expr *expr;
2110
2111 do
2112 {
2113 expr = read_sql_expression2(',', ';',
2114 ", or ;",
2115 &endtoken);
2116 new->params = lappend(new->params,
2117 expr);
2118 } while (endtoken == ',');
2119 }
2120 }
2121 else
2122 {
2123 plpgsql_push_back_token(tok);
2124 new->query = read_sql_stmt("");
2125 }
2126 }
2127 else
2128 {
2129 /* predefined cursor query, so read args */
2130 new->argquery = read_cursor_args($2, ';', ";");
2131 }
2132
2133 $$ = (PLpgSQL_stmt *)new;
2134 }
2135 ;
2136
2137 stmt_fetch : K_FETCH opt_fetch_direction cursor_variable K_INTO
2138 {
2139 PLpgSQL_stmt_fetch *fetch = $2;
2140 PLpgSQL_variable *target;
2141
2142 /* We have already parsed everything through the INTO keyword */
2143 read_into_target(&target, NULL);
2144
2145 if (yylex() != ';')
2146 yyerror("syntax error");
2147
2148 /*
2149 * We don't allow multiple rows in PL/pgSQL's FETCH
2150 * statement, only in MOVE.
2151 */
2152 if (fetch->returns_multiple_rows)
2153 ereport(ERROR,
2154 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2155 errmsg("FETCH statement cannot return multiple rows"),
2156 parser_errposition(@1)));
2157
2158 fetch->lineno = plpgsql_location_to_lineno(@1);
2159 fetch->target = target;
2160 fetch->curvar = $3->dno;
2161 fetch->is_move = false;
2162
2163 $$ = (PLpgSQL_stmt *)fetch;
2164 }
2165 ;
2166
2167 stmt_move : K_MOVE opt_fetch_direction cursor_variable ';'
2168 {
2169 PLpgSQL_stmt_fetch *fetch = $2;
2170
2171 fetch->lineno = plpgsql_location_to_lineno(@1);
2172 fetch->curvar = $3->dno;
2173 fetch->is_move = true;
2174
2175 $$ = (PLpgSQL_stmt *)fetch;
2176 }
2177 ;
2178
2179 opt_fetch_direction :
2180 {
2181 $$ = read_fetch_direction();
2182 }
2183 ;
2184
2185 stmt_close : K_CLOSE cursor_variable ';'
2186 {
2187 PLpgSQL_stmt_close *new;
2188
2189 new = palloc(sizeof(PLpgSQL_stmt_close));
2190 new->cmd_type = PLPGSQL_STMT_CLOSE;
2191 new->lineno = plpgsql_location_to_lineno(@1);
2192 new->stmtid = ++plpgsql_curr_compile->nstatements;
2193 new->curvar = $2->dno;
2194
2195 $$ = (PLpgSQL_stmt *)new;
2196 }
2197 ;
2198
2199 stmt_null : K_NULL ';'
2200 {
2201 /* We do not bother building a node for NULL */
2202 $$ = NULL;
2203 }
2204 ;
2205
2206 stmt_commit : K_COMMIT opt_transaction_chain ';'
2207 {
2208 PLpgSQL_stmt_commit *new;
2209
2210 new = palloc(sizeof(PLpgSQL_stmt_commit));
2211 new->cmd_type = PLPGSQL_STMT_COMMIT;
2212 new->lineno = plpgsql_location_to_lineno(@1);
2213 new->stmtid = ++plpgsql_curr_compile->nstatements;
2214 new->chain = $2;
2215
2216 $$ = (PLpgSQL_stmt *)new;
2217 }
2218 ;
2219
2220 stmt_rollback : K_ROLLBACK opt_transaction_chain ';'
2221 {
2222 PLpgSQL_stmt_rollback *new;
2223
2224 new = palloc(sizeof(PLpgSQL_stmt_rollback));
2225 new->cmd_type = PLPGSQL_STMT_ROLLBACK;
2226 new->lineno = plpgsql_location_to_lineno(@1);
2227 new->stmtid = ++plpgsql_curr_compile->nstatements;
2228 new->chain = $2;
2229
2230 $$ = (PLpgSQL_stmt *)new;
2231 }
2232 ;
2233
2234 opt_transaction_chain:
2235 K_AND K_CHAIN { $$ = true; }
2236 | K_AND K_NO K_CHAIN { $$ = false; }
2237 | /* EMPTY */ { $$ = false; }
2238 ;
2239
2240 stmt_set : K_SET
2241 {
2242 PLpgSQL_stmt_set *new;
2243
2244 new = palloc0(sizeof(PLpgSQL_stmt_set));
2245 new->cmd_type = PLPGSQL_STMT_SET;
2246 new->lineno = plpgsql_location_to_lineno(@1);
2247 new->stmtid = ++plpgsql_curr_compile->nstatements;
2248
2249 new->expr = read_sql_stmt("SET ");
2250
2251 $$ = (PLpgSQL_stmt *)new;
2252 }
2253 | K_RESET
2254 {
2255 PLpgSQL_stmt_set *new;
2256
2257 new = palloc0(sizeof(PLpgSQL_stmt_set));
2258 new->cmd_type = PLPGSQL_STMT_SET;
2259 new->lineno = plpgsql_location_to_lineno(@1);
2260 new->stmtid = ++plpgsql_curr_compile->nstatements;
2261 new->expr = read_sql_stmt("RESET ");
2262
2263 $$ = (PLpgSQL_stmt *)new;
2264 }
2265 ;
2266
2267
2268 cursor_variable : T_DATUM
2269 {
2270 /*
2271 * In principle we should support a cursor_variable
2272 * that is an array element, but for now we don't, so
2273 * just throw an error if next token is '['.
2274 */
2275 if ($1.datum->dtype != PLPGSQL_DTYPE_VAR ||
2276 plpgsql_peek() == '[')
2277 ereport(ERROR,
2278 (errcode(ERRCODE_DATATYPE_MISMATCH),
2279 errmsg("cursor variable must be a simple variable"),
2280 parser_errposition(@1)));
2281
2282 if (((PLpgSQL_var *) $1.datum)->datatype->typoid != REFCURSOROID)
2283 ereport(ERROR,
2284 (errcode(ERRCODE_DATATYPE_MISMATCH),
2285 errmsg("variable \"%s\" must be of type cursor or refcursor",
2286 ((PLpgSQL_var *) $1.datum)->refname),
2287 parser_errposition(@1)));
2288 $$ = (PLpgSQL_var *) $1.datum;
2289 }
2290 | T_WORD
2291 {
2292 /* just to give a better message than "syntax error" */
2293 word_is_not_variable(&($1), @1);
2294 }
2295 | T_CWORD
2296 {
2297 /* just to give a better message than "syntax error" */
2298 cword_is_not_variable(&($1), @1);
2299 }
2300 ;
2301
2302 exception_sect :
2303 { $$ = NULL; }
2304 | K_EXCEPTION
2305 {
2306 /*
2307 * We use a mid-rule action to add these
2308 * special variables to the namespace before
2309 * parsing the WHEN clauses themselves. The
2310 * scope of the names extends to the end of the
2311 * current block.
2312 */
2313 int lineno = plpgsql_location_to_lineno(@1);
2314 PLpgSQL_exception_block *new = palloc(sizeof(PLpgSQL_exception_block));
2315 PLpgSQL_variable *var;
2316
2317 var = plpgsql_build_variable("sqlstate", lineno,
2318 plpgsql_build_datatype(TEXTOID,
2319 -1,
2320 plpgsql_curr_compile->fn_input_collation,
2321 NULL),
2322 true);
2323 var->isconst = true;
2324 new->sqlstate_varno = var->dno;
2325
2326 var = plpgsql_build_variable("sqlerrm", lineno,
2327 plpgsql_build_datatype(TEXTOID,
2328 -1,
2329 plpgsql_curr_compile->fn_input_collation,
2330 NULL),
2331 true);
2332 var->isconst = true;
2333 new->sqlerrm_varno = var->dno;
2334
2335 $<exception_block>$ = new;
2336 }
2337 proc_exceptions
2338 {
2339 PLpgSQL_exception_block *new = $<exception_block>2;
2340 new->exc_list = $3;
2341
2342 $$ = new;
2343 }
2344 ;
2345
2346 proc_exceptions : proc_exceptions proc_exception
2347 {
2348 $$ = lappend($1, $2);
2349 }
2350 | proc_exception
2351 {
2352 $$ = list_make1($1);
2353 }
2354 ;
2355
2356 proc_exception : K_WHEN proc_conditions K_THEN proc_sect
2357 {
2358 PLpgSQL_exception *new;
2359
2360 new = palloc0(sizeof(PLpgSQL_exception));
2361 new->lineno = plpgsql_location_to_lineno(@1);
2362 new->conditions = $2;
2363 new->action = $4;
2364
2365 $$ = new;
2366 }
2367 ;
2368
2369 proc_conditions : proc_conditions K_OR proc_condition
2370 {
2371 PLpgSQL_condition *old;
2372
2373 for (old = $1; old->next != NULL; old = old->next)
2374 /* skip */ ;
2375 old->next = $3;
2376 $$ = $1;
2377 }
2378 | proc_condition
2379 {
2380 $$ = $1;
2381 }
2382 ;
2383
2384 proc_condition : any_identifier
2385 {
2386 if (strcmp($1, "sqlstate") != 0)
2387 {
2388 $$ = plpgsql_parse_err_condition($1);
2389 }
2390 else
2391 {
2392 PLpgSQL_condition *new;
2393 char *sqlstatestr;
2394
2395 /* next token should be a string literal */
2396 if (yylex() != SCONST)
2397 yyerror("syntax error");
2398 sqlstatestr = yylval.str;
2399
2400 if (strlen(sqlstatestr) != 5)
2401 yyerror("invalid SQLSTATE code");
2402 if (strspn(sqlstatestr, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != 5)
2403 yyerror("invalid SQLSTATE code");
2404
2405 new = palloc(sizeof(PLpgSQL_condition));
2406 new->sqlerrstate =
2407 MAKE_SQLSTATE(sqlstatestr[0],
2408 sqlstatestr[1],
2409 sqlstatestr[2],
2410 sqlstatestr[3],
2411 sqlstatestr[4]);
2412 new->condname = sqlstatestr;
2413 new->next = NULL;
2414
2415 $$ = new;
2416 }
2417 }
2418 ;
2419
2420 expr_until_semi :
2421 { $$ = read_sql_expression(';', ";"); }
2422 ;
2423
2424 expr_until_rightbracket :
2425 { $$ = read_sql_expression(']', "]"); }
2426 ;
2427
2428 expr_until_then :
2429 { $$ = read_sql_expression(K_THEN, "THEN"); }
2430 ;
2431
2432 expr_until_loop :
2433 { $$ = read_sql_expression(K_LOOP, "LOOP"); }
2434 ;
2435
2436 opt_block_label :
2437 {
2438 plpgsql_ns_push(NULL, PLPGSQL_LABEL_BLOCK);
2439 $$ = NULL;
2440 }
2441 | LESS_LESS any_identifier GREATER_GREATER
2442 {
2443 plpgsql_ns_push($2, PLPGSQL_LABEL_BLOCK);
2444 $$ = $2;
2445 }
2446 ;
2447
2448 opt_loop_label :
2449 {
2450 plpgsql_ns_push(NULL, PLPGSQL_LABEL_LOOP);
2451 $$ = NULL;
2452 }
2453 | LESS_LESS any_identifier GREATER_GREATER
2454 {
2455 plpgsql_ns_push($2, PLPGSQL_LABEL_LOOP);
2456 $$ = $2;
2457 }
2458 ;
2459
2460 opt_label :
2461 {
2462 $$ = NULL;
2463 }
2464 | any_identifier
2465 {
2466 /* label validity will be checked by outer production */
2467 $$ = $1;
2468 }
2469 ;
2470
2471 opt_exitcond : ';'
2472 { $$ = NULL; }
2473 | K_WHEN expr_until_semi
2474 { $$ = $2; }
2475 ;
2476
2477 /*
2478 * need to allow DATUM because scanner will have tried to resolve as variable
2479 */
2480 any_identifier : T_WORD
2481 {
2482 $$ = $1.ident;
2483 }
2484 | unreserved_keyword
2485 {
2486 $$ = pstrdup($1);
2487 }
2488 | T_DATUM
2489 {
2490 if ($1.ident == NULL) /* composite name not OK */
2491 yyerror("syntax error");
2492 $$ = $1.ident;
2493 }
2494 ;
2495
2496 unreserved_keyword :
2497 K_ABSOLUTE
2498 | K_ALIAS
2499 | K_AND
2500 | K_ARRAY
2501 | K_ASSERT
2502 | K_BACKWARD
2503 | K_CALL
2504 | K_CHAIN
2505 | K_CLOSE
2506 | K_COLLATE
2507 | K_COLUMN
2508 | K_COLUMN_NAME
2509 | K_COMMIT
2510 | K_CONSTANT
2511 | K_CONSTRAINT
2512 | K_CONSTRAINT_NAME
2513 | K_CONTINUE
2514 | K_CURRENT
2515 | K_CURSOR
2516 | K_DATATYPE
2517 | K_DEBUG
2518 | K_DEFAULT
2519 | K_DETAIL
2520 | K_DIAGNOSTICS
2521 | K_DO
2522 | K_DUMP
2523 | K_ELSIF
2524 | K_ERRCODE
2525 | K_ERROR
2526 | K_EXCEPTION
2527 | K_EXIT
2528 | K_FETCH
2529 | K_FIRST
2530 | K_FORWARD
2531 | K_GET
2532 | K_HINT
2533 | K_IMPORT
2534 | K_INFO
2535 | K_INSERT
2536 | K_IS
2537 | K_LAST
2538 | K_LOG
2539 | K_MESSAGE
2540 | K_MESSAGE_TEXT
2541 | K_MOVE
2542 | K_NEXT
2543 | K_NO
2544 | K_NOTICE
2545 | K_OPEN
2546 | K_OPTION
2547 | K_PERFORM
2548 | K_PG_CONTEXT
2549 | K_PG_DATATYPE_NAME
2550 | K_PG_EXCEPTION_CONTEXT
2551 | K_PG_EXCEPTION_DETAIL
2552 | K_PG_EXCEPTION_HINT
2553 | K_PRINT_STRICT_PARAMS
2554 | K_PRIOR
2555 | K_QUERY
2556 | K_RAISE
2557 | K_RELATIVE
2558 | K_RESET
2559 | K_RETURN
2560 | K_RETURNED_SQLSTATE
2561 | K_REVERSE
2562 | K_ROLLBACK
2563 | K_ROW_COUNT
2564 | K_ROWTYPE
2565 | K_SCHEMA
2566 | K_SCHEMA_NAME
2567 | K_SCROLL
2568 | K_SET
2569 | K_SLICE
2570 | K_SQLSTATE
2571 | K_STACKED
2572 | K_TABLE
2573 | K_TABLE_NAME
2574 | K_TYPE
2575 | K_USE_COLUMN
2576 | K_USE_VARIABLE
2577 | K_VARIABLE_CONFLICT
2578 | K_WARNING
2579 ;
2580
2581 %%
2582
2583 /*
2584 * Check whether a token represents an "unreserved keyword".
2585 * We have various places where we want to recognize a keyword in preference
2586 * to a variable name, but not reserve that keyword in other contexts.
2587 * Hence, this kluge.
2588 */
2589 static bool
2590 tok_is_keyword(int token, union YYSTYPE *lval,
2591 int kw_token, const char *kw_str)
2592 {
2593 if (token == kw_token)
2594 {
2595 /* Normal case, was recognized by scanner (no conflicting variable) */
2596 return true;
2597 }
2598 else if (token == T_DATUM)
2599 {
2600 /*
2601 * It's a variable, so recheck the string name. Note we will not
2602 * match composite names (hence an unreserved word followed by "."
2603 * will not be recognized).
2604 */
2605 if (!lval->wdatum.quoted && lval->wdatum.ident != NULL &&
2606 strcmp(lval->wdatum.ident, kw_str) == 0)
2607 return true;
2608 }
2609 return false; /* not the keyword */
2610 }
2611
2612 /*
2613 * Convenience routine to complain when we expected T_DATUM and got T_WORD,
2614 * ie, unrecognized variable.
2615 */
2616 static void
word_is_not_variable(PLword * word,int location)2617 word_is_not_variable(PLword *word, int location)
2618 {
2619 ereport(ERROR,
2620 (errcode(ERRCODE_SYNTAX_ERROR),
2621 errmsg("\"%s\" is not a known variable",
2622 word->ident),
2623 parser_errposition(location)));
2624 }
2625
2626 /* Same, for a CWORD */
2627 static void
cword_is_not_variable(PLcword * cword,int location)2628 cword_is_not_variable(PLcword *cword, int location)
2629 {
2630 ereport(ERROR,
2631 (errcode(ERRCODE_SYNTAX_ERROR),
2632 errmsg("\"%s\" is not a known variable",
2633 NameListToString(cword->idents)),
2634 parser_errposition(location)));
2635 }
2636
2637 /*
2638 * Convenience routine to complain when we expected T_DATUM and got
2639 * something else. "tok" must be the current token, since we also
2640 * look at yylval and yylloc.
2641 */
2642 static void
current_token_is_not_variable(int tok)2643 current_token_is_not_variable(int tok)
2644 {
2645 if (tok == T_WORD)
2646 word_is_not_variable(&(yylval.word), yylloc);
2647 else if (tok == T_CWORD)
2648 cword_is_not_variable(&(yylval.cword), yylloc);
2649 else
2650 yyerror("syntax error");
2651 }
2652
2653 /* Convenience routine to read an expression with one possible terminator */
2654 static PLpgSQL_expr *
read_sql_expression(int until,const char * expected)2655 read_sql_expression(int until, const char *expected)
2656 {
2657 return read_sql_construct(until, 0, 0, expected,
2658 "SELECT ", true, true, true, NULL, NULL);
2659 }
2660
2661 /* Convenience routine to read an expression with two possible terminators */
2662 static PLpgSQL_expr *
read_sql_expression2(int until,int until2,const char * expected,int * endtoken)2663 read_sql_expression2(int until, int until2, const char *expected,
2664 int *endtoken)
2665 {
2666 return read_sql_construct(until, until2, 0, expected,
2667 "SELECT ", true, true, true, NULL, endtoken);
2668 }
2669
2670 /* Convenience routine to read a SQL statement that must end with ';' */
2671 static PLpgSQL_expr *
read_sql_stmt(const char * sqlstart)2672 read_sql_stmt(const char *sqlstart)
2673 {
2674 return read_sql_construct(';', 0, 0, ";",
2675 sqlstart, false, true, true, NULL, NULL);
2676 }
2677
2678 /*
2679 * Read a SQL construct and build a PLpgSQL_expr for it.
2680 *
2681 * until: token code for expected terminator
2682 * until2: token code for alternate terminator (pass 0 if none)
2683 * until3: token code for another alternate terminator (pass 0 if none)
2684 * expected: text to use in complaining that terminator was not found
2685 * sqlstart: text to prefix to the accumulated SQL text
2686 * isexpression: whether to say we're reading an "expression" or a "statement"
2687 * valid_sql: whether to check the syntax of the expr (prefixed with sqlstart)
2688 * trim: trim trailing whitespace
2689 * startloc: if not NULL, location of first token is stored at *startloc
2690 * endtoken: if not NULL, ending token is stored at *endtoken
2691 * (this is only interesting if until2 or until3 isn't zero)
2692 */
2693 static PLpgSQL_expr *
read_sql_construct(int until,int until2,int until3,const char * expected,const char * sqlstart,bool isexpression,bool valid_sql,bool trim,int * startloc,int * endtoken)2694 read_sql_construct(int until,
2695 int until2,
2696 int until3,
2697 const char *expected,
2698 const char *sqlstart,
2699 bool isexpression,
2700 bool valid_sql,
2701 bool trim,
2702 int *startloc,
2703 int *endtoken)
2704 {
2705 int tok;
2706 StringInfoData ds;
2707 IdentifierLookup save_IdentifierLookup;
2708 int startlocation = -1;
2709 int parenlevel = 0;
2710 PLpgSQL_expr *expr;
2711
2712 initStringInfo(&ds);
2713 appendStringInfoString(&ds, sqlstart);
2714
2715 /* special lookup mode for identifiers within the SQL text */
2716 save_IdentifierLookup = plpgsql_IdentifierLookup;
2717 plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_EXPR;
2718
2719 for (;;)
2720 {
2721 tok = yylex();
2722 if (startlocation < 0) /* remember loc of first token */
2723 startlocation = yylloc;
2724 if (tok == until && parenlevel == 0)
2725 break;
2726 if (tok == until2 && parenlevel == 0)
2727 break;
2728 if (tok == until3 && parenlevel == 0)
2729 break;
2730 if (tok == '(' || tok == '[')
2731 parenlevel++;
2732 else if (tok == ')' || tok == ']')
2733 {
2734 parenlevel--;
2735 if (parenlevel < 0)
2736 yyerror("mismatched parentheses");
2737 }
2738 /*
2739 * End of function definition is an error, and we don't expect to
2740 * hit a semicolon either (unless it's the until symbol, in which
2741 * case we should have fallen out above).
2742 */
2743 if (tok == 0 || tok == ';')
2744 {
2745 if (parenlevel != 0)
2746 yyerror("mismatched parentheses");
2747 if (isexpression)
2748 ereport(ERROR,
2749 (errcode(ERRCODE_SYNTAX_ERROR),
2750 errmsg("missing \"%s\" at end of SQL expression",
2751 expected),
2752 parser_errposition(yylloc)));
2753 else
2754 ereport(ERROR,
2755 (errcode(ERRCODE_SYNTAX_ERROR),
2756 errmsg("missing \"%s\" at end of SQL statement",
2757 expected),
2758 parser_errposition(yylloc)));
2759 }
2760 }
2761
2762 plpgsql_IdentifierLookup = save_IdentifierLookup;
2763
2764 if (startloc)
2765 *startloc = startlocation;
2766 if (endtoken)
2767 *endtoken = tok;
2768
2769 /* give helpful complaint about empty input */
2770 if (startlocation >= yylloc)
2771 {
2772 if (isexpression)
2773 yyerror("missing expression");
2774 else
2775 yyerror("missing SQL statement");
2776 }
2777
2778 plpgsql_append_source_text(&ds, startlocation, yylloc);
2779
2780 /* trim any trailing whitespace, for neatness */
2781 if (trim)
2782 {
2783 while (ds.len > 0 && scanner_isspace(ds.data[ds.len - 1]))
2784 ds.data[--ds.len] = '\0';
2785 }
2786
2787 expr = palloc0(sizeof(PLpgSQL_expr));
2788 expr->query = pstrdup(ds.data);
2789 expr->plan = NULL;
2790 expr->paramnos = NULL;
2791 expr->rwparam = -1;
2792 expr->ns = plpgsql_ns_top();
2793 pfree(ds.data);
2794
2795 if (valid_sql)
2796 check_sql_expr(expr->query, startlocation, strlen(sqlstart));
2797
2798 return expr;
2799 }
2800
2801 static PLpgSQL_type *
read_datatype(int tok)2802 read_datatype(int tok)
2803 {
2804 StringInfoData ds;
2805 char *type_name;
2806 int startlocation;
2807 PLpgSQL_type *result;
2808 int parenlevel = 0;
2809
2810 /* Should only be called while parsing DECLARE sections */
2811 Assert(plpgsql_IdentifierLookup == IDENTIFIER_LOOKUP_DECLARE);
2812
2813 /* Often there will be a lookahead token, but if not, get one */
2814 if (tok == YYEMPTY)
2815 tok = yylex();
2816
2817 startlocation = yylloc;
2818
2819 /*
2820 * If we have a simple or composite identifier, check for %TYPE
2821 * and %ROWTYPE constructs.
2822 */
2823 if (tok == T_WORD)
2824 {
2825 char *dtname = yylval.word.ident;
2826
2827 tok = yylex();
2828 if (tok == '%')
2829 {
2830 tok = yylex();
2831 if (tok_is_keyword(tok, &yylval,
2832 K_TYPE, "type"))
2833 {
2834 result = plpgsql_parse_wordtype(dtname);
2835 if (result)
2836 return result;
2837 }
2838 else if (tok_is_keyword(tok, &yylval,
2839 K_ROWTYPE, "rowtype"))
2840 {
2841 result = plpgsql_parse_wordrowtype(dtname);
2842 if (result)
2843 return result;
2844 }
2845 }
2846 }
2847 else if (plpgsql_token_is_unreserved_keyword(tok))
2848 {
2849 char *dtname = pstrdup(yylval.keyword);
2850
2851 tok = yylex();
2852 if (tok == '%')
2853 {
2854 tok = yylex();
2855 if (tok_is_keyword(tok, &yylval,
2856 K_TYPE, "type"))
2857 {
2858 result = plpgsql_parse_wordtype(dtname);
2859 if (result)
2860 return result;
2861 }
2862 else if (tok_is_keyword(tok, &yylval,
2863 K_ROWTYPE, "rowtype"))
2864 {
2865 result = plpgsql_parse_wordrowtype(dtname);
2866 if (result)
2867 return result;
2868 }
2869 }
2870 }
2871 else if (tok == T_CWORD)
2872 {
2873 List *dtnames = yylval.cword.idents;
2874
2875 tok = yylex();
2876 if (tok == '%')
2877 {
2878 tok = yylex();
2879 if (tok_is_keyword(tok, &yylval,
2880 K_TYPE, "type"))
2881 {
2882 result = plpgsql_parse_cwordtype(dtnames);
2883 if (result)
2884 return result;
2885 }
2886 else if (tok_is_keyword(tok, &yylval,
2887 K_ROWTYPE, "rowtype"))
2888 {
2889 result = plpgsql_parse_cwordrowtype(dtnames);
2890 if (result)
2891 return result;
2892 }
2893 }
2894 }
2895
2896 while (tok != ';')
2897 {
2898 if (tok == 0)
2899 {
2900 if (parenlevel != 0)
2901 yyerror("mismatched parentheses");
2902 else
2903 yyerror("incomplete data type declaration");
2904 }
2905 /* Possible followers for datatype in a declaration */
2906 if (tok == K_COLLATE || tok == K_NOT ||
2907 tok == '=' || tok == COLON_EQUALS || tok == K_DEFAULT)
2908 break;
2909 /* Possible followers for datatype in a cursor_arg list */
2910 if ((tok == ',' || tok == ')') && parenlevel == 0)
2911 break;
2912 if (tok == '(')
2913 parenlevel++;
2914 else if (tok == ')')
2915 parenlevel--;
2916
2917 tok = yylex();
2918 }
2919
2920 /* set up ds to contain complete typename text */
2921 initStringInfo(&ds);
2922 plpgsql_append_source_text(&ds, startlocation, yylloc);
2923 type_name = ds.data;
2924
2925 if (type_name[0] == '\0')
2926 yyerror("missing data type declaration");
2927
2928 result = parse_datatype(type_name, startlocation);
2929
2930 pfree(ds.data);
2931
2932 plpgsql_push_back_token(tok);
2933
2934 return result;
2935 }
2936
2937 static PLpgSQL_stmt *
make_execsql_stmt(int firsttoken,int location)2938 make_execsql_stmt(int firsttoken, int location)
2939 {
2940 StringInfoData ds;
2941 IdentifierLookup save_IdentifierLookup;
2942 PLpgSQL_stmt_execsql *execsql;
2943 PLpgSQL_expr *expr;
2944 PLpgSQL_variable *target = NULL;
2945 int tok;
2946 int prev_tok;
2947 bool have_into = false;
2948 bool have_strict = false;
2949 int into_start_loc = -1;
2950 int into_end_loc = -1;
2951
2952 initStringInfo(&ds);
2953
2954 /* special lookup mode for identifiers within the SQL text */
2955 save_IdentifierLookup = plpgsql_IdentifierLookup;
2956 plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_EXPR;
2957
2958 /*
2959 * Scan to the end of the SQL command. Identify any INTO-variables
2960 * clause lurking within it, and parse that via read_into_target().
2961 *
2962 * Because INTO is sometimes used in the main SQL grammar, we have to be
2963 * careful not to take any such usage of INTO as a PL/pgSQL INTO clause.
2964 * There are currently three such cases:
2965 *
2966 * 1. SELECT ... INTO. We don't care, we just override that with the
2967 * PL/pgSQL definition.
2968 *
2969 * 2. INSERT INTO. This is relatively easy to recognize since the words
2970 * must appear adjacently; but we can't assume INSERT starts the command,
2971 * because it can appear in CREATE RULE or WITH. Unfortunately, INSERT is
2972 * *not* fully reserved, so that means there is a chance of a false match;
2973 * but it's not very likely.
2974 *
2975 * 3. IMPORT FOREIGN SCHEMA ... INTO. This is not allowed in CREATE RULE
2976 * or WITH, so we just check for IMPORT as the command's first token.
2977 * (If IMPORT FOREIGN SCHEMA returned data someone might wish to capture
2978 * with an INTO-variables clause, we'd have to work much harder here.)
2979 *
2980 * Fortunately, INTO is a fully reserved word in the main grammar, so
2981 * at least we need not worry about it appearing as an identifier.
2982 *
2983 * Any future additional uses of INTO in the main grammar will doubtless
2984 * break this logic again ... beware!
2985 */
2986 tok = firsttoken;
2987 for (;;)
2988 {
2989 prev_tok = tok;
2990 tok = yylex();
2991 if (have_into && into_end_loc < 0)
2992 into_end_loc = yylloc; /* token after the INTO part */
2993 if (tok == ';')
2994 break;
2995 if (tok == 0)
2996 yyerror("unexpected end of function definition");
2997 if (tok == K_INTO)
2998 {
2999 if (prev_tok == K_INSERT)
3000 continue; /* INSERT INTO is not an INTO-target */
3001 if (firsttoken == K_IMPORT)
3002 continue; /* IMPORT ... INTO is not an INTO-target */
3003 if (have_into)
3004 yyerror("INTO specified more than once");
3005 have_into = true;
3006 into_start_loc = yylloc;
3007 plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL;
3008 read_into_target(&target, &have_strict);
3009 plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_EXPR;
3010 }
3011 }
3012
3013 plpgsql_IdentifierLookup = save_IdentifierLookup;
3014
3015 if (have_into)
3016 {
3017 /*
3018 * Insert an appropriate number of spaces corresponding to the
3019 * INTO text, so that locations within the redacted SQL statement
3020 * still line up with those in the original source text.
3021 */
3022 plpgsql_append_source_text(&ds, location, into_start_loc);
3023 appendStringInfoSpaces(&ds, into_end_loc - into_start_loc);
3024 plpgsql_append_source_text(&ds, into_end_loc, yylloc);
3025 }
3026 else
3027 plpgsql_append_source_text(&ds, location, yylloc);
3028
3029 /* trim any trailing whitespace, for neatness */
3030 while (ds.len > 0 && scanner_isspace(ds.data[ds.len - 1]))
3031 ds.data[--ds.len] = '\0';
3032
3033 expr = palloc0(sizeof(PLpgSQL_expr));
3034 expr->query = pstrdup(ds.data);
3035 expr->plan = NULL;
3036 expr->paramnos = NULL;
3037 expr->rwparam = -1;
3038 expr->ns = plpgsql_ns_top();
3039 pfree(ds.data);
3040
3041 check_sql_expr(expr->query, location, 0);
3042
3043 execsql = palloc0(sizeof(PLpgSQL_stmt_execsql));
3044 execsql->cmd_type = PLPGSQL_STMT_EXECSQL;
3045 execsql->lineno = plpgsql_location_to_lineno(location);
3046 execsql->stmtid = ++plpgsql_curr_compile->nstatements;
3047 execsql->sqlstmt = expr;
3048 execsql->into = have_into;
3049 execsql->strict = have_strict;
3050 execsql->target = target;
3051
3052 return (PLpgSQL_stmt *) execsql;
3053 }
3054
3055
3056 /*
3057 * Read FETCH or MOVE direction clause (everything through FROM/IN).
3058 */
3059 static PLpgSQL_stmt_fetch *
read_fetch_direction(void)3060 read_fetch_direction(void)
3061 {
3062 PLpgSQL_stmt_fetch *fetch;
3063 int tok;
3064 bool check_FROM = true;
3065
3066 /*
3067 * We create the PLpgSQL_stmt_fetch struct here, but only fill in
3068 * the fields arising from the optional direction clause
3069 */
3070 fetch = (PLpgSQL_stmt_fetch *) palloc0(sizeof(PLpgSQL_stmt_fetch));
3071 fetch->cmd_type = PLPGSQL_STMT_FETCH;
3072 fetch->stmtid = ++plpgsql_curr_compile->nstatements;
3073 /* set direction defaults: */
3074 fetch->direction = FETCH_FORWARD;
3075 fetch->how_many = 1;
3076 fetch->expr = NULL;
3077 fetch->returns_multiple_rows = false;
3078
3079 tok = yylex();
3080 if (tok == 0)
3081 yyerror("unexpected end of function definition");
3082
3083 if (tok_is_keyword(tok, &yylval,
3084 K_NEXT, "next"))
3085 {
3086 /* use defaults */
3087 }
3088 else if (tok_is_keyword(tok, &yylval,
3089 K_PRIOR, "prior"))
3090 {
3091 fetch->direction = FETCH_BACKWARD;
3092 }
3093 else if (tok_is_keyword(tok, &yylval,
3094 K_FIRST, "first"))
3095 {
3096 fetch->direction = FETCH_ABSOLUTE;
3097 }
3098 else if (tok_is_keyword(tok, &yylval,
3099 K_LAST, "last"))
3100 {
3101 fetch->direction = FETCH_ABSOLUTE;
3102 fetch->how_many = -1;
3103 }
3104 else if (tok_is_keyword(tok, &yylval,
3105 K_ABSOLUTE, "absolute"))
3106 {
3107 fetch->direction = FETCH_ABSOLUTE;
3108 fetch->expr = read_sql_expression2(K_FROM, K_IN,
3109 "FROM or IN",
3110 NULL);
3111 check_FROM = false;
3112 }
3113 else if (tok_is_keyword(tok, &yylval,
3114 K_RELATIVE, "relative"))
3115 {
3116 fetch->direction = FETCH_RELATIVE;
3117 fetch->expr = read_sql_expression2(K_FROM, K_IN,
3118 "FROM or IN",
3119 NULL);
3120 check_FROM = false;
3121 }
3122 else if (tok_is_keyword(tok, &yylval,
3123 K_ALL, "all"))
3124 {
3125 fetch->how_many = FETCH_ALL;
3126 fetch->returns_multiple_rows = true;
3127 }
3128 else if (tok_is_keyword(tok, &yylval,
3129 K_FORWARD, "forward"))
3130 {
3131 complete_direction(fetch, &check_FROM);
3132 }
3133 else if (tok_is_keyword(tok, &yylval,
3134 K_BACKWARD, "backward"))
3135 {
3136 fetch->direction = FETCH_BACKWARD;
3137 complete_direction(fetch, &check_FROM);
3138 }
3139 else if (tok == K_FROM || tok == K_IN)
3140 {
3141 /* empty direction */
3142 check_FROM = false;
3143 }
3144 else if (tok == T_DATUM)
3145 {
3146 /* Assume there's no direction clause and tok is a cursor name */
3147 plpgsql_push_back_token(tok);
3148 check_FROM = false;
3149 }
3150 else
3151 {
3152 /*
3153 * Assume it's a count expression with no preceding keyword.
3154 * Note: we allow this syntax because core SQL does, but we don't
3155 * document it because of the ambiguity with the omitted-direction
3156 * case. For instance, "MOVE n IN c" will fail if n is a variable.
3157 * Perhaps this can be improved someday, but it's hardly worth a
3158 * lot of work.
3159 */
3160 plpgsql_push_back_token(tok);
3161 fetch->expr = read_sql_expression2(K_FROM, K_IN,
3162 "FROM or IN",
3163 NULL);
3164 fetch->returns_multiple_rows = true;
3165 check_FROM = false;
3166 }
3167
3168 /* check FROM or IN keyword after direction's specification */
3169 if (check_FROM)
3170 {
3171 tok = yylex();
3172 if (tok != K_FROM && tok != K_IN)
3173 yyerror("expected FROM or IN");
3174 }
3175
3176 return fetch;
3177 }
3178
3179 /*
3180 * Process remainder of FETCH/MOVE direction after FORWARD or BACKWARD.
3181 * Allows these cases:
3182 * FORWARD expr, FORWARD ALL, FORWARD
3183 * BACKWARD expr, BACKWARD ALL, BACKWARD
3184 */
3185 static void
complete_direction(PLpgSQL_stmt_fetch * fetch,bool * check_FROM)3186 complete_direction(PLpgSQL_stmt_fetch *fetch, bool *check_FROM)
3187 {
3188 int tok;
3189
3190 tok = yylex();
3191 if (tok == 0)
3192 yyerror("unexpected end of function definition");
3193
3194 if (tok == K_FROM || tok == K_IN)
3195 {
3196 *check_FROM = false;
3197 return;
3198 }
3199
3200 if (tok == K_ALL)
3201 {
3202 fetch->how_many = FETCH_ALL;
3203 fetch->returns_multiple_rows = true;
3204 *check_FROM = true;
3205 return;
3206 }
3207
3208 plpgsql_push_back_token(tok);
3209 fetch->expr = read_sql_expression2(K_FROM, K_IN,
3210 "FROM or IN",
3211 NULL);
3212 fetch->returns_multiple_rows = true;
3213 *check_FROM = false;
3214 }
3215
3216
3217 static PLpgSQL_stmt *
make_return_stmt(int location)3218 make_return_stmt(int location)
3219 {
3220 PLpgSQL_stmt_return *new;
3221
3222 new = palloc0(sizeof(PLpgSQL_stmt_return));
3223 new->cmd_type = PLPGSQL_STMT_RETURN;
3224 new->lineno = plpgsql_location_to_lineno(location);
3225 new->stmtid = ++plpgsql_curr_compile->nstatements;
3226 new->expr = NULL;
3227 new->retvarno = -1;
3228
3229 if (plpgsql_curr_compile->fn_retset)
3230 {
3231 if (yylex() != ';')
3232 ereport(ERROR,
3233 (errcode(ERRCODE_DATATYPE_MISMATCH),
3234 errmsg("RETURN cannot have a parameter in function returning set"),
3235 errhint("Use RETURN NEXT or RETURN QUERY."),
3236 parser_errposition(yylloc)));
3237 }
3238 else if (plpgsql_curr_compile->fn_rettype == VOIDOID)
3239 {
3240 if (yylex() != ';')
3241 {
3242 if (plpgsql_curr_compile->fn_prokind == PROKIND_PROCEDURE)
3243 ereport(ERROR,
3244 (errcode(ERRCODE_SYNTAX_ERROR),
3245 errmsg("RETURN cannot have a parameter in a procedure"),
3246 parser_errposition(yylloc)));
3247 else
3248 ereport(ERROR,
3249 (errcode(ERRCODE_DATATYPE_MISMATCH),
3250 errmsg("RETURN cannot have a parameter in function returning void"),
3251 parser_errposition(yylloc)));
3252 }
3253 }
3254 else if (plpgsql_curr_compile->out_param_varno >= 0)
3255 {
3256 if (yylex() != ';')
3257 ereport(ERROR,
3258 (errcode(ERRCODE_DATATYPE_MISMATCH),
3259 errmsg("RETURN cannot have a parameter in function with OUT parameters"),
3260 parser_errposition(yylloc)));
3261 new->retvarno = plpgsql_curr_compile->out_param_varno;
3262 }
3263 else
3264 {
3265 /*
3266 * We want to special-case simple variable references for efficiency.
3267 * So peek ahead to see if that's what we have.
3268 */
3269 int tok = yylex();
3270
3271 if (tok == T_DATUM && plpgsql_peek() == ';' &&
3272 (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_VAR ||
3273 yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_PROMISE ||
3274 yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
3275 yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC))
3276 {
3277 new->retvarno = yylval.wdatum.datum->dno;
3278 /* eat the semicolon token that we only peeked at above */
3279 tok = yylex();
3280 Assert(tok == ';');
3281 }
3282 else
3283 {
3284 /*
3285 * Not (just) a variable name, so treat as expression.
3286 *
3287 * Note that a well-formed expression is _required_ here;
3288 * anything else is a compile-time error.
3289 */
3290 plpgsql_push_back_token(tok);
3291 new->expr = read_sql_expression(';', ";");
3292 }
3293 }
3294
3295 return (PLpgSQL_stmt *) new;
3296 }
3297
3298
3299 static PLpgSQL_stmt *
make_return_next_stmt(int location)3300 make_return_next_stmt(int location)
3301 {
3302 PLpgSQL_stmt_return_next *new;
3303
3304 if (!plpgsql_curr_compile->fn_retset)
3305 ereport(ERROR,
3306 (errcode(ERRCODE_DATATYPE_MISMATCH),
3307 errmsg("cannot use RETURN NEXT in a non-SETOF function"),
3308 parser_errposition(location)));
3309
3310 new = palloc0(sizeof(PLpgSQL_stmt_return_next));
3311 new->cmd_type = PLPGSQL_STMT_RETURN_NEXT;
3312 new->lineno = plpgsql_location_to_lineno(location);
3313 new->stmtid = ++plpgsql_curr_compile->nstatements;
3314 new->expr = NULL;
3315 new->retvarno = -1;
3316
3317 if (plpgsql_curr_compile->out_param_varno >= 0)
3318 {
3319 if (yylex() != ';')
3320 ereport(ERROR,
3321 (errcode(ERRCODE_DATATYPE_MISMATCH),
3322 errmsg("RETURN NEXT cannot have a parameter in function with OUT parameters"),
3323 parser_errposition(yylloc)));
3324 new->retvarno = plpgsql_curr_compile->out_param_varno;
3325 }
3326 else
3327 {
3328 /*
3329 * We want to special-case simple variable references for efficiency.
3330 * So peek ahead to see if that's what we have.
3331 */
3332 int tok = yylex();
3333
3334 if (tok == T_DATUM && plpgsql_peek() == ';' &&
3335 (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_VAR ||
3336 yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_PROMISE ||
3337 yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
3338 yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC))
3339 {
3340 new->retvarno = yylval.wdatum.datum->dno;
3341 /* eat the semicolon token that we only peeked at above */
3342 tok = yylex();
3343 Assert(tok == ';');
3344 }
3345 else
3346 {
3347 /*
3348 * Not (just) a variable name, so treat as expression.
3349 *
3350 * Note that a well-formed expression is _required_ here;
3351 * anything else is a compile-time error.
3352 */
3353 plpgsql_push_back_token(tok);
3354 new->expr = read_sql_expression(';', ";");
3355 }
3356 }
3357
3358 return (PLpgSQL_stmt *) new;
3359 }
3360
3361
3362 static PLpgSQL_stmt *
make_return_query_stmt(int location)3363 make_return_query_stmt(int location)
3364 {
3365 PLpgSQL_stmt_return_query *new;
3366 int tok;
3367
3368 if (!plpgsql_curr_compile->fn_retset)
3369 ereport(ERROR,
3370 (errcode(ERRCODE_DATATYPE_MISMATCH),
3371 errmsg("cannot use RETURN QUERY in a non-SETOF function"),
3372 parser_errposition(location)));
3373
3374 new = palloc0(sizeof(PLpgSQL_stmt_return_query));
3375 new->cmd_type = PLPGSQL_STMT_RETURN_QUERY;
3376 new->lineno = plpgsql_location_to_lineno(location);
3377 new->stmtid = ++plpgsql_curr_compile->nstatements;
3378
3379 /* check for RETURN QUERY EXECUTE */
3380 if ((tok = yylex()) != K_EXECUTE)
3381 {
3382 /* ordinary static query */
3383 plpgsql_push_back_token(tok);
3384 new->query = read_sql_stmt("");
3385 }
3386 else
3387 {
3388 /* dynamic SQL */
3389 int term;
3390
3391 new->dynquery = read_sql_expression2(';', K_USING, "; or USING",
3392 &term);
3393 if (term == K_USING)
3394 {
3395 do
3396 {
3397 PLpgSQL_expr *expr;
3398
3399 expr = read_sql_expression2(',', ';', ", or ;", &term);
3400 new->params = lappend(new->params, expr);
3401 } while (term == ',');
3402 }
3403 }
3404
3405 return (PLpgSQL_stmt *) new;
3406 }
3407
3408
3409 /* convenience routine to fetch the name of a T_DATUM */
3410 static char *
NameOfDatum(PLwdatum * wdatum)3411 NameOfDatum(PLwdatum *wdatum)
3412 {
3413 if (wdatum->ident)
3414 return wdatum->ident;
3415 Assert(wdatum->idents != NIL);
3416 return NameListToString(wdatum->idents);
3417 }
3418
3419 static void
check_assignable(PLpgSQL_datum * datum,int location)3420 check_assignable(PLpgSQL_datum *datum, int location)
3421 {
3422 switch (datum->dtype)
3423 {
3424 case PLPGSQL_DTYPE_VAR:
3425 case PLPGSQL_DTYPE_PROMISE:
3426 case PLPGSQL_DTYPE_REC:
3427 if (((PLpgSQL_variable *) datum)->isconst)
3428 ereport(ERROR,
3429 (errcode(ERRCODE_ERROR_IN_ASSIGNMENT),
3430 errmsg("variable \"%s\" is declared CONSTANT",
3431 ((PLpgSQL_variable *) datum)->refname),
3432 parser_errposition(location)));
3433 break;
3434 case PLPGSQL_DTYPE_ROW:
3435 /* always assignable; member vars were checked at compile time */
3436 break;
3437 case PLPGSQL_DTYPE_RECFIELD:
3438 /* assignable if parent record is */
3439 check_assignable(plpgsql_Datums[((PLpgSQL_recfield *) datum)->recparentno],
3440 location);
3441 break;
3442 case PLPGSQL_DTYPE_ARRAYELEM:
3443 /* assignable if parent array is */
3444 check_assignable(plpgsql_Datums[((PLpgSQL_arrayelem *) datum)->arrayparentno],
3445 location);
3446 break;
3447 default:
3448 elog(ERROR, "unrecognized dtype: %d", datum->dtype);
3449 break;
3450 }
3451 }
3452
3453 /*
3454 * Read the argument of an INTO clause. On entry, we have just read the
3455 * INTO keyword.
3456 */
3457 static void
read_into_target(PLpgSQL_variable ** target,bool * strict)3458 read_into_target(PLpgSQL_variable **target, bool *strict)
3459 {
3460 int tok;
3461
3462 /* Set default results */
3463 *target = NULL;
3464 if (strict)
3465 *strict = false;
3466
3467 tok = yylex();
3468 if (strict && tok == K_STRICT)
3469 {
3470 *strict = true;
3471 tok = yylex();
3472 }
3473
3474 /*
3475 * Currently, a row or record variable can be the single INTO target,
3476 * but not a member of a multi-target list. So we throw error if there
3477 * is a comma after it, because that probably means the user tried to
3478 * write a multi-target list. If this ever gets generalized, we should
3479 * probably refactor read_into_scalar_list so it handles all cases.
3480 */
3481 switch (tok)
3482 {
3483 case T_DATUM:
3484 if (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
3485 yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC)
3486 {
3487 check_assignable(yylval.wdatum.datum, yylloc);
3488 *target = (PLpgSQL_variable *) yylval.wdatum.datum;
3489
3490 if ((tok = yylex()) == ',')
3491 ereport(ERROR,
3492 (errcode(ERRCODE_SYNTAX_ERROR),
3493 errmsg("record variable cannot be part of multiple-item INTO list"),
3494 parser_errposition(yylloc)));
3495 plpgsql_push_back_token(tok);
3496 }
3497 else
3498 {
3499 *target = (PLpgSQL_variable *)
3500 read_into_scalar_list(NameOfDatum(&(yylval.wdatum)),
3501 yylval.wdatum.datum, yylloc);
3502 }
3503 break;
3504
3505 default:
3506 /* just to give a better message than "syntax error" */
3507 current_token_is_not_variable(tok);
3508 }
3509 }
3510
3511 /*
3512 * Given the first datum and name in the INTO list, continue to read
3513 * comma-separated scalar variables until we run out. Then construct
3514 * and return a fake "row" variable that represents the list of
3515 * scalars.
3516 */
3517 static PLpgSQL_row *
read_into_scalar_list(char * initial_name,PLpgSQL_datum * initial_datum,int initial_location)3518 read_into_scalar_list(char *initial_name,
3519 PLpgSQL_datum *initial_datum,
3520 int initial_location)
3521 {
3522 int nfields;
3523 char *fieldnames[1024];
3524 int varnos[1024];
3525 PLpgSQL_row *row;
3526 int tok;
3527
3528 check_assignable(initial_datum, initial_location);
3529 fieldnames[0] = initial_name;
3530 varnos[0] = initial_datum->dno;
3531 nfields = 1;
3532
3533 while ((tok = yylex()) == ',')
3534 {
3535 /* Check for array overflow */
3536 if (nfields >= 1024)
3537 ereport(ERROR,
3538 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3539 errmsg("too many INTO variables specified"),
3540 parser_errposition(yylloc)));
3541
3542 tok = yylex();
3543 switch (tok)
3544 {
3545 case T_DATUM:
3546 check_assignable(yylval.wdatum.datum, yylloc);
3547 if (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
3548 yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC)
3549 ereport(ERROR,
3550 (errcode(ERRCODE_SYNTAX_ERROR),
3551 errmsg("\"%s\" is not a scalar variable",
3552 NameOfDatum(&(yylval.wdatum))),
3553 parser_errposition(yylloc)));
3554 fieldnames[nfields] = NameOfDatum(&(yylval.wdatum));
3555 varnos[nfields++] = yylval.wdatum.datum->dno;
3556 break;
3557
3558 default:
3559 /* just to give a better message than "syntax error" */
3560 current_token_is_not_variable(tok);
3561 }
3562 }
3563
3564 /*
3565 * We read an extra, non-comma token from yylex(), so push it
3566 * back onto the input stream
3567 */
3568 plpgsql_push_back_token(tok);
3569
3570 row = palloc0(sizeof(PLpgSQL_row));
3571 row->dtype = PLPGSQL_DTYPE_ROW;
3572 row->refname = "(unnamed row)";
3573 row->lineno = plpgsql_location_to_lineno(initial_location);
3574 row->rowtupdesc = NULL;
3575 row->nfields = nfields;
3576 row->fieldnames = palloc(sizeof(char *) * nfields);
3577 row->varnos = palloc(sizeof(int) * nfields);
3578 while (--nfields >= 0)
3579 {
3580 row->fieldnames[nfields] = fieldnames[nfields];
3581 row->varnos[nfields] = varnos[nfields];
3582 }
3583
3584 plpgsql_adddatum((PLpgSQL_datum *)row);
3585
3586 return row;
3587 }
3588
3589 /*
3590 * Convert a single scalar into a "row" list. This is exactly
3591 * like read_into_scalar_list except we never consume any input.
3592 *
3593 * Note: lineno could be computed from location, but since callers
3594 * have it at hand already, we may as well pass it in.
3595 */
3596 static PLpgSQL_row *
make_scalar_list1(char * initial_name,PLpgSQL_datum * initial_datum,int lineno,int location)3597 make_scalar_list1(char *initial_name,
3598 PLpgSQL_datum *initial_datum,
3599 int lineno, int location)
3600 {
3601 PLpgSQL_row *row;
3602
3603 check_assignable(initial_datum, location);
3604
3605 row = palloc0(sizeof(PLpgSQL_row));
3606 row->dtype = PLPGSQL_DTYPE_ROW;
3607 row->refname = "(unnamed row)";
3608 row->lineno = lineno;
3609 row->rowtupdesc = NULL;
3610 row->nfields = 1;
3611 row->fieldnames = palloc(sizeof(char *));
3612 row->varnos = palloc(sizeof(int));
3613 row->fieldnames[0] = initial_name;
3614 row->varnos[0] = initial_datum->dno;
3615
3616 plpgsql_adddatum((PLpgSQL_datum *)row);
3617
3618 return row;
3619 }
3620
3621 /*
3622 * When the PL/pgSQL parser expects to see a SQL statement, it is very
3623 * liberal in what it accepts; for example, we often assume an
3624 * unrecognized keyword is the beginning of a SQL statement. This
3625 * avoids the need to duplicate parts of the SQL grammar in the
3626 * PL/pgSQL grammar, but it means we can accept wildly malformed
3627 * input. To try and catch some of the more obviously invalid input,
3628 * we run the strings we expect to be SQL statements through the main
3629 * SQL parser.
3630 *
3631 * We only invoke the raw parser (not the analyzer); this doesn't do
3632 * any database access and does not check any semantic rules, it just
3633 * checks for basic syntactic correctness. We do this here, rather
3634 * than after parsing has finished, because a malformed SQL statement
3635 * may cause the PL/pgSQL parser to become confused about statement
3636 * borders. So it is best to bail out as early as we can.
3637 *
3638 * It is assumed that "stmt" represents a copy of the function source text
3639 * beginning at offset "location", with leader text of length "leaderlen"
3640 * (typically "SELECT ") prefixed to the source text. We use this assumption
3641 * to transpose any error cursor position back to the function source text.
3642 * If no error cursor is provided, we'll just point at "location".
3643 */
3644 static void
check_sql_expr(const char * stmt,int location,int leaderlen)3645 check_sql_expr(const char *stmt, int location, int leaderlen)
3646 {
3647 sql_error_callback_arg cbarg;
3648 ErrorContextCallback syntax_errcontext;
3649 MemoryContext oldCxt;
3650
3651 if (!plpgsql_check_syntax)
3652 return;
3653
3654 cbarg.location = location;
3655 cbarg.leaderlen = leaderlen;
3656
3657 syntax_errcontext.callback = plpgsql_sql_error_callback;
3658 syntax_errcontext.arg = &cbarg;
3659 syntax_errcontext.previous = error_context_stack;
3660 error_context_stack = &syntax_errcontext;
3661
3662 oldCxt = MemoryContextSwitchTo(plpgsql_compile_tmp_cxt);
3663 (void) raw_parser(stmt);
3664 MemoryContextSwitchTo(oldCxt);
3665
3666 /* Restore former ereport callback */
3667 error_context_stack = syntax_errcontext.previous;
3668 }
3669
3670 static void
plpgsql_sql_error_callback(void * arg)3671 plpgsql_sql_error_callback(void *arg)
3672 {
3673 sql_error_callback_arg *cbarg = (sql_error_callback_arg *) arg;
3674 int errpos;
3675
3676 /*
3677 * First, set up internalerrposition to point to the start of the
3678 * statement text within the function text. Note this converts
3679 * location (a byte offset) to a character number.
3680 */
3681 parser_errposition(cbarg->location);
3682
3683 /*
3684 * If the core parser provided an error position, transpose it.
3685 * Note we are dealing with 1-based character numbers at this point.
3686 */
3687 errpos = geterrposition();
3688 if (errpos > cbarg->leaderlen)
3689 {
3690 int myerrpos = getinternalerrposition();
3691
3692 if (myerrpos > 0) /* safety check */
3693 internalerrposition(myerrpos + errpos - cbarg->leaderlen - 1);
3694 }
3695
3696 /* In any case, flush errposition --- we want internalerrpos only */
3697 errposition(0);
3698 }
3699
3700 /*
3701 * Parse a SQL datatype name and produce a PLpgSQL_type structure.
3702 *
3703 * The heavy lifting is done elsewhere. Here we are only concerned
3704 * with setting up an errcontext link that will let us give an error
3705 * cursor pointing into the plpgsql function source, if necessary.
3706 * This is handled the same as in check_sql_expr(), and we likewise
3707 * expect that the given string is a copy from the source text.
3708 */
3709 static PLpgSQL_type *
parse_datatype(const char * string,int location)3710 parse_datatype(const char *string, int location)
3711 {
3712 TypeName *typeName;
3713 Oid type_id;
3714 int32 typmod;
3715 sql_error_callback_arg cbarg;
3716 ErrorContextCallback syntax_errcontext;
3717
3718 cbarg.location = location;
3719 cbarg.leaderlen = 0;
3720
3721 syntax_errcontext.callback = plpgsql_sql_error_callback;
3722 syntax_errcontext.arg = &cbarg;
3723 syntax_errcontext.previous = error_context_stack;
3724 error_context_stack = &syntax_errcontext;
3725
3726 /* Let the main parser try to parse it under standard SQL rules */
3727 typeName = typeStringToTypeName(string);
3728 typenameTypeIdAndMod(NULL, typeName, &type_id, &typmod);
3729
3730 /* Restore former ereport callback */
3731 error_context_stack = syntax_errcontext.previous;
3732
3733 /* Okay, build a PLpgSQL_type data structure for it */
3734 return plpgsql_build_datatype(type_id, typmod,
3735 plpgsql_curr_compile->fn_input_collation,
3736 typeName);
3737 }
3738
3739 /*
3740 * Check block starting and ending labels match.
3741 */
3742 static void
check_labels(const char * start_label,const char * end_label,int end_location)3743 check_labels(const char *start_label, const char *end_label, int end_location)
3744 {
3745 if (end_label)
3746 {
3747 if (!start_label)
3748 ereport(ERROR,
3749 (errcode(ERRCODE_SYNTAX_ERROR),
3750 errmsg("end label \"%s\" specified for unlabelled block",
3751 end_label),
3752 parser_errposition(end_location)));
3753
3754 if (strcmp(start_label, end_label) != 0)
3755 ereport(ERROR,
3756 (errcode(ERRCODE_SYNTAX_ERROR),
3757 errmsg("end label \"%s\" differs from block's label \"%s\"",
3758 end_label, start_label),
3759 parser_errposition(end_location)));
3760 }
3761 }
3762
3763 /*
3764 * Read the arguments (if any) for a cursor, followed by the until token
3765 *
3766 * If cursor has no args, just swallow the until token and return NULL.
3767 * If it does have args, we expect to see "( arg [, arg ...] )" followed
3768 * by the until token, where arg may be a plain expression, or a named
3769 * parameter assignment of the form argname := expr. Consume all that and
3770 * return a SELECT query that evaluates the expression(s) (without the outer
3771 * parens).
3772 */
3773 static PLpgSQL_expr *
read_cursor_args(PLpgSQL_var * cursor,int until,const char * expected)3774 read_cursor_args(PLpgSQL_var *cursor, int until, const char *expected)
3775 {
3776 PLpgSQL_expr *expr;
3777 PLpgSQL_row *row;
3778 int tok;
3779 int argc;
3780 char **argv;
3781 StringInfoData ds;
3782 char *sqlstart = "SELECT ";
3783 bool any_named = false;
3784
3785 tok = yylex();
3786 if (cursor->cursor_explicit_argrow < 0)
3787 {
3788 /* No arguments expected */
3789 if (tok == '(')
3790 ereport(ERROR,
3791 (errcode(ERRCODE_SYNTAX_ERROR),
3792 errmsg("cursor \"%s\" has no arguments",
3793 cursor->refname),
3794 parser_errposition(yylloc)));
3795
3796 if (tok != until)
3797 yyerror("syntax error");
3798
3799 return NULL;
3800 }
3801
3802 /* Else better provide arguments */
3803 if (tok != '(')
3804 ereport(ERROR,
3805 (errcode(ERRCODE_SYNTAX_ERROR),
3806 errmsg("cursor \"%s\" has arguments",
3807 cursor->refname),
3808 parser_errposition(yylloc)));
3809
3810 /*
3811 * Read the arguments, one by one.
3812 */
3813 row = (PLpgSQL_row *) plpgsql_Datums[cursor->cursor_explicit_argrow];
3814 argv = (char **) palloc0(row->nfields * sizeof(char *));
3815
3816 for (argc = 0; argc < row->nfields; argc++)
3817 {
3818 PLpgSQL_expr *item;
3819 int endtoken;
3820 int argpos;
3821 int tok1,
3822 tok2;
3823 int arglocation;
3824
3825 /* Check if it's a named parameter: "param := value" */
3826 plpgsql_peek2(&tok1, &tok2, &arglocation, NULL);
3827 if (tok1 == IDENT && tok2 == COLON_EQUALS)
3828 {
3829 char *argname;
3830 IdentifierLookup save_IdentifierLookup;
3831
3832 /* Read the argument name, ignoring any matching variable */
3833 save_IdentifierLookup = plpgsql_IdentifierLookup;
3834 plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_DECLARE;
3835 yylex();
3836 argname = yylval.str;
3837 plpgsql_IdentifierLookup = save_IdentifierLookup;
3838
3839 /* Match argument name to cursor arguments */
3840 for (argpos = 0; argpos < row->nfields; argpos++)
3841 {
3842 if (strcmp(row->fieldnames[argpos], argname) == 0)
3843 break;
3844 }
3845 if (argpos == row->nfields)
3846 ereport(ERROR,
3847 (errcode(ERRCODE_SYNTAX_ERROR),
3848 errmsg("cursor \"%s\" has no argument named \"%s\"",
3849 cursor->refname, argname),
3850 parser_errposition(yylloc)));
3851
3852 /*
3853 * Eat the ":=". We already peeked, so the error should never
3854 * happen.
3855 */
3856 tok2 = yylex();
3857 if (tok2 != COLON_EQUALS)
3858 yyerror("syntax error");
3859
3860 any_named = true;
3861 }
3862 else
3863 argpos = argc;
3864
3865 if (argv[argpos] != NULL)
3866 ereport(ERROR,
3867 (errcode(ERRCODE_SYNTAX_ERROR),
3868 errmsg("value for parameter \"%s\" of cursor \"%s\" specified more than once",
3869 row->fieldnames[argpos], cursor->refname),
3870 parser_errposition(arglocation)));
3871
3872 /*
3873 * Read the value expression. To provide the user with meaningful
3874 * parse error positions, we check the syntax immediately, instead of
3875 * checking the final expression that may have the arguments
3876 * reordered. Trailing whitespace must not be trimmed, because
3877 * otherwise input of the form (param -- comment\n, param) would be
3878 * translated into a form where the second parameter is commented
3879 * out.
3880 */
3881 item = read_sql_construct(',', ')', 0,
3882 ",\" or \")",
3883 sqlstart,
3884 true, true,
3885 false, /* do not trim */
3886 NULL, &endtoken);
3887
3888 argv[argpos] = item->query + strlen(sqlstart);
3889
3890 if (endtoken == ')' && !(argc == row->nfields - 1))
3891 ereport(ERROR,
3892 (errcode(ERRCODE_SYNTAX_ERROR),
3893 errmsg("not enough arguments for cursor \"%s\"",
3894 cursor->refname),
3895 parser_errposition(yylloc)));
3896
3897 if (endtoken == ',' && (argc == row->nfields - 1))
3898 ereport(ERROR,
3899 (errcode(ERRCODE_SYNTAX_ERROR),
3900 errmsg("too many arguments for cursor \"%s\"",
3901 cursor->refname),
3902 parser_errposition(yylloc)));
3903 }
3904
3905 /* Make positional argument list */
3906 initStringInfo(&ds);
3907 appendStringInfoString(&ds, sqlstart);
3908 for (argc = 0; argc < row->nfields; argc++)
3909 {
3910 Assert(argv[argc] != NULL);
3911
3912 /*
3913 * Because named notation allows permutated argument lists, include
3914 * the parameter name for meaningful runtime errors.
3915 */
3916 appendStringInfoString(&ds, argv[argc]);
3917 if (any_named)
3918 appendStringInfo(&ds, " AS %s",
3919 quote_identifier(row->fieldnames[argc]));
3920 if (argc < row->nfields - 1)
3921 appendStringInfoString(&ds, ", ");
3922 }
3923 appendStringInfoChar(&ds, ';');
3924
3925 expr = palloc0(sizeof(PLpgSQL_expr));
3926 expr->query = pstrdup(ds.data);
3927 expr->plan = NULL;
3928 expr->paramnos = NULL;
3929 expr->rwparam = -1;
3930 expr->ns = plpgsql_ns_top();
3931 pfree(ds.data);
3932
3933 /* Next we'd better find the until token */
3934 tok = yylex();
3935 if (tok != until)
3936 yyerror("syntax error");
3937
3938 return expr;
3939 }
3940
3941 /*
3942 * Parse RAISE ... USING options
3943 */
3944 static List *
read_raise_options(void)3945 read_raise_options(void)
3946 {
3947 List *result = NIL;
3948
3949 for (;;)
3950 {
3951 PLpgSQL_raise_option *opt;
3952 int tok;
3953
3954 if ((tok = yylex()) == 0)
3955 yyerror("unexpected end of function definition");
3956
3957 opt = (PLpgSQL_raise_option *) palloc(sizeof(PLpgSQL_raise_option));
3958
3959 if (tok_is_keyword(tok, &yylval,
3960 K_ERRCODE, "errcode"))
3961 opt->opt_type = PLPGSQL_RAISEOPTION_ERRCODE;
3962 else if (tok_is_keyword(tok, &yylval,
3963 K_MESSAGE, "message"))
3964 opt->opt_type = PLPGSQL_RAISEOPTION_MESSAGE;
3965 else if (tok_is_keyword(tok, &yylval,
3966 K_DETAIL, "detail"))
3967 opt->opt_type = PLPGSQL_RAISEOPTION_DETAIL;
3968 else if (tok_is_keyword(tok, &yylval,
3969 K_HINT, "hint"))
3970 opt->opt_type = PLPGSQL_RAISEOPTION_HINT;
3971 else if (tok_is_keyword(tok, &yylval,
3972 K_COLUMN, "column"))
3973 opt->opt_type = PLPGSQL_RAISEOPTION_COLUMN;
3974 else if (tok_is_keyword(tok, &yylval,
3975 K_CONSTRAINT, "constraint"))
3976 opt->opt_type = PLPGSQL_RAISEOPTION_CONSTRAINT;
3977 else if (tok_is_keyword(tok, &yylval,
3978 K_DATATYPE, "datatype"))
3979 opt->opt_type = PLPGSQL_RAISEOPTION_DATATYPE;
3980 else if (tok_is_keyword(tok, &yylval,
3981 K_TABLE, "table"))
3982 opt->opt_type = PLPGSQL_RAISEOPTION_TABLE;
3983 else if (tok_is_keyword(tok, &yylval,
3984 K_SCHEMA, "schema"))
3985 opt->opt_type = PLPGSQL_RAISEOPTION_SCHEMA;
3986 else
3987 yyerror("unrecognized RAISE statement option");
3988
3989 tok = yylex();
3990 if (tok != '=' && tok != COLON_EQUALS)
3991 yyerror("syntax error, expected \"=\"");
3992
3993 opt->expr = read_sql_expression2(',', ';', ", or ;", &tok);
3994
3995 result = lappend(result, opt);
3996
3997 if (tok == ';')
3998 break;
3999 }
4000
4001 return result;
4002 }
4003
4004 /*
4005 * Check that the number of parameter placeholders in the message matches the
4006 * number of parameters passed to it, if a message was given.
4007 */
4008 static void
check_raise_parameters(PLpgSQL_stmt_raise * stmt)4009 check_raise_parameters(PLpgSQL_stmt_raise *stmt)
4010 {
4011 char *cp;
4012 int expected_nparams = 0;
4013
4014 if (stmt->message == NULL)
4015 return;
4016
4017 for (cp = stmt->message; *cp; cp++)
4018 {
4019 if (cp[0] == '%')
4020 {
4021 /* ignore literal % characters */
4022 if (cp[1] == '%')
4023 cp++;
4024 else
4025 expected_nparams++;
4026 }
4027 }
4028
4029 if (expected_nparams < list_length(stmt->params))
4030 ereport(ERROR,
4031 (errcode(ERRCODE_SYNTAX_ERROR),
4032 errmsg("too many parameters specified for RAISE")));
4033 if (expected_nparams > list_length(stmt->params))
4034 ereport(ERROR,
4035 (errcode(ERRCODE_SYNTAX_ERROR),
4036 errmsg("too few parameters specified for RAISE")));
4037 }
4038
4039 /*
4040 * Fix up CASE statement
4041 */
4042 static PLpgSQL_stmt *
make_case(int location,PLpgSQL_expr * t_expr,List * case_when_list,List * else_stmts)4043 make_case(int location, PLpgSQL_expr *t_expr,
4044 List *case_when_list, List *else_stmts)
4045 {
4046 PLpgSQL_stmt_case *new;
4047
4048 new = palloc(sizeof(PLpgSQL_stmt_case));
4049 new->cmd_type = PLPGSQL_STMT_CASE;
4050 new->lineno = plpgsql_location_to_lineno(location);
4051 new->stmtid = ++plpgsql_curr_compile->nstatements;
4052 new->t_expr = t_expr;
4053 new->t_varno = 0;
4054 new->case_when_list = case_when_list;
4055 new->have_else = (else_stmts != NIL);
4056 /* Get rid of list-with-NULL hack */
4057 if (list_length(else_stmts) == 1 && linitial(else_stmts) == NULL)
4058 new->else_stmts = NIL;
4059 else
4060 new->else_stmts = else_stmts;
4061
4062 /*
4063 * When test expression is present, we create a var for it and then
4064 * convert all the WHEN expressions to "VAR IN (original_expression)".
4065 * This is a bit klugy, but okay since we haven't yet done more than
4066 * read the expressions as text. (Note that previous parsing won't
4067 * have complained if the WHEN ... THEN expression contained multiple
4068 * comma-separated values.)
4069 */
4070 if (t_expr)
4071 {
4072 char varname[32];
4073 PLpgSQL_var *t_var;
4074 ListCell *l;
4075
4076 /* use a name unlikely to collide with any user names */
4077 snprintf(varname, sizeof(varname), "__Case__Variable_%d__",
4078 plpgsql_nDatums);
4079
4080 /*
4081 * We don't yet know the result datatype of t_expr. Build the
4082 * variable as if it were INT4; we'll fix this at runtime if needed.
4083 */
4084 t_var = (PLpgSQL_var *)
4085 plpgsql_build_variable(varname, new->lineno,
4086 plpgsql_build_datatype(INT4OID,
4087 -1,
4088 InvalidOid,
4089 NULL),
4090 true);
4091 new->t_varno = t_var->dno;
4092
4093 foreach(l, case_when_list)
4094 {
4095 PLpgSQL_case_when *cwt = (PLpgSQL_case_when *) lfirst(l);
4096 PLpgSQL_expr *expr = cwt->expr;
4097 StringInfoData ds;
4098
4099 /* copy expression query without SELECT keyword (expr->query + 7) */
4100 Assert(strncmp(expr->query, "SELECT ", 7) == 0);
4101
4102 /* And do the string hacking */
4103 initStringInfo(&ds);
4104
4105 appendStringInfo(&ds, "SELECT \"%s\" IN (%s)",
4106 varname, expr->query + 7);
4107
4108 pfree(expr->query);
4109 expr->query = pstrdup(ds.data);
4110 /* Adjust expr's namespace to include the case variable */
4111 expr->ns = plpgsql_ns_top();
4112
4113 pfree(ds.data);
4114 }
4115 }
4116
4117 return (PLpgSQL_stmt *) new;
4118 }
4119