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