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