2 /*-------------------------------------------------------------------------
4 * gram.y - Parser for the PL/pgSQL
7 * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
12 * $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.88 2006/03/23 04:22:36 tgl Exp $
14 *-------------------------------------------------------------------------
19 #include "parser/parser.h"
21 static PLpgSQL_expr *read_sql_construct(int until,
28 static PLpgSQL_expr *read_sql_stmt(const char *sqlstart);
29 static PLpgSQL_type *read_datatype(int tok);
30 static PLpgSQL_stmt *make_select_stmt(void);
31 static PLpgSQL_stmt *make_fetch_stmt(void);
32 static void check_assignable(PLpgSQL_datum *datum);
33 static PLpgSQL_row *read_into_scalar_list(const char *initial_name,
34 PLpgSQL_datum *initial_datum);
35 static PLpgSQL_row *make_scalar_list1(const char *initial_name,
36 PLpgSQL_datum *initial_datum,
38 static void check_sql_expr(const char *stmt);
39 static void plpgsql_sql_error_callback(void *arg);
40 static void check_labels(const char *start_label,
41 const char *end_label);
45 %name-prefix="plpgsql_yy"
60 PLpgSQL_datum *scalar;
77 PLpgSQL_datum *scalar; /* a VAR, RECFIELD, or TRIGARG */
78 PLpgSQL_variable *variable; /* a VAR, REC, or ROW */
84 PLpgSQL_stmt_block *program;
85 PLpgSQL_condition *condition;
86 PLpgSQL_exception *exception;
87 PLpgSQL_exception_block *exception_block;
88 PLpgSQL_nsitem *nsitem;
89 PLpgSQL_diag_item *diagitem;
92 %type <declhdr> decl_sect
93 %type <varname> decl_varname
94 %type <str> decl_renname
95 %type <boolean> decl_const decl_notnull exit_type
96 %type <expr> decl_defval decl_cursor_query
97 %type <dtype> decl_datatype
98 %type <row> decl_cursor_args
99 %type <list> decl_cursor_arglist
100 %type <nsitem> decl_aliasitem
101 %type <str> decl_stmts decl_stmt
103 %type <expr> expr_until_semi expr_until_rightbracket
104 %type <expr> expr_until_then expr_until_loop
105 %type <expr> opt_exitcond
107 %type <ival> assign_var cursor_variable
108 %type <var> cursor_varptr
109 %type <variable> decl_cursor_arg
110 %type <forvariable> for_variable
111 %type <stmt> for_control
113 %type <str> opt_lblname opt_block_label opt_label
114 %type <str> execsql_start
116 %type <list> proc_sect proc_stmts stmt_else
117 %type <loop_body> loop_body
118 %type <stmt> proc_stmt pl_block
119 %type <stmt> stmt_assign stmt_if stmt_loop stmt_while stmt_exit
120 %type <stmt> stmt_return stmt_return_next stmt_raise stmt_execsql
121 %type <stmt> stmt_for stmt_select stmt_perform
122 %type <stmt> stmt_dynexecute stmt_getdiag
123 %type <stmt> stmt_open stmt_fetch stmt_close stmt_null
125 %type <list> proc_exceptions
126 %type <exception_block> exception_sect
127 %type <exception> proc_exception
128 %type <condition> proc_conditions
131 %type <ival> raise_level
132 %type <str> raise_msg
134 %type <list> getdiag_list
135 %type <diagitem> getdiag_list_item
136 %type <ival> getdiag_kind getdiag_target
201 %token T_SCALAR /* a VAR, RECFIELD, or TRIGARG */
214 pl_function : T_FUNCTION comp_optsect pl_block opt_semi
216 yylval.program = (PLpgSQL_stmt_block *)$3;
218 | T_TRIGGER comp_optsect pl_block opt_semi
220 yylval.program = (PLpgSQL_stmt_block *)$3;
228 comp_options : comp_options comp_option
232 comp_option : O_OPTION O_DUMP
234 plpgsql_DumpExecTree = true;
242 pl_block : decl_sect K_BEGIN lno proc_sect exception_sect K_END opt_label
244 PLpgSQL_stmt_block *new;
246 new = palloc0(sizeof(PLpgSQL_stmt_block));
248 new->cmd_type = PLPGSQL_STMT_BLOCK;
250 new->label = $1.label;
251 new->n_initvars = $1.n_initvars;
252 new->initvarnos = $1.initvarnos;
254 new->exceptions = $5;
256 check_labels($1.label, $7);
259 $$ = (PLpgSQL_stmt *)new;
264 decl_sect : opt_block_label
266 plpgsql_ns_setlocal(false);
269 $$.initvarnos = NULL;
270 plpgsql_add_initdatums(NULL);
272 | opt_block_label decl_start
274 plpgsql_ns_setlocal(false);
277 $$.initvarnos = NULL;
278 plpgsql_add_initdatums(NULL);
280 | opt_block_label decl_start decl_stmts
282 plpgsql_ns_setlocal(false);
287 $$.n_initvars = plpgsql_add_initdatums(&($$.initvarnos));
291 decl_start : K_DECLARE
293 plpgsql_ns_setlocal(true);
297 decl_stmts : decl_stmts decl_stmt
303 decl_stmt : '<' '<' opt_lblname '>' '>'
311 decl_statement : decl_varname decl_const decl_datatype decl_notnull decl_defval
313 PLpgSQL_variable *var;
315 var = plpgsql_build_variable($1.name, $1.lineno,
319 if (var->dtype == PLPGSQL_DTYPE_VAR)
320 ((PLpgSQL_var *) var)->isconst = $2;
323 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
324 errmsg("row or record variable cannot be CONSTANT")));
328 if (var->dtype == PLPGSQL_DTYPE_VAR)
329 ((PLpgSQL_var *) var)->notnull = $4;
332 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
333 errmsg("row or record variable cannot be NOT NULL")));
337 if (var->dtype == PLPGSQL_DTYPE_VAR)
338 ((PLpgSQL_var *) var)->default_val = $5;
341 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
342 errmsg("default value for row or record variable is not supported")));
345 | decl_varname K_ALIAS K_FOR decl_aliasitem ';'
347 plpgsql_ns_additem($4->itemtype,
348 $4->itemno, $1.name);
350 | K_RENAME decl_renname K_TO decl_renname ';'
352 plpgsql_ns_rename($2, $4);
354 | decl_varname K_CURSOR
355 { plpgsql_ns_push(NULL); }
356 decl_cursor_args decl_is_from decl_cursor_query
359 PLpgSQL_expr *curname_def;
364 /* pop local namespace for cursor args */
367 new = (PLpgSQL_var *)
368 plpgsql_build_variable($1.name, $1.lineno,
369 plpgsql_build_datatype(REFCURSOROID,
373 curname_def = palloc0(sizeof(PLpgSQL_expr));
375 curname_def->dtype = PLPGSQL_DTYPE_EXPR;
376 strcpy(buf, "SELECT ");
378 cp2 = buf + strlen(buf);
379 if (strchr(cp1, '\\') != NULL)
380 *cp2++ = ESCAPE_STRING_SYNTAX;
384 if (SQL_STR_DOUBLE(*cp1))
388 strcpy(cp2, "'::refcursor");
389 curname_def->query = pstrdup(buf);
390 new->default_val = curname_def;
392 new->cursor_explicit_expr = $6;
394 new->cursor_explicit_argrow = -1;
396 new->cursor_explicit_argrow = $4->rowno;
404 plpgsql_ns_setlocal(false);
405 query = read_sql_stmt("");
406 plpgsql_ns_setlocal(true);
416 | '(' decl_cursor_arglist ')'
422 new = palloc0(sizeof(PLpgSQL_row));
423 new->dtype = PLPGSQL_DTYPE_ROW;
424 new->lineno = plpgsql_scanner_lineno();
425 new->rowtupdesc = NULL;
426 new->nfields = list_length($2);
427 new->fieldnames = palloc(new->nfields * sizeof(char *));
428 new->varnos = palloc(new->nfields * sizeof(int));
433 PLpgSQL_variable *arg = (PLpgSQL_variable *) lfirst(l);
434 new->fieldnames[i] = arg->refname;
435 new->varnos[i] = arg->dno;
440 plpgsql_adddatum((PLpgSQL_datum *) new);
445 decl_cursor_arglist : decl_cursor_arg
449 | decl_cursor_arglist ',' decl_cursor_arg
451 $$ = lappend($1, $3);
455 decl_cursor_arg : decl_varname decl_datatype
457 $$ = plpgsql_build_variable($1.name, $1.lineno,
462 decl_is_from : K_IS | /* Oracle */
465 decl_aliasitem : T_WORD
470 plpgsql_convert_ident(yytext, &name, 1);
472 yyerror("only positional parameters may be aliased");
474 plpgsql_ns_setlocal(false);
475 nsi = plpgsql_ns_lookup(name, NULL);
478 plpgsql_error_lineno = plpgsql_scanner_lineno();
480 (errcode(ERRCODE_UNDEFINED_PARAMETER),
481 errmsg("function has no parameter \"%s\"",
485 plpgsql_ns_setlocal(true);
493 decl_varname : T_WORD
497 plpgsql_convert_ident(yytext, &name, 1);
499 $$.lineno = plpgsql_scanner_lineno();
503 decl_renname : T_WORD
507 plpgsql_convert_ident(yytext, &name, 1);
508 /* the result must be palloc'd, see plpgsql_ns_rename */
522 * If there's a lookahead token, read_datatype
525 $$ = read_datatype(yychar);
540 plpgsql_ns_setlocal(false);
541 $$ = plpgsql_read_expression(';', ";");
542 plpgsql_ns_setlocal(true);
546 decl_defkey : K_ASSIGN
558 proc_stmts : proc_stmts proc_stmt
563 $$ = lappend($1, $2);
574 proc_stmt : pl_block ';'
614 stmt_perform : K_PERFORM lno expr_until_semi
616 PLpgSQL_stmt_perform *new;
618 new = palloc0(sizeof(PLpgSQL_stmt_perform));
619 new->cmd_type = PLPGSQL_STMT_PERFORM;
623 $$ = (PLpgSQL_stmt *)new;
627 stmt_assign : assign_var lno K_ASSIGN expr_until_semi
629 PLpgSQL_stmt_assign *new;
631 new = palloc0(sizeof(PLpgSQL_stmt_assign));
632 new->cmd_type = PLPGSQL_STMT_ASSIGN;
637 $$ = (PLpgSQL_stmt *)new;
641 stmt_getdiag : K_GET K_DIAGNOSTICS lno getdiag_list ';'
643 PLpgSQL_stmt_getdiag *new;
645 new = palloc0(sizeof(PLpgSQL_stmt_getdiag));
646 new->cmd_type = PLPGSQL_STMT_GETDIAG;
648 new->diag_items = $4;
650 $$ = (PLpgSQL_stmt *)new;
654 getdiag_list : getdiag_list ',' getdiag_list_item
656 $$ = lappend($1, $3);
664 getdiag_list_item : getdiag_target K_ASSIGN getdiag_kind
666 PLpgSQL_diag_item *new;
668 new = palloc(sizeof(PLpgSQL_diag_item));
676 getdiag_kind : K_ROW_COUNT
678 $$ = PLPGSQL_GETDIAG_ROW_COUNT;
682 $$ = PLPGSQL_GETDIAG_RESULT_OID;
686 getdiag_target : T_SCALAR
688 check_assignable(yylval.scalar);
689 $$ = yylval.scalar->dno;
694 assign_var : T_SCALAR
696 check_assignable(yylval.scalar);
697 $$ = yylval.scalar->dno;
701 check_assignable((PLpgSQL_datum *) yylval.row);
702 $$ = yylval.row->rowno;
706 check_assignable((PLpgSQL_datum *) yylval.rec);
707 $$ = yylval.rec->recno;
709 | assign_var '[' expr_until_rightbracket
711 PLpgSQL_arrayelem *new;
713 new = palloc0(sizeof(PLpgSQL_arrayelem));
714 new->dtype = PLPGSQL_DTYPE_ARRAYELEM;
716 new->arrayparentno = $1;
718 plpgsql_adddatum((PLpgSQL_datum *)new);
724 stmt_if : K_IF lno expr_until_then proc_sect stmt_else K_END K_IF ';'
726 PLpgSQL_stmt_if *new;
728 new = palloc0(sizeof(PLpgSQL_stmt_if));
729 new->cmd_type = PLPGSQL_STMT_IF;
733 new->false_body = $5;
735 $$ = (PLpgSQL_stmt *)new;
743 | K_ELSIF lno expr_until_then proc_sect stmt_else
746 * Translate the structure: into:
748 * IF c1 THEN IF c1 THEN
758 PLpgSQL_stmt_if *new_if;
760 /* first create a new if-statement */
761 new_if = palloc0(sizeof(PLpgSQL_stmt_if));
762 new_if->cmd_type = PLPGSQL_STMT_IF;
765 new_if->true_body = $4;
766 new_if->false_body = $5;
768 /* wrap the if-statement in a "container" list */
769 $$ = list_make1(new_if);
778 stmt_loop : opt_block_label K_LOOP lno loop_body
780 PLpgSQL_stmt_loop *new;
782 new = palloc0(sizeof(PLpgSQL_stmt_loop));
783 new->cmd_type = PLPGSQL_STMT_LOOP;
786 new->body = $4.stmts;
788 check_labels($1, $4.end_label);
791 $$ = (PLpgSQL_stmt *)new;
795 stmt_while : opt_block_label K_WHILE lno expr_until_loop loop_body
797 PLpgSQL_stmt_while *new;
799 new = palloc0(sizeof(PLpgSQL_stmt_while));
800 new->cmd_type = PLPGSQL_STMT_WHILE;
804 new->body = $5.stmts;
806 check_labels($1, $5.end_label);
809 $$ = (PLpgSQL_stmt *)new;
813 stmt_for : opt_block_label K_FOR for_control loop_body
815 /* This runs after we've scanned the loop body */
816 if ($3->cmd_type == PLPGSQL_STMT_FORI)
818 PLpgSQL_stmt_fori *new;
820 new = (PLpgSQL_stmt_fori *) $3;
822 new->body = $4.stmts;
823 $$ = (PLpgSQL_stmt *) new;
825 else if ($3->cmd_type == PLPGSQL_STMT_FORS)
827 PLpgSQL_stmt_fors *new;
829 new = (PLpgSQL_stmt_fors *) $3;
831 new->body = $4.stmts;
832 $$ = (PLpgSQL_stmt *) new;
836 PLpgSQL_stmt_dynfors *new;
838 Assert($3->cmd_type == PLPGSQL_STMT_DYNFORS);
839 new = (PLpgSQL_stmt_dynfors *) $3;
841 new->body = $4.stmts;
842 $$ = (PLpgSQL_stmt *) new;
845 check_labels($1, $4.end_label);
846 /* close namespace started in opt_label */
852 lno for_variable K_IN
856 /* Simple case: EXECUTE is a dynamic FOR loop */
857 if (tok == K_EXECUTE)
859 PLpgSQL_stmt_dynfors *new;
862 expr = plpgsql_read_expression(K_LOOP, "LOOP");
864 new = palloc0(sizeof(PLpgSQL_stmt_dynfors));
865 new->cmd_type = PLPGSQL_STMT_DYNFORS;
870 check_assignable((PLpgSQL_datum *) new->rec);
875 check_assignable((PLpgSQL_datum *) new->row);
879 /* convert single scalar to list */
880 new->row = make_scalar_list1($2.name, $2.scalar, $2.lineno);
881 /* no need for check_assignable */
885 plpgsql_error_lineno = $2.lineno;
886 yyerror("loop variable of loop over rows must be a record or row variable or list of scalar variables");
890 $$ = (PLpgSQL_stmt *) new;
895 bool reverse = false;
898 * We have to distinguish between two
899 * alternatives: FOR var IN a .. b and FOR
900 * var IN query. Unfortunately this is
901 * tricky, since the query in the second
902 * form needn't start with a SELECT
903 * keyword. We use the ugly hack of
904 * looking for two periods after the first
905 * token. We also check for the REVERSE
906 * keyword, which means it must be an
909 if (tok == K_REVERSE)
912 plpgsql_push_back_token(tok);
915 * Read tokens until we see either a ".."
916 * or a LOOP. The text we read may not
917 * necessarily be a well-formed SQL
918 * statement, so we need to invoke
919 * read_sql_construct directly.
921 expr1 = read_sql_construct(K_DOTDOT,
931 /* Saw "..", so it must be an integer loop */
934 PLpgSQL_stmt_fori *new;
937 /* First expression is well-formed */
938 check_sql_expr(expr1->query);
940 expr2 = plpgsql_read_expression(K_LOOP, "LOOP");
942 /* should have had a single variable name */
943 plpgsql_error_lineno = $2.lineno;
944 if ($2.scalar && $2.row)
946 (errcode(ERRCODE_SYNTAX_ERROR),
947 errmsg("integer FOR loop must have just one target variable")));
949 /* create loop's private variable */
950 plpgsql_convert_ident($2.name, &varname, 1);
951 fvar = (PLpgSQL_var *)
952 plpgsql_build_variable(varname,
954 plpgsql_build_datatype(INT4OID,
958 /* put the for-variable into the local block */
959 plpgsql_add_initdatums(NULL);
961 new = palloc0(sizeof(PLpgSQL_stmt_fori));
962 new->cmd_type = PLPGSQL_STMT_FORI;
965 new->reverse = reverse;
969 $$ = (PLpgSQL_stmt *) new;
974 * No "..", so it must be a query loop. We've prefixed an
975 * extra SELECT to the query text, so we need to remove that
976 * before performing syntax checking.
979 PLpgSQL_stmt_fors *new;
982 yyerror("cannot specify REVERSE in query FOR loop");
984 Assert(strncmp(expr1->query, "SELECT ", 7) == 0);
985 tmp_query = pstrdup(expr1->query + 7);
987 expr1->query = tmp_query;
989 check_sql_expr(expr1->query);
991 new = palloc0(sizeof(PLpgSQL_stmt_fors));
992 new->cmd_type = PLPGSQL_STMT_FORS;
997 check_assignable((PLpgSQL_datum *) new->rec);
1002 check_assignable((PLpgSQL_datum *) new->row);
1006 /* convert single scalar to list */
1007 new->row = make_scalar_list1($2.name, $2.scalar, $2.lineno);
1008 /* no need for check_assignable */
1012 plpgsql_error_lineno = $2.lineno;
1013 yyerror("loop variable of loop over rows must be a record or row variable or list of scalar variables");
1017 $$ = (PLpgSQL_stmt *) new;
1024 * Processing the for_variable is tricky because we don't yet know if the
1025 * FOR is an integer FOR loop or a loop over query results. In the former
1026 * case, the variable is just a name that we must instantiate as a loop
1027 * local variable, regardless of any other definition it might have.
1028 * Therefore, we always save the actual identifier into $$.name where it
1029 * can be used for that case. We also save the outer-variable definition,
1030 * if any, because that's what we need for the loop-over-query case. Note
1031 * that we must NOT apply check_assignable() or any other semantic check
1032 * until we know what's what.
1034 * However, if we see a comma-separated list of names, we know that it
1035 * can't be an integer FOR loop and so it's OK to check the variables
1036 * immediately. In particular, for T_WORD followed by comma, we should
1037 * complain that the name is not known rather than say it's a syntax error.
1038 * Note that the non-error result of this case sets *both* $$.scalar and
1039 * $$.row; see the for_control production.
1041 for_variable : T_SCALAR
1045 $$.name = pstrdup(yytext);
1046 $$.lineno = plpgsql_scanner_lineno();
1047 $$.scalar = yylval.scalar;
1050 /* check for comma-separated list */
1052 plpgsql_push_back_token(tok);
1054 $$.row = read_into_scalar_list($$.name, $$.scalar);
1060 $$.name = pstrdup(yytext);
1061 $$.lineno = plpgsql_scanner_lineno();
1065 /* check for comma-separated list */
1067 plpgsql_push_back_token(tok);
1070 plpgsql_error_lineno = $$.lineno;
1072 (errcode(ERRCODE_SYNTAX_ERROR),
1073 errmsg("\"%s\" is not a scalar variable",
1079 $$.name = pstrdup(yytext);
1080 $$.lineno = plpgsql_scanner_lineno();
1082 $$.rec = yylval.rec;
1087 $$.name = pstrdup(yytext);
1088 $$.lineno = plpgsql_scanner_lineno();
1090 $$.row = yylval.row;
1095 stmt_select : K_SELECT lno
1097 $$ = make_select_stmt();
1102 stmt_exit : exit_type lno opt_label opt_exitcond
1104 PLpgSQL_stmt_exit *new;
1106 new = palloc0(sizeof(PLpgSQL_stmt_exit));
1107 new->cmd_type = PLPGSQL_STMT_EXIT;
1113 $$ = (PLpgSQL_stmt *)new;
1127 stmt_return : K_RETURN lno
1129 PLpgSQL_stmt_return *new;
1131 new = palloc0(sizeof(PLpgSQL_stmt_return));
1132 new->cmd_type = PLPGSQL_STMT_RETURN;
1137 if (plpgsql_curr_compile->fn_retset)
1140 yyerror("RETURN cannot have a parameter in function returning set; use RETURN NEXT");
1142 else if (plpgsql_curr_compile->out_param_varno >= 0)
1145 yyerror("RETURN cannot have a parameter in function with OUT parameters");
1146 new->retvarno = plpgsql_curr_compile->out_param_varno;
1148 else if (plpgsql_curr_compile->fn_rettype == VOIDOID)
1151 yyerror("RETURN cannot have a parameter in function returning void");
1153 else if (plpgsql_curr_compile->fn_retistuple)
1158 /* we allow this to support RETURN NULL in triggers */
1162 new->retvarno = yylval.row->rowno;
1166 new->retvarno = yylval.rec->recno;
1170 yyerror("RETURN must specify a record or row variable in function returning tuple");
1174 yyerror("RETURN must specify a record or row variable in function returning tuple");
1179 * Note that a well-formed expression is
1180 * _required_ here; anything else is a
1181 * compile-time error.
1183 new->expr = plpgsql_read_expression(';', ";");
1186 $$ = (PLpgSQL_stmt *)new;
1190 stmt_return_next: K_RETURN_NEXT lno
1192 PLpgSQL_stmt_return_next *new;
1194 if (!plpgsql_curr_compile->fn_retset)
1195 yyerror("cannot use RETURN NEXT in a non-SETOF function");
1197 new = palloc0(sizeof(PLpgSQL_stmt_return_next));
1198 new->cmd_type = PLPGSQL_STMT_RETURN_NEXT;
1203 if (plpgsql_curr_compile->out_param_varno >= 0)
1206 yyerror("RETURN NEXT cannot have a parameter in function with OUT parameters");
1207 new->retvarno = plpgsql_curr_compile->out_param_varno;
1209 else if (plpgsql_curr_compile->fn_retistuple)
1214 new->retvarno = yylval.row->rowno;
1218 new->retvarno = yylval.rec->recno;
1222 yyerror("RETURN NEXT must specify a record or row variable in function returning tuple");
1226 yyerror("RETURN NEXT must specify a record or row variable in function returning tuple");
1229 new->expr = plpgsql_read_expression(';', ";");
1231 $$ = (PLpgSQL_stmt *)new;
1235 stmt_raise : K_RAISE lno raise_level raise_msg
1237 PLpgSQL_stmt_raise *new;
1240 new = palloc(sizeof(PLpgSQL_stmt_raise));
1242 new->cmd_type = PLPGSQL_STMT_RAISE;
1244 new->elog_level = $3;
1251 * We expect either a semi-colon, which
1252 * indicates no parameters, or a comma that
1253 * begins the list of parameter expressions
1255 if (tok != ',' && tok != ';')
1256 yyerror("syntax error");
1265 expr = read_sql_construct(',', ';', ", or ;",
1268 new->params = lappend(new->params, expr);
1274 $$ = (PLpgSQL_stmt *)new;
1278 raise_msg : T_STRING
1280 $$ = plpgsql_get_string_value();
1284 raise_level : K_EXCEPTION
1310 loop_body : proc_sect K_END K_LOOP opt_label ';'
1317 stmt_execsql : execsql_start lno
1319 PLpgSQL_stmt_execsql *new;
1321 new = palloc(sizeof(PLpgSQL_stmt_execsql));
1322 new->cmd_type = PLPGSQL_STMT_EXECSQL;
1324 new->sqlstmt = read_sql_stmt($1);
1326 $$ = (PLpgSQL_stmt *)new;
1330 stmt_dynexecute : K_EXECUTE lno
1332 PLpgSQL_stmt_dynexecute *new;
1336 expr = read_sql_construct(K_INTO, ';', "INTO|;", "SELECT ",
1337 true, true, &endtoken);
1339 new = palloc(sizeof(PLpgSQL_stmt_dynexecute));
1340 new->cmd_type = PLPGSQL_STMT_DYNEXECUTE;
1347 * If we saw "INTO", look for a following row
1348 * var, record var, or list of scalars.
1350 if (endtoken == K_INTO)
1355 new->row = yylval.row;
1356 check_assignable((PLpgSQL_datum *) new->row);
1360 new->rec = yylval.rec;
1361 check_assignable((PLpgSQL_datum *) new->rec);
1365 new->row = read_into_scalar_list(yytext, yylval.scalar);
1369 plpgsql_error_lineno = $2;
1371 (errcode(ERRCODE_SYNTAX_ERROR),
1372 errmsg("syntax error at \"%s\"", yytext),
1373 errdetail("Expected record variable, row variable, "
1374 "or list of scalar variables.")));
1377 yyerror("syntax error");
1380 $$ = (PLpgSQL_stmt *)new;
1385 stmt_open : K_OPEN lno cursor_varptr
1387 PLpgSQL_stmt_open *new;
1390 new = palloc0(sizeof(PLpgSQL_stmt_open));
1391 new->cmd_type = PLPGSQL_STMT_OPEN;
1393 new->curvar = $3->varno;
1395 if ($3->cursor_explicit_expr == NULL)
1400 plpgsql_error_lineno = $2;
1402 (errcode(ERRCODE_SYNTAX_ERROR),
1403 errmsg("syntax error at \"%s\"",
1405 errdetail("Expected FOR to open a reference cursor.")));
1409 if (tok == K_EXECUTE)
1411 new->dynquery = read_sql_stmt("SELECT ");
1415 plpgsql_push_back_token(tok);
1416 new->query = read_sql_stmt("");
1421 if ($3->cursor_explicit_argrow >= 0)
1428 plpgsql_error_lineno = plpgsql_scanner_lineno();
1430 (errcode(ERRCODE_SYNTAX_ERROR),
1431 errmsg("cursor \"%s\" has arguments",
1436 * Push back the '(', else read_sql_stmt
1437 * will complain about unbalanced parens.
1439 plpgsql_push_back_token(tok);
1441 new->argquery = read_sql_stmt("SELECT ");
1444 * Now remove the leading and trailing parens,
1445 * because we want "select 1, 2", not
1448 cp = new->argquery->query;
1450 if (strncmp(cp, "SELECT", 6) != 0)
1452 plpgsql_error_lineno = plpgsql_scanner_lineno();
1453 /* internal error */
1454 elog(ERROR, "expected \"SELECT (\", got \"%s\"",
1455 new->argquery->query);
1458 while (*cp == ' ') /* could be more than 1 space here */
1462 plpgsql_error_lineno = plpgsql_scanner_lineno();
1463 /* internal error */
1464 elog(ERROR, "expected \"SELECT (\", got \"%s\"",
1465 new->argquery->query);
1469 cp += strlen(cp) - 1;
1472 yyerror("expected \")\"");
1480 plpgsql_error_lineno = plpgsql_scanner_lineno();
1482 (errcode(ERRCODE_SYNTAX_ERROR),
1483 errmsg("cursor \"%s\" has no arguments",
1489 plpgsql_error_lineno = plpgsql_scanner_lineno();
1491 (errcode(ERRCODE_SYNTAX_ERROR),
1492 errmsg("syntax error at \"%s\"",
1498 $$ = (PLpgSQL_stmt *)new;
1502 stmt_fetch : K_FETCH lno cursor_variable K_INTO
1504 PLpgSQL_stmt_fetch *new;
1506 new = (PLpgSQL_stmt_fetch *)make_fetch_stmt();
1509 $$ = (PLpgSQL_stmt *)new;
1514 stmt_close : K_CLOSE lno cursor_variable ';'
1516 PLpgSQL_stmt_close *new;
1518 new = palloc(sizeof(PLpgSQL_stmt_close));
1519 new->cmd_type = PLPGSQL_STMT_CLOSE;
1523 $$ = (PLpgSQL_stmt *)new;
1527 stmt_null : K_NULL ';'
1529 /* We do not bother building a node for NULL */
1534 cursor_varptr : T_SCALAR
1536 if (yylval.scalar->dtype != PLPGSQL_DTYPE_VAR)
1537 yyerror("cursor variable must be a simple variable");
1539 if (((PLpgSQL_var *) yylval.scalar)->datatype->typoid != REFCURSOROID)
1541 plpgsql_error_lineno = plpgsql_scanner_lineno();
1543 (errcode(ERRCODE_DATATYPE_MISMATCH),
1544 errmsg("\"%s\" must be of type cursor or refcursor",
1545 ((PLpgSQL_var *) yylval.scalar)->refname)));
1547 $$ = (PLpgSQL_var *) yylval.scalar;
1551 cursor_variable : T_SCALAR
1553 if (yylval.scalar->dtype != PLPGSQL_DTYPE_VAR)
1554 yyerror("cursor variable must be a simple variable");
1556 if (((PLpgSQL_var *) yylval.scalar)->datatype->typoid != REFCURSOROID)
1558 plpgsql_error_lineno = plpgsql_scanner_lineno();
1560 (errcode(ERRCODE_DATATYPE_MISMATCH),
1561 errmsg("\"%s\" must be of type refcursor",
1562 ((PLpgSQL_var *) yylval.scalar)->refname)));
1564 $$ = yylval.scalar->dno;
1568 execsql_start : T_WORD
1569 { $$ = pstrdup(yytext); }
1571 { $$ = pstrdup(yytext); }
1579 * We use a mid-rule action to add these
1580 * special variables to the namespace before
1581 * parsing the WHEN clauses themselves.
1583 PLpgSQL_exception_block *new = palloc(sizeof(PLpgSQL_exception_block));
1584 PLpgSQL_variable *var;
1586 var = plpgsql_build_variable("sqlstate", $2,
1587 plpgsql_build_datatype(TEXTOID, -1),
1589 ((PLpgSQL_var *) var)->isconst = true;
1590 new->sqlstate_varno = var->dno;
1592 var = plpgsql_build_variable("sqlerrm", $2,
1593 plpgsql_build_datatype(TEXTOID, -1),
1595 ((PLpgSQL_var *) var)->isconst = true;
1596 new->sqlerrm_varno = var->dno;
1598 $<exception_block>$ = new;
1602 PLpgSQL_exception_block *new = $<exception_block>3;
1609 proc_exceptions : proc_exceptions proc_exception
1611 $$ = lappend($1, $2);
1615 $$ = list_make1($1);
1619 proc_exception : K_WHEN lno proc_conditions K_THEN proc_sect
1621 PLpgSQL_exception *new;
1623 new = palloc0(sizeof(PLpgSQL_exception));
1625 new->conditions = $3;
1632 proc_conditions : proc_conditions K_OR opt_lblname
1634 PLpgSQL_condition *old;
1636 for (old = $1; old->next != NULL; old = old->next)
1638 old->next = plpgsql_parse_err_condition($3);
1644 $$ = plpgsql_parse_err_condition($1);
1649 { $$ = plpgsql_read_expression(';', ";"); }
1652 expr_until_rightbracket :
1653 { $$ = plpgsql_read_expression(']', "]"); }
1657 { $$ = plpgsql_read_expression(K_THEN, "THEN"); }
1661 { $$ = plpgsql_read_expression(K_LOOP, "LOOP"); }
1666 plpgsql_ns_push(NULL);
1669 | '<' '<' opt_lblname '>' '>'
1671 plpgsql_ns_push($3);
1683 plpgsql_convert_ident(yytext, &label_name, 1);
1688 /* just to give a better error than "syntax error" */
1689 yyerror("no such label");
1695 | K_WHEN expr_until_semi
1699 opt_lblname : T_WORD
1703 plpgsql_convert_ident(yytext, &name, 1);
1710 $$ = plpgsql_error_lineno = plpgsql_scanner_lineno();
1717 #define MAX_EXPR_PARAMS 1024
1720 * determine the expression parameter position to use for a plpgsql datum
1722 * It is important that any given plpgsql datum map to just one parameter.
1723 * We used to be sloppy and assign a separate parameter for each occurrence
1724 * of a datum reference, but that fails for situations such as "select DATUM
1725 * from ... group by DATUM".
1727 * The params[] array must be of size MAX_EXPR_PARAMS.
1730 assign_expr_param(int dno, int *params, int *nparams)
1734 /* already have an instance of this dno? */
1735 for (i = 0; i < *nparams; i++)
1737 if (params[i] == dno)
1740 /* check for array overflow */
1741 if (*nparams >= MAX_EXPR_PARAMS)
1743 plpgsql_error_lineno = plpgsql_scanner_lineno();
1745 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1746 errmsg("too many variables specified in SQL statement")));
1748 /* add new parameter dno to array */
1749 params[*nparams] = dno;
1756 plpgsql_read_expression(int until, const char *expected)
1758 return read_sql_construct(until, 0, expected, "SELECT ", true, true, NULL);
1761 static PLpgSQL_expr *
1762 read_sql_stmt(const char *sqlstart)
1764 return read_sql_construct(';', 0, ";", sqlstart, false, true, NULL);
1768 * Read a SQL construct and build a PLpgSQL_expr for it.
1770 * until: token code for expected terminator
1771 * until2: token code for alternate terminator (pass 0 if none)
1772 * expected: text to use in complaining that terminator was not found
1773 * sqlstart: text to prefix to the accumulated SQL text
1774 * isexpression: whether to say we're reading an "expression" or a "statement"
1775 * valid_sql: whether to check the syntax of the expr (prefixed with sqlstart)
1776 * endtoken: if not NULL, ending token is stored at *endtoken
1777 * (this is only interesting if until2 isn't zero)
1779 static PLpgSQL_expr *
1780 read_sql_construct(int until,
1782 const char *expected,
1783 const char *sqlstart,
1793 int params[MAX_EXPR_PARAMS];
1797 lno = plpgsql_scanner_lineno();
1798 plpgsql_dstring_init(&ds);
1799 plpgsql_dstring_append(&ds, sqlstart);
1804 if (tok == until && parenlevel == 0)
1806 if (tok == until2 && parenlevel == 0)
1808 if (tok == '(' || tok == '[')
1810 else if (tok == ')' || tok == ']')
1815 (errcode(ERRCODE_SYNTAX_ERROR),
1816 errmsg("mismatched parentheses")));
1819 * End of function definition is an error, and we don't expect to
1820 * hit a semicolon either (unless it's the until symbol, in which
1821 * case we should have fallen out above).
1823 if (tok == 0 || tok == ';')
1825 plpgsql_error_lineno = lno;
1826 if (parenlevel != 0)
1828 (errcode(ERRCODE_SYNTAX_ERROR),
1829 errmsg("mismatched parentheses")));
1832 (errcode(ERRCODE_SYNTAX_ERROR),
1833 errmsg("missing \"%s\" at end of SQL expression",
1837 (errcode(ERRCODE_SYNTAX_ERROR),
1838 errmsg("missing \"%s\" at end of SQL statement",
1842 if (plpgsql_SpaceScanned)
1843 plpgsql_dstring_append(&ds, " ");
1848 snprintf(buf, sizeof(buf), " $%d ",
1849 assign_expr_param(yylval.scalar->dno,
1851 plpgsql_dstring_append(&ds, buf);
1855 snprintf(buf, sizeof(buf), " $%d ",
1856 assign_expr_param(yylval.row->rowno,
1858 plpgsql_dstring_append(&ds, buf);
1862 snprintf(buf, sizeof(buf), " $%d ",
1863 assign_expr_param(yylval.rec->recno,
1865 plpgsql_dstring_append(&ds, buf);
1869 plpgsql_dstring_append(&ds, yytext);
1877 expr = palloc(sizeof(PLpgSQL_expr) + sizeof(int) * nparams - sizeof(int));
1878 expr->dtype = PLPGSQL_DTYPE_EXPR;
1879 expr->query = pstrdup(plpgsql_dstring_get(&ds));
1881 expr->nparams = nparams;
1882 while(nparams-- > 0)
1883 expr->params[nparams] = params[nparams];
1884 plpgsql_dstring_free(&ds);
1887 check_sql_expr(expr->query);
1892 static PLpgSQL_type *
1893 read_datatype(int tok)
1897 PLpgSQL_type *result;
1898 bool needspace = false;
1901 lno = plpgsql_scanner_lineno();
1903 /* Often there will be a lookahead token, but if not, get one */
1909 /* lexer found word%TYPE and did its thing already */
1910 return yylval.dtype;
1913 plpgsql_dstring_init(&ds);
1919 plpgsql_error_lineno = lno;
1920 if (parenlevel != 0)
1922 (errcode(ERRCODE_SYNTAX_ERROR),
1923 errmsg("mismatched parentheses")));
1925 (errcode(ERRCODE_SYNTAX_ERROR),
1926 errmsg("incomplete datatype declaration")));
1928 /* Possible followers for datatype in a declaration */
1929 if (tok == K_NOT || tok == K_ASSIGN || tok == K_DEFAULT)
1931 /* Possible followers for datatype in a cursor_arg list */
1932 if ((tok == ',' || tok == ')') && parenlevel == 0)
1936 else if (tok == ')')
1939 plpgsql_dstring_append(&ds, " ");
1941 plpgsql_dstring_append(&ds, yytext);
1946 plpgsql_push_back_token(tok);
1948 plpgsql_error_lineno = lno; /* in case of error in parse_datatype */
1950 result = plpgsql_parse_datatype(plpgsql_dstring_get(&ds));
1952 plpgsql_dstring_free(&ds);
1957 static PLpgSQL_stmt *
1958 make_select_stmt(void)
1962 int params[MAX_EXPR_PARAMS];
1965 PLpgSQL_row *row = NULL;
1966 PLpgSQL_rec *rec = NULL;
1968 bool have_into = false;
1970 plpgsql_dstring_init(&ds);
1971 plpgsql_dstring_append(&ds, "SELECT ");
1981 plpgsql_error_lineno = plpgsql_scanner_lineno();
1983 (errcode(ERRCODE_SYNTAX_ERROR),
1984 errmsg("unexpected end of function definition")));
1990 plpgsql_error_lineno = plpgsql_scanner_lineno();
1992 (errcode(ERRCODE_SYNTAX_ERROR),
1993 errmsg("INTO specified more than once")));
2000 check_assignable((PLpgSQL_datum *) row);
2006 check_assignable((PLpgSQL_datum *) rec);
2011 row = read_into_scalar_list(yytext, yylval.scalar);
2016 /* Treat the INTO as non-special */
2017 plpgsql_dstring_append(&ds, " INTO ");
2018 plpgsql_push_back_token(tok);
2024 if (plpgsql_SpaceScanned)
2025 plpgsql_dstring_append(&ds, " ");
2030 snprintf(buf, sizeof(buf), " $%d ",
2031 assign_expr_param(yylval.scalar->dno,
2033 plpgsql_dstring_append(&ds, buf);
2037 snprintf(buf, sizeof(buf), " $%d ",
2038 assign_expr_param(yylval.row->rowno,
2040 plpgsql_dstring_append(&ds, buf);
2044 snprintf(buf, sizeof(buf), " $%d ",
2045 assign_expr_param(yylval.rec->recno,
2047 plpgsql_dstring_append(&ds, buf);
2051 plpgsql_dstring_append(&ds, yytext);
2056 expr = palloc(sizeof(PLpgSQL_expr) + sizeof(int) * nparams - sizeof(int));
2057 expr->dtype = PLPGSQL_DTYPE_EXPR;
2058 expr->query = pstrdup(plpgsql_dstring_get(&ds));
2060 expr->nparams = nparams;
2061 while(nparams-- > 0)
2062 expr->params[nparams] = params[nparams];
2063 plpgsql_dstring_free(&ds);
2065 check_sql_expr(expr->query);
2069 PLpgSQL_stmt_select *select;
2071 select = palloc0(sizeof(PLpgSQL_stmt_select));
2072 select->cmd_type = PLPGSQL_STMT_SELECT;
2075 select->query = expr;
2077 return (PLpgSQL_stmt *)select;
2081 PLpgSQL_stmt_execsql *execsql;
2083 execsql = palloc(sizeof(PLpgSQL_stmt_execsql));
2084 execsql->cmd_type = PLPGSQL_STMT_EXECSQL;
2085 execsql->sqlstmt = expr;
2087 return (PLpgSQL_stmt *)execsql;
2092 static PLpgSQL_stmt *
2093 make_fetch_stmt(void)
2096 PLpgSQL_row *row = NULL;
2097 PLpgSQL_rec *rec = NULL;
2098 PLpgSQL_stmt_fetch *fetch;
2100 /* We have already parsed everything through the INTO keyword */
2107 check_assignable((PLpgSQL_datum *) row);
2112 check_assignable((PLpgSQL_datum *) rec);
2116 row = read_into_scalar_list(yytext, yylval.scalar);
2120 plpgsql_error_lineno = plpgsql_scanner_lineno();
2122 (errcode(ERRCODE_SYNTAX_ERROR),
2123 errmsg("syntax error at \"%s\"", yytext),
2124 errdetail("Expected record variable, row variable, "
2125 "or list of scalar variables.")));
2130 yyerror("syntax error");
2132 fetch = palloc0(sizeof(PLpgSQL_stmt_select));
2133 fetch->cmd_type = PLPGSQL_STMT_FETCH;
2137 return (PLpgSQL_stmt *)fetch;
2142 check_assignable(PLpgSQL_datum *datum)
2144 switch (datum->dtype)
2146 case PLPGSQL_DTYPE_VAR:
2147 if (((PLpgSQL_var *) datum)->isconst)
2149 plpgsql_error_lineno = plpgsql_scanner_lineno();
2151 (errcode(ERRCODE_ERROR_IN_ASSIGNMENT),
2152 errmsg("\"%s\" is declared CONSTANT",
2153 ((PLpgSQL_var *) datum)->refname)));
2156 case PLPGSQL_DTYPE_ROW:
2157 /* always assignable? */
2159 case PLPGSQL_DTYPE_REC:
2160 /* always assignable? What about NEW/OLD? */
2162 case PLPGSQL_DTYPE_RECFIELD:
2163 /* always assignable? */
2165 case PLPGSQL_DTYPE_ARRAYELEM:
2166 /* always assignable? */
2168 case PLPGSQL_DTYPE_TRIGARG:
2169 yyerror("cannot assign to tg_argv");
2172 elog(ERROR, "unrecognized dtype: %d", datum->dtype);
2178 * Given the first datum and name in the INTO list, continue to read
2179 * comma-separated scalar variables until we run out. Then construct
2180 * and return a fake "row" variable that represents the list of
2183 static PLpgSQL_row *
2184 read_into_scalar_list(const char *initial_name,
2185 PLpgSQL_datum *initial_datum)
2188 char *fieldnames[1024];
2193 check_assignable(initial_datum);
2194 fieldnames[0] = pstrdup(initial_name);
2195 varnos[0] = initial_datum->dno;
2198 while ((tok = yylex()) == ',')
2200 /* Check for array overflow */
2201 if (nfields >= 1024)
2203 plpgsql_error_lineno = plpgsql_scanner_lineno();
2205 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2206 errmsg("too many INTO variables specified")));
2213 check_assignable(yylval.scalar);
2214 fieldnames[nfields] = pstrdup(yytext);
2215 varnos[nfields++] = yylval.scalar->dno;
2219 plpgsql_error_lineno = plpgsql_scanner_lineno();
2221 (errcode(ERRCODE_SYNTAX_ERROR),
2222 errmsg("\"%s\" is not a scalar variable",
2228 * We read an extra, non-comma token from yylex(), so push it
2229 * back onto the input stream
2231 plpgsql_push_back_token(tok);
2233 row = palloc(sizeof(PLpgSQL_row));
2234 row->dtype = PLPGSQL_DTYPE_ROW;
2235 row->refname = pstrdup("*internal*");
2236 row->lineno = plpgsql_scanner_lineno();
2237 row->rowtupdesc = NULL;
2238 row->nfields = nfields;
2239 row->fieldnames = palloc(sizeof(char *) * nfields);
2240 row->varnos = palloc(sizeof(int) * nfields);
2241 while (--nfields >= 0)
2243 row->fieldnames[nfields] = fieldnames[nfields];
2244 row->varnos[nfields] = varnos[nfields];
2247 plpgsql_adddatum((PLpgSQL_datum *)row);
2253 * Convert a single scalar into a "row" list. This is exactly
2254 * like read_into_scalar_list except we never consume any input.
2255 * In fact, since this can be invoked long after the source
2256 * input was actually read, the lineno has to be passed in.
2258 static PLpgSQL_row *
2259 make_scalar_list1(const char *initial_name,
2260 PLpgSQL_datum *initial_datum,
2265 check_assignable(initial_datum);
2267 row = palloc(sizeof(PLpgSQL_row));
2268 row->dtype = PLPGSQL_DTYPE_ROW;
2269 row->refname = pstrdup("*internal*");
2270 row->lineno = lineno;
2271 row->rowtupdesc = NULL;
2273 row->fieldnames = palloc(sizeof(char *));
2274 row->varnos = palloc(sizeof(int));
2275 row->fieldnames[0] = pstrdup(initial_name);
2276 row->varnos[0] = initial_datum->dno;
2278 plpgsql_adddatum((PLpgSQL_datum *)row);
2284 * When the PL/PgSQL parser expects to see a SQL statement, it is very
2285 * liberal in what it accepts; for example, we often assume an
2286 * unrecognized keyword is the beginning of a SQL statement. This
2287 * avoids the need to duplicate parts of the SQL grammar in the
2288 * PL/PgSQL grammar, but it means we can accept wildly malformed
2289 * input. To try and catch some of the more obviously invalid input,
2290 * we run the strings we expect to be SQL statements through the main
2293 * We only invoke the raw parser (not the analyzer); this doesn't do
2294 * any database access and does not check any semantic rules, it just
2295 * checks for basic syntactic correctness. We do this here, rather
2296 * than after parsing has finished, because a malformed SQL statement
2297 * may cause the PL/PgSQL parser to become confused about statement
2298 * borders. So it is best to bail out as early as we can.
2301 check_sql_expr(const char *stmt)
2303 ErrorContextCallback syntax_errcontext;
2304 ErrorContextCallback *previous_errcontext;
2305 MemoryContext oldCxt;
2307 if (!plpgsql_check_syntax)
2311 * Setup error traceback support for ereport(). The previous
2312 * ereport callback is installed by pl_comp.c, but we don't want
2313 * that to be invoked (since it will try to transpose the syntax
2314 * error to be relative to the CREATE FUNCTION), so temporarily
2315 * remove it from the list of callbacks.
2317 Assert(error_context_stack->callback == plpgsql_compile_error_callback);
2319 previous_errcontext = error_context_stack;
2320 syntax_errcontext.callback = plpgsql_sql_error_callback;
2321 syntax_errcontext.arg = (char *) stmt;
2322 syntax_errcontext.previous = error_context_stack->previous;
2323 error_context_stack = &syntax_errcontext;
2325 oldCxt = MemoryContextSwitchTo(compile_tmp_cxt);
2326 (void) raw_parser(stmt);
2327 MemoryContextSwitchTo(oldCxt);
2329 /* Restore former ereport callback */
2330 error_context_stack = previous_errcontext;
2334 plpgsql_sql_error_callback(void *arg)
2336 char *sql_stmt = (char *) arg;
2338 Assert(plpgsql_error_funcname);
2340 errcontext("SQL statement in PL/PgSQL function \"%s\" near line %d",
2341 plpgsql_error_funcname, plpgsql_error_lineno);
2342 internalerrquery(sql_stmt);
2343 internalerrposition(geterrposition());
2348 check_labels(const char *start_label, const char *end_label)
2354 plpgsql_error_lineno = plpgsql_scanner_lineno();
2356 (errcode(ERRCODE_SYNTAX_ERROR),
2357 errmsg("end label \"%s\" specified for unlabelled block",
2361 if (strcmp(start_label, end_label) != 0)
2363 plpgsql_error_lineno = plpgsql_scanner_lineno();
2365 (errcode(ERRCODE_SYNTAX_ERROR),
2366 errmsg("end label \"%s\" differs from block's label \"%s\"",
2367 end_label, start_label)));
2372 /* Needed to avoid conflict between different prefix settings: */
2375 #include "pl_scan.c"