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