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