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