2 /**********************************************************************
3 * gram.y - Parser for the PL/pgSQL
7 * $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.75 2005/06/10 16:23:11 neilc Exp $
9 * This software is copyrighted by Jan Wieck - Hamburg.
11 * The author hereby grants permission to use, copy, modify,
12 * distribute, and license this software and its documentation
13 * for any purpose, provided that existing copyright notices are
14 * retained in all copies and that this notice is included
15 * verbatim in any distributions. No written agreement, license,
16 * or royalty fee is required for any of the authorized uses.
17 * Modifications to this software may be copyrighted by their
18 * author and need not follow the licensing terms described
19 * here, provided that the new terms are clearly indicated on
20 * the first page of each file where they apply.
22 * IN NO EVENT SHALL THE AUTHOR OR DISTRIBUTORS BE LIABLE TO ANY
23 * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
24 * CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS
25 * SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN
26 * IF THE AUTHOR HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
29 * THE AUTHOR AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY
30 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
31 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
32 * PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON
33 * AN "AS IS" BASIS, AND THE AUTHOR AND DISTRIBUTORS HAVE NO
34 * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
35 * ENHANCEMENTS, OR MODIFICATIONS.
37 **********************************************************************/
41 #include "parser/parser.h"
43 static PLpgSQL_expr *read_sql_construct(int until,
50 static PLpgSQL_expr *read_sql_stmt(const char *sqlstart);
51 static PLpgSQL_type *read_datatype(int tok);
52 static PLpgSQL_stmt *make_select_stmt(void);
53 static PLpgSQL_stmt *make_fetch_stmt(void);
54 static void check_assignable(PLpgSQL_datum *datum);
55 static PLpgSQL_row *read_into_scalar_list(const char *initial_name,
56 PLpgSQL_datum *initial_datum);
57 static void check_sql_expr(const char *stmt);
58 static void plpgsql_sql_error_callback(void *arg);
85 PLpgSQL_datum *scalar; /* a VAR, RECFIELD, or TRIGARG */
86 PLpgSQL_variable *variable; /* a VAR, REC, or ROW */
92 PLpgSQL_stmt_block *program;
93 PLpgSQL_condition *condition;
94 PLpgSQL_exception *exception;
95 PLpgSQL_exception_block *exception_block;
96 PLpgSQL_nsitem *nsitem;
97 PLpgSQL_diag_item *diagitem;
100 %type <declhdr> decl_sect
101 %type <varname> decl_varname
102 %type <str> decl_renname
103 %type <ival> decl_const decl_notnull
104 %type <expr> decl_defval decl_cursor_query
105 %type <dtype> decl_datatype
106 %type <row> decl_cursor_args
107 %type <list> decl_cursor_arglist
108 %type <nsitem> decl_aliasitem
109 %type <str> decl_stmts decl_stmt
111 %type <expr> expr_until_semi expr_until_rightbracket
112 %type <expr> expr_until_then expr_until_loop
113 %type <expr> opt_exitcond
115 %type <ival> assign_var cursor_variable
116 %type <var> cursor_varptr
117 %type <variable> decl_cursor_arg
118 %type <forvariable> for_variable
119 %type <stmt> for_control
121 %type <str> opt_lblname opt_label
122 %type <str> opt_exitlabel
123 %type <str> execsql_start
125 %type <list> proc_sect proc_stmts stmt_else loop_body
126 %type <stmt> proc_stmt pl_block
127 %type <stmt> stmt_assign stmt_if stmt_loop stmt_while stmt_exit
128 %type <stmt> stmt_return stmt_return_next stmt_raise stmt_execsql
129 %type <stmt> stmt_for stmt_select stmt_perform
130 %type <stmt> stmt_dynexecute stmt_getdiag
131 %type <stmt> stmt_open stmt_fetch stmt_close stmt_null
133 %type <list> proc_exceptions
134 %type <exception_block> exception_sect
135 %type <exception> proc_exception
136 %type <condition> proc_conditions
138 %type <list> raise_params
139 %type <ival> raise_level raise_param
140 %type <str> raise_msg
142 %type <list> getdiag_list
143 %type <diagitem> getdiag_list_item
144 %type <ival> getdiag_kind getdiag_target
208 %token T_SCALAR /* a VAR, RECFIELD, or TRIGARG */
221 pl_function : T_FUNCTION comp_optsect pl_block opt_semi
223 yylval.program = (PLpgSQL_stmt_block *)$3;
225 | T_TRIGGER comp_optsect pl_block opt_semi
227 yylval.program = (PLpgSQL_stmt_block *)$3;
235 comp_options : comp_options comp_option
239 comp_option : O_OPTION O_DUMP
241 plpgsql_DumpExecTree = true;
249 pl_block : decl_sect K_BEGIN lno proc_sect exception_sect K_END
251 PLpgSQL_stmt_block *new;
253 new = palloc0(sizeof(PLpgSQL_stmt_block));
255 new->cmd_type = PLPGSQL_STMT_BLOCK;
257 new->label = $1.label;
258 new->n_initvars = $1.n_initvars;
259 new->initvarnos = $1.initvarnos;
261 new->exceptions = $5;
265 $$ = (PLpgSQL_stmt *)new;
270 decl_sect : opt_label
272 plpgsql_ns_setlocal(false);
275 $$.initvarnos = NULL;
276 plpgsql_add_initdatums(NULL);
278 | opt_label decl_start
280 plpgsql_ns_setlocal(false);
283 $$.initvarnos = NULL;
284 plpgsql_add_initdatums(NULL);
286 | opt_label decl_start decl_stmts
288 plpgsql_ns_setlocal(false);
293 $$.n_initvars = plpgsql_add_initdatums(&($$.initvarnos));
297 decl_start : K_DECLARE
299 plpgsql_ns_setlocal(true);
303 decl_stmts : decl_stmts decl_stmt
309 decl_stmt : '<' '<' opt_lblname '>' '>'
317 decl_statement : decl_varname decl_const decl_datatype decl_notnull decl_defval
319 PLpgSQL_variable *var;
321 var = plpgsql_build_variable($1.name, $1.lineno,
325 if (var->dtype == PLPGSQL_DTYPE_VAR)
326 ((PLpgSQL_var *) var)->isconst = $2;
329 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
330 errmsg("row or record variable cannot be CONSTANT")));
334 if (var->dtype == PLPGSQL_DTYPE_VAR)
335 ((PLpgSQL_var *) var)->notnull = $4;
338 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
339 errmsg("row or record variable cannot be NOT NULL")));
343 if (var->dtype == PLPGSQL_DTYPE_VAR)
344 ((PLpgSQL_var *) var)->default_val = $5;
347 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
348 errmsg("default value for row or record variable is not supported")));
351 | decl_varname K_ALIAS K_FOR decl_aliasitem ';'
353 plpgsql_ns_additem($4->itemtype,
354 $4->itemno, $1.name);
356 | K_RENAME decl_renname K_TO decl_renname ';'
358 plpgsql_ns_rename($2, $4);
360 | decl_varname K_CURSOR
361 { plpgsql_ns_push(NULL); }
362 decl_cursor_args decl_is_from decl_cursor_query
365 PLpgSQL_expr *curname_def;
370 /* pop local namespace for cursor args */
373 new = (PLpgSQL_var *)
374 plpgsql_build_variable($1.name, $1.lineno,
375 plpgsql_build_datatype(REFCURSOROID,
379 curname_def = palloc0(sizeof(PLpgSQL_expr));
381 curname_def->dtype = PLPGSQL_DTYPE_EXPR;
382 strcpy(buf, "SELECT '");
384 cp2 = buf + strlen(buf);
387 if (*cp1 == '\\' || *cp1 == '\'')
391 strcpy(cp2, "'::refcursor");
392 curname_def->query = pstrdup(buf);
393 new->default_val = curname_def;
395 new->cursor_explicit_expr = $6;
397 new->cursor_explicit_argrow = -1;
399 new->cursor_explicit_argrow = $4->rowno;
407 plpgsql_ns_setlocal(false);
408 query = read_sql_stmt("");
409 plpgsql_ns_setlocal(true);
419 | '(' decl_cursor_arglist ')'
425 new = palloc0(sizeof(PLpgSQL_row));
426 new->dtype = PLPGSQL_DTYPE_ROW;
427 new->lineno = plpgsql_scanner_lineno();
428 new->rowtupdesc = NULL;
429 new->nfields = list_length($2);
430 new->fieldnames = palloc(new->nfields * sizeof(char *));
431 new->varnos = palloc(new->nfields * sizeof(int));
436 PLpgSQL_variable *arg = (PLpgSQL_variable *) lfirst(l);
437 new->fieldnames[i] = arg->refname;
438 new->varnos[i] = arg->dno;
443 plpgsql_adddatum((PLpgSQL_datum *) new);
448 decl_cursor_arglist : decl_cursor_arglist decl_cursor_arg
450 $$ = lappend($1, $2);
458 decl_cursor_arg : decl_varname decl_datatype
460 $$ = plpgsql_build_variable($1.name, $1.lineno,
465 decl_is_from : K_IS | /* Oracle */
468 decl_aliasitem : T_WORD
473 plpgsql_convert_ident(yytext, &name, 1);
475 yyerror("only positional parameters may be aliased");
477 plpgsql_ns_setlocal(false);
478 nsi = plpgsql_ns_lookup(name, NULL);
481 plpgsql_error_lineno = plpgsql_scanner_lineno();
483 (errcode(ERRCODE_UNDEFINED_PARAMETER),
484 errmsg("function has no parameter \"%s\"",
488 plpgsql_ns_setlocal(true);
496 decl_varname : T_WORD
500 plpgsql_convert_ident(yytext, &name, 1);
502 $$.lineno = plpgsql_scanner_lineno();
506 decl_renname : T_WORD
510 plpgsql_convert_ident(yytext, &name, 1);
511 /* the result must be palloc'd, see plpgsql_ns_rename */
525 * If there's a lookahead token, read_datatype
528 $$ = read_datatype(yychar);
543 plpgsql_ns_setlocal(false);
544 $$ = plpgsql_read_expression(';', ";");
545 plpgsql_ns_setlocal(true);
549 decl_defkey : K_ASSIGN
561 proc_stmts : proc_stmts proc_stmt
566 $$ = lappend($1, $2);
577 proc_stmt : pl_block ';'
617 stmt_perform : K_PERFORM lno expr_until_semi
619 PLpgSQL_stmt_perform *new;
621 new = palloc0(sizeof(PLpgSQL_stmt_perform));
622 new->cmd_type = PLPGSQL_STMT_PERFORM;
626 $$ = (PLpgSQL_stmt *)new;
630 stmt_assign : assign_var lno K_ASSIGN expr_until_semi
632 PLpgSQL_stmt_assign *new;
634 new = palloc0(sizeof(PLpgSQL_stmt_assign));
635 new->cmd_type = PLPGSQL_STMT_ASSIGN;
640 $$ = (PLpgSQL_stmt *)new;
644 stmt_getdiag : K_GET K_DIAGNOSTICS lno getdiag_list ';'
646 PLpgSQL_stmt_getdiag *new;
648 new = palloc0(sizeof(PLpgSQL_stmt_getdiag));
649 new->cmd_type = PLPGSQL_STMT_GETDIAG;
651 new->diag_items = $4;
653 $$ = (PLpgSQL_stmt *)new;
657 getdiag_list : getdiag_list ',' getdiag_list_item
659 $$ = lappend($1, $3);
667 getdiag_list_item : getdiag_target K_ASSIGN getdiag_kind
669 PLpgSQL_diag_item *new;
671 new = palloc(sizeof(PLpgSQL_diag_item));
679 getdiag_kind : K_ROW_COUNT
681 $$ = PLPGSQL_GETDIAG_ROW_COUNT;
685 $$ = PLPGSQL_GETDIAG_RESULT_OID;
689 getdiag_target : T_SCALAR
691 check_assignable(yylval.scalar);
692 $$ = yylval.scalar->dno;
697 assign_var : T_SCALAR
699 check_assignable(yylval.scalar);
700 $$ = yylval.scalar->dno;
704 check_assignable((PLpgSQL_datum *) yylval.row);
705 $$ = yylval.row->rowno;
709 check_assignable((PLpgSQL_datum *) yylval.rec);
710 $$ = yylval.rec->recno;
712 | assign_var '[' expr_until_rightbracket
714 PLpgSQL_arrayelem *new;
716 new = palloc0(sizeof(PLpgSQL_arrayelem));
717 new->dtype = PLPGSQL_DTYPE_ARRAYELEM;
719 new->arrayparentno = $1;
721 plpgsql_adddatum((PLpgSQL_datum *)new);
727 stmt_if : K_IF lno expr_until_then proc_sect stmt_else K_END K_IF ';'
729 PLpgSQL_stmt_if *new;
731 new = palloc0(sizeof(PLpgSQL_stmt_if));
732 new->cmd_type = PLPGSQL_STMT_IF;
736 new->false_body = $5;
738 $$ = (PLpgSQL_stmt *)new;
746 | K_ELSIF lno expr_until_then proc_sect stmt_else
749 * Translate the structure: into:
751 * IF c1 THEN IF c1 THEN
761 PLpgSQL_stmt_if *new_if;
763 /* first create a new if-statement */
764 new_if = palloc0(sizeof(PLpgSQL_stmt_if));
765 new_if->cmd_type = PLPGSQL_STMT_IF;
768 new_if->true_body = $4;
769 new_if->false_body = $5;
771 /* wrap the if-statement in a "container" list */
772 $$ = list_make1(new_if);
781 stmt_loop : opt_label K_LOOP lno loop_body
783 PLpgSQL_stmt_loop *new;
785 new = palloc0(sizeof(PLpgSQL_stmt_loop));
786 new->cmd_type = PLPGSQL_STMT_LOOP;
793 $$ = (PLpgSQL_stmt *)new;
797 stmt_while : opt_label K_WHILE lno expr_until_loop loop_body
799 PLpgSQL_stmt_while *new;
801 new = palloc0(sizeof(PLpgSQL_stmt_while));
802 new->cmd_type = PLPGSQL_STMT_WHILE;
810 $$ = (PLpgSQL_stmt *)new;
814 stmt_for : opt_label K_FOR for_control loop_body
816 /* This runs after we've scanned the loop body */
817 if ($3->cmd_type == PLPGSQL_STMT_FORI)
819 PLpgSQL_stmt_fori *new;
821 new = (PLpgSQL_stmt_fori *) $3;
824 $$ = (PLpgSQL_stmt *) new;
826 else if ($3->cmd_type == PLPGSQL_STMT_FORS)
828 PLpgSQL_stmt_fors *new;
830 new = (PLpgSQL_stmt_fors *) $3;
833 $$ = (PLpgSQL_stmt *) new;
837 PLpgSQL_stmt_dynfors *new;
839 Assert($3->cmd_type == PLPGSQL_STMT_DYNFORS);
840 new = (PLpgSQL_stmt_dynfors *) $3;
843 $$ = (PLpgSQL_stmt *) new;
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;
873 plpgsql_error_lineno = $1;
874 yyerror("loop variable of loop over rows must be a record or row variable");
878 $$ = (PLpgSQL_stmt *) new;
883 bool reverse = false;
886 * We have to distinguish between two
887 * alternatives: FOR var IN a .. b and FOR
888 * var IN query. Unfortunately this is
889 * tricky, since the query in the second
890 * form needn't start with a SELECT
891 * keyword. We use the ugly hack of
892 * looking for two periods after the first
893 * token. We also check for the REVERSE
894 * keyword, which means it must be an
897 if (tok == K_REVERSE)
900 plpgsql_push_back_token(tok);
903 * Read tokens until we see either a ".."
904 * or a LOOP. The text we read may not
905 * necessarily be a well-formed SQL
906 * statement, so we need to invoke
907 * read_sql_construct directly.
909 expr1 = read_sql_construct(K_DOTDOT,
919 /* Saw "..", so it must be an integer loop */
922 PLpgSQL_stmt_fori *new;
924 /* First expression is well-formed */
925 check_sql_expr(expr1->query);
927 expr2 = plpgsql_read_expression(K_LOOP, "LOOP");
929 fvar = (PLpgSQL_var *)
930 plpgsql_build_variable($2.name,
932 plpgsql_build_datatype(INT4OID,
936 /* put the for-variable into the local block */
937 plpgsql_add_initdatums(NULL);
939 new = palloc0(sizeof(PLpgSQL_stmt_fori));
940 new->cmd_type = PLPGSQL_STMT_FORI;
943 new->reverse = reverse;
947 $$ = (PLpgSQL_stmt *) new;
952 * No "..", so it must be a query loop. We've prefixed an
953 * extra SELECT to the query text, so we need to remove that
954 * before performing syntax checking.
957 PLpgSQL_stmt_fors *new;
960 yyerror("cannot specify REVERSE in query FOR loop");
962 Assert(strncmp(expr1->query, "SELECT ", 7) == 0);
963 tmp_query = pstrdup(expr1->query + 7);
965 expr1->query = tmp_query;
967 check_sql_expr(expr1->query);
969 new = palloc0(sizeof(PLpgSQL_stmt_fors));
970 new->cmd_type = PLPGSQL_STMT_FORS;
978 plpgsql_error_lineno = $1;
979 yyerror("loop variable of loop over rows must be record or row variable");
983 $$ = (PLpgSQL_stmt *) new;
989 for_variable : T_SCALAR
993 plpgsql_convert_ident(yytext, &name, 1);
995 $$.lineno = plpgsql_scanner_lineno();
1003 plpgsql_convert_ident(yytext, &name, 1);
1005 $$.lineno = plpgsql_scanner_lineno();
1013 plpgsql_convert_ident(yytext, &name, 1);
1015 $$.lineno = plpgsql_scanner_lineno();
1016 $$.rec = yylval.rec;
1023 plpgsql_convert_ident(yytext, &name, 1);
1025 $$.lineno = plpgsql_scanner_lineno();
1026 $$.row = yylval.row;
1031 stmt_select : K_SELECT lno
1033 $$ = make_select_stmt();
1038 stmt_exit : K_EXIT lno opt_exitlabel opt_exitcond
1040 PLpgSQL_stmt_exit *new;
1042 new = palloc0(sizeof(PLpgSQL_stmt_exit));
1043 new->cmd_type = PLPGSQL_STMT_EXIT;
1048 $$ = (PLpgSQL_stmt *)new;
1052 stmt_return : K_RETURN lno
1054 PLpgSQL_stmt_return *new;
1056 new = palloc0(sizeof(PLpgSQL_stmt_return));
1057 new->cmd_type = PLPGSQL_STMT_RETURN;
1062 if (plpgsql_curr_compile->fn_retset)
1065 yyerror("RETURN cannot have a parameter in function returning set; use RETURN NEXT");
1067 else if (plpgsql_curr_compile->out_param_varno >= 0)
1070 yyerror("RETURN cannot have a parameter in function with OUT parameters");
1071 new->retvarno = plpgsql_curr_compile->out_param_varno;
1073 else if (plpgsql_curr_compile->fn_rettype == VOIDOID)
1076 yyerror("RETURN cannot have a parameter in function returning void");
1078 else if (plpgsql_curr_compile->fn_retistuple)
1083 /* we allow this to support RETURN NULL in triggers */
1087 new->retvarno = yylval.row->rowno;
1091 new->retvarno = yylval.rec->recno;
1095 yyerror("RETURN must specify a record or row variable in function returning tuple");
1099 yyerror("RETURN must specify a record or row variable in function returning tuple");
1104 * Note that a well-formed expression is
1105 * _required_ here; anything else is a
1106 * compile-time error.
1108 new->expr = plpgsql_read_expression(';', ";");
1111 $$ = (PLpgSQL_stmt *)new;
1115 stmt_return_next: K_RETURN_NEXT lno
1117 PLpgSQL_stmt_return_next *new;
1119 if (!plpgsql_curr_compile->fn_retset)
1120 yyerror("cannot use RETURN NEXT in a non-SETOF function");
1122 new = palloc0(sizeof(PLpgSQL_stmt_return_next));
1123 new->cmd_type = PLPGSQL_STMT_RETURN_NEXT;
1128 if (plpgsql_curr_compile->out_param_varno >= 0)
1131 yyerror("RETURN NEXT cannot have a parameter in function with OUT parameters");
1132 new->retvarno = plpgsql_curr_compile->out_param_varno;
1134 else if (plpgsql_curr_compile->fn_retistuple)
1139 new->retvarno = yylval.row->rowno;
1143 new->retvarno = yylval.rec->recno;
1147 yyerror("RETURN NEXT must specify a record or row variable in function returning tuple");
1151 yyerror("RETURN NEXT must specify a record or row variable in function returning tuple");
1154 new->expr = plpgsql_read_expression(';', ";");
1156 $$ = (PLpgSQL_stmt *)new;
1160 stmt_raise : K_RAISE lno raise_level raise_msg raise_params ';'
1162 PLpgSQL_stmt_raise *new;
1164 new = palloc(sizeof(PLpgSQL_stmt_raise));
1166 new->cmd_type = PLPGSQL_STMT_RAISE;
1168 new->elog_level = $3;
1172 $$ = (PLpgSQL_stmt *)new;
1174 | K_RAISE lno raise_level raise_msg ';'
1176 PLpgSQL_stmt_raise *new;
1178 new = palloc(sizeof(PLpgSQL_stmt_raise));
1180 new->cmd_type = PLPGSQL_STMT_RAISE;
1182 new->elog_level = $3;
1186 $$ = (PLpgSQL_stmt *)new;
1190 raise_msg : T_STRING
1192 $$ = plpgsql_get_string_value();
1196 raise_level : K_EXCEPTION
1222 raise_params : raise_params raise_param
1224 $$ = lappend_int($1, $2);
1228 $$ = list_make1_int($1);
1232 raise_param : ',' T_SCALAR
1234 $$ = yylval.scalar->dno;
1238 loop_body : proc_sect K_END K_LOOP ';'
1242 stmt_execsql : execsql_start lno
1244 PLpgSQL_stmt_execsql *new;
1246 new = palloc(sizeof(PLpgSQL_stmt_execsql));
1247 new->cmd_type = PLPGSQL_STMT_EXECSQL;
1249 new->sqlstmt = read_sql_stmt($1);
1251 $$ = (PLpgSQL_stmt *)new;
1255 stmt_dynexecute : K_EXECUTE lno
1257 PLpgSQL_stmt_dynexecute *new;
1261 expr = read_sql_construct(K_INTO, ';', "INTO|;", "SELECT ",
1262 true, true, &endtoken);
1264 new = palloc(sizeof(PLpgSQL_stmt_dynexecute));
1265 new->cmd_type = PLPGSQL_STMT_DYNEXECUTE;
1272 * If we saw "INTO", look for a following row
1273 * var, record var, or list of scalars.
1275 if (endtoken == K_INTO)
1280 check_assignable((PLpgSQL_datum *) yylval.row);
1281 new->row = yylval.row;
1285 check_assignable((PLpgSQL_datum *) yylval.row);
1286 new->rec = yylval.rec;
1290 new->row = read_into_scalar_list(yytext, yylval.scalar);
1294 plpgsql_error_lineno = $2;
1296 (errcode(ERRCODE_SYNTAX_ERROR),
1297 errmsg("syntax error at \"%s\"", yytext),
1298 errdetail("Expected record variable, row variable, "
1299 "or list of scalar variables.")));
1302 yyerror("syntax error");
1305 $$ = (PLpgSQL_stmt *)new;
1310 stmt_open : K_OPEN lno cursor_varptr
1312 PLpgSQL_stmt_open *new;
1315 new = palloc0(sizeof(PLpgSQL_stmt_open));
1316 new->cmd_type = PLPGSQL_STMT_OPEN;
1318 new->curvar = $3->varno;
1320 if ($3->cursor_explicit_expr == NULL)
1325 plpgsql_error_lineno = $2;
1327 (errcode(ERRCODE_SYNTAX_ERROR),
1328 errmsg("syntax error at \"%s\"",
1330 errdetail("Expected FOR to open a reference cursor.")));
1334 if (tok == K_EXECUTE)
1336 new->dynquery = read_sql_stmt("SELECT ");
1340 plpgsql_push_back_token(tok);
1341 new->query = read_sql_stmt("");
1346 if ($3->cursor_explicit_argrow >= 0)
1353 plpgsql_error_lineno = plpgsql_scanner_lineno();
1355 (errcode(ERRCODE_SYNTAX_ERROR),
1356 errmsg("cursor \"%s\" has arguments",
1361 * Push back the '(', else read_sql_stmt
1362 * will complain about unbalanced parens.
1364 plpgsql_push_back_token(tok);
1366 new->argquery = read_sql_stmt("SELECT ");
1369 * Now remove the leading and trailing parens,
1370 * because we want "select 1, 2", not
1373 cp = new->argquery->query;
1375 if (strncmp(cp, "SELECT", 6) != 0)
1377 plpgsql_error_lineno = plpgsql_scanner_lineno();
1378 /* internal error */
1379 elog(ERROR, "expected \"SELECT (\", got \"%s\"",
1380 new->argquery->query);
1383 while (*cp == ' ') /* could be more than 1 space here */
1387 plpgsql_error_lineno = plpgsql_scanner_lineno();
1388 /* internal error */
1389 elog(ERROR, "expected \"SELECT (\", got \"%s\"",
1390 new->argquery->query);
1394 cp += strlen(cp) - 1;
1397 yyerror("expected \")\"");
1405 plpgsql_error_lineno = plpgsql_scanner_lineno();
1407 (errcode(ERRCODE_SYNTAX_ERROR),
1408 errmsg("cursor \"%s\" has no arguments",
1414 plpgsql_error_lineno = plpgsql_scanner_lineno();
1416 (errcode(ERRCODE_SYNTAX_ERROR),
1417 errmsg("syntax error at \"%s\"",
1423 $$ = (PLpgSQL_stmt *)new;
1427 stmt_fetch : K_FETCH lno cursor_variable K_INTO
1429 PLpgSQL_stmt_fetch *new;
1431 new = (PLpgSQL_stmt_fetch *)make_fetch_stmt();
1434 $$ = (PLpgSQL_stmt *)new;
1439 stmt_close : K_CLOSE lno cursor_variable ';'
1441 PLpgSQL_stmt_close *new;
1443 new = palloc(sizeof(PLpgSQL_stmt_close));
1444 new->cmd_type = PLPGSQL_STMT_CLOSE;
1448 $$ = (PLpgSQL_stmt *)new;
1452 stmt_null : K_NULL ';'
1454 /* We do not bother building a node for NULL */
1459 cursor_varptr : T_SCALAR
1461 if (yylval.scalar->dtype != PLPGSQL_DTYPE_VAR)
1462 yyerror("cursor variable must be a simple variable");
1464 if (((PLpgSQL_var *) yylval.scalar)->datatype->typoid != REFCURSOROID)
1466 plpgsql_error_lineno = plpgsql_scanner_lineno();
1468 (errcode(ERRCODE_DATATYPE_MISMATCH),
1469 errmsg("\"%s\" must be of type cursor or refcursor",
1470 ((PLpgSQL_var *) yylval.scalar)->refname)));
1472 $$ = (PLpgSQL_var *) yylval.scalar;
1476 cursor_variable : T_SCALAR
1478 if (yylval.scalar->dtype != PLPGSQL_DTYPE_VAR)
1479 yyerror("cursor variable must be a simple variable");
1481 if (((PLpgSQL_var *) yylval.scalar)->datatype->typoid != REFCURSOROID)
1483 plpgsql_error_lineno = plpgsql_scanner_lineno();
1485 (errcode(ERRCODE_DATATYPE_MISMATCH),
1486 errmsg("\"%s\" must be of type refcursor",
1487 ((PLpgSQL_var *) yylval.scalar)->refname)));
1489 $$ = yylval.scalar->dno;
1493 execsql_start : T_WORD
1494 { $$ = pstrdup(yytext); }
1496 { $$ = pstrdup(yytext); }
1504 * We use a mid-rule action to add these
1505 * special variables to the namespace before
1506 * parsing the WHEN clauses themselves.
1508 PLpgSQL_exception_block *new = palloc(sizeof(PLpgSQL_exception_block));
1509 PLpgSQL_variable *var;
1511 var = plpgsql_build_variable("sqlstate", $2,
1512 plpgsql_build_datatype(TEXTOID, -1),
1514 ((PLpgSQL_var *) var)->isconst = true;
1515 new->sqlstate_varno = var->dno;
1517 var = plpgsql_build_variable("sqlerrm", $2,
1518 plpgsql_build_datatype(TEXTOID, -1),
1520 ((PLpgSQL_var *) var)->isconst = true;
1521 new->sqlerrm_varno = var->dno;
1523 $<exception_block>$ = new;
1527 PLpgSQL_exception_block *new = $<exception_block>3;
1534 proc_exceptions : proc_exceptions proc_exception
1536 $$ = lappend($1, $2);
1540 $$ = list_make1($1);
1544 proc_exception : K_WHEN lno proc_conditions K_THEN proc_sect
1546 PLpgSQL_exception *new;
1548 new = palloc0(sizeof(PLpgSQL_exception));
1550 new->conditions = $3;
1557 proc_conditions : proc_conditions K_OR opt_lblname
1559 PLpgSQL_condition *old;
1561 for (old = $1; old->next != NULL; old = old->next)
1563 old->next = plpgsql_parse_err_condition($3);
1569 $$ = plpgsql_parse_err_condition($1);
1574 { $$ = plpgsql_read_expression(';', ";"); }
1577 expr_until_rightbracket :
1578 { $$ = plpgsql_read_expression(']', "]"); }
1582 { $$ = plpgsql_read_expression(K_THEN, "THEN"); }
1586 { $$ = plpgsql_read_expression(K_LOOP, "LOOP"); }
1591 plpgsql_ns_push(NULL);
1594 | '<' '<' opt_lblname '>' '>'
1596 plpgsql_ns_push($3);
1607 plpgsql_convert_ident(yytext, &name, 1);
1612 /* just to give a better error than "syntax error" */
1613 yyerror("no such label");
1619 | K_WHEN expr_until_semi
1623 opt_lblname : T_WORD
1627 plpgsql_convert_ident(yytext, &name, 1);
1634 $$ = plpgsql_error_lineno = plpgsql_scanner_lineno();
1642 plpgsql_read_expression(int until, const char *expected)
1644 return read_sql_construct(until, 0, expected, "SELECT ", true, true, NULL);
1647 static PLpgSQL_expr *
1648 read_sql_stmt(const char *sqlstart)
1650 return read_sql_construct(';', 0, ";", sqlstart, false, true, NULL);
1654 * Read a SQL construct and build a PLpgSQL_expr for it.
1656 * until: token code for expected terminator
1657 * until2: token code for alternate terminator (pass 0 if none)
1658 * expected: text to use in complaining that terminator was not found
1659 * sqlstart: text to prefix to the accumulated SQL text
1660 * isexpression: whether to say we're reading an "expression" or a "statement"
1661 * valid_sql: whether to check the syntax of the expression (plus sqlstart)
1662 * endtoken: if not NULL, ending token is stored at *endtoken
1663 * (this is only interesting if until2 isn't zero)
1665 static PLpgSQL_expr *
1666 read_sql_construct(int until,
1668 const char *expected,
1669 const char *sqlstart,
1683 lno = plpgsql_scanner_lineno();
1684 plpgsql_dstring_init(&ds);
1685 plpgsql_dstring_append(&ds, sqlstart);
1690 if (tok == until && parenlevel == 0)
1692 if (tok == until2 && parenlevel == 0)
1694 if (tok == '(' || tok == '[')
1696 else if (tok == ')' || tok == ']')
1701 (errcode(ERRCODE_SYNTAX_ERROR),
1702 errmsg("mismatched parentheses")));
1705 * End of function definition is an error, and we don't expect to
1706 * hit a semicolon either (unless it's the until symbol, in which
1707 * case we should have fallen out above).
1709 if (tok == 0 || tok == ';')
1711 plpgsql_error_lineno = lno;
1712 if (parenlevel != 0)
1714 (errcode(ERRCODE_SYNTAX_ERROR),
1715 errmsg("mismatched parentheses")));
1718 (errcode(ERRCODE_SYNTAX_ERROR),
1719 errmsg("missing \"%s\" at end of SQL expression",
1723 (errcode(ERRCODE_SYNTAX_ERROR),
1724 errmsg("missing \"%s\" at end of SQL statement",
1728 if (plpgsql_SpaceScanned)
1729 plpgsql_dstring_append(&ds, " ");
1731 /* Check for array overflow */
1732 if (nparams >= 1024)
1734 plpgsql_error_lineno = lno;
1736 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1737 errmsg("too many variables specified in SQL statement")));
1743 params[nparams] = yylval.scalar->dno;
1744 snprintf(buf, sizeof(buf), " $%d ", ++nparams);
1745 plpgsql_dstring_append(&ds, buf);
1749 params[nparams] = yylval.row->rowno;
1750 snprintf(buf, sizeof(buf), " $%d ", ++nparams);
1751 plpgsql_dstring_append(&ds, buf);
1755 params[nparams] = yylval.rec->recno;
1756 snprintf(buf, sizeof(buf), " $%d ", ++nparams);
1757 plpgsql_dstring_append(&ds, buf);
1761 plpgsql_dstring_append(&ds, yytext);
1769 expr = palloc(sizeof(PLpgSQL_expr) + sizeof(int) * nparams - sizeof(int));
1770 expr->dtype = PLPGSQL_DTYPE_EXPR;
1771 expr->query = pstrdup(plpgsql_dstring_get(&ds));
1773 expr->nparams = nparams;
1774 while(nparams-- > 0)
1775 expr->params[nparams] = params[nparams];
1776 plpgsql_dstring_free(&ds);
1779 check_sql_expr(expr->query);
1784 static PLpgSQL_type *
1785 read_datatype(int tok)
1789 PLpgSQL_type *result;
1790 bool needspace = false;
1793 lno = plpgsql_scanner_lineno();
1795 /* Often there will be a lookahead token, but if not, get one */
1801 /* lexer found word%TYPE and did its thing already */
1802 return yylval.dtype;
1805 plpgsql_dstring_init(&ds);
1811 plpgsql_error_lineno = lno;
1812 if (parenlevel != 0)
1814 (errcode(ERRCODE_SYNTAX_ERROR),
1815 errmsg("mismatched parentheses")));
1817 (errcode(ERRCODE_SYNTAX_ERROR),
1818 errmsg("incomplete datatype declaration")));
1820 /* Possible followers for datatype in a declaration */
1821 if (tok == K_NOT || tok == K_ASSIGN || tok == K_DEFAULT)
1823 /* Possible followers for datatype in a cursor_arg list */
1824 if ((tok == ',' || tok == ')') && parenlevel == 0)
1828 else if (tok == ')')
1831 plpgsql_dstring_append(&ds, " ");
1833 plpgsql_dstring_append(&ds, yytext);
1838 plpgsql_push_back_token(tok);
1840 plpgsql_error_lineno = lno; /* in case of error in parse_datatype */
1842 result = plpgsql_parse_datatype(plpgsql_dstring_get(&ds));
1844 plpgsql_dstring_free(&ds);
1849 static PLpgSQL_stmt *
1850 make_select_stmt(void)
1857 PLpgSQL_row *row = NULL;
1858 PLpgSQL_rec *rec = NULL;
1860 bool have_into = false;
1862 plpgsql_dstring_init(&ds);
1863 plpgsql_dstring_append(&ds, "SELECT ");
1873 plpgsql_error_lineno = plpgsql_scanner_lineno();
1875 (errcode(ERRCODE_SYNTAX_ERROR),
1876 errmsg("unexpected end of function definition")));
1882 plpgsql_error_lineno = plpgsql_scanner_lineno();
1884 (errcode(ERRCODE_SYNTAX_ERROR),
1885 errmsg("INTO specified more than once")));
1901 row = read_into_scalar_list(yytext, yylval.scalar);
1906 /* Treat the INTO as non-special */
1907 plpgsql_dstring_append(&ds, " INTO ");
1908 plpgsql_push_back_token(tok);
1914 if (plpgsql_SpaceScanned)
1915 plpgsql_dstring_append(&ds, " ");
1917 /* Check for array overflow */
1918 if (nparams >= 1024)
1920 plpgsql_error_lineno = plpgsql_scanner_lineno();
1922 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1923 errmsg("too many parameters specified in SQL statement")));
1929 params[nparams] = yylval.scalar->dno;
1930 snprintf(buf, sizeof(buf), " $%d ", ++nparams);
1931 plpgsql_dstring_append(&ds, buf);
1935 params[nparams] = yylval.row->rowno;
1936 snprintf(buf, sizeof(buf), " $%d ", ++nparams);
1937 plpgsql_dstring_append(&ds, buf);
1941 params[nparams] = yylval.rec->recno;
1942 snprintf(buf, sizeof(buf), " $%d ", ++nparams);
1943 plpgsql_dstring_append(&ds, buf);
1947 plpgsql_dstring_append(&ds, yytext);
1952 expr = palloc(sizeof(PLpgSQL_expr) + sizeof(int) * nparams - sizeof(int));
1953 expr->dtype = PLPGSQL_DTYPE_EXPR;
1954 expr->query = pstrdup(plpgsql_dstring_get(&ds));
1956 expr->nparams = nparams;
1957 while(nparams-- > 0)
1958 expr->params[nparams] = params[nparams];
1959 plpgsql_dstring_free(&ds);
1963 PLpgSQL_stmt_select *select;
1965 select = palloc0(sizeof(PLpgSQL_stmt_select));
1966 select->cmd_type = PLPGSQL_STMT_SELECT;
1969 select->query = expr;
1971 return (PLpgSQL_stmt *)select;
1975 PLpgSQL_stmt_execsql *execsql;
1977 execsql = palloc(sizeof(PLpgSQL_stmt_execsql));
1978 execsql->cmd_type = PLPGSQL_STMT_EXECSQL;
1979 execsql->sqlstmt = expr;
1981 return (PLpgSQL_stmt *)execsql;
1986 static PLpgSQL_stmt *
1987 make_fetch_stmt(void)
1990 PLpgSQL_row *row = NULL;
1991 PLpgSQL_rec *rec = NULL;
1992 PLpgSQL_stmt_fetch *fetch;
1994 /* We have already parsed everything through the INTO keyword */
2008 row = read_into_scalar_list(yytext, yylval.scalar);
2012 yyerror("syntax error");
2017 yyerror("syntax error");
2019 fetch = palloc0(sizeof(PLpgSQL_stmt_select));
2020 fetch->cmd_type = PLPGSQL_STMT_FETCH;
2024 return (PLpgSQL_stmt *)fetch;
2029 check_assignable(PLpgSQL_datum *datum)
2031 switch (datum->dtype)
2033 case PLPGSQL_DTYPE_VAR:
2034 if (((PLpgSQL_var *) datum)->isconst)
2036 plpgsql_error_lineno = plpgsql_scanner_lineno();
2038 (errcode(ERRCODE_ERROR_IN_ASSIGNMENT),
2039 errmsg("\"%s\" is declared CONSTANT",
2040 ((PLpgSQL_var *) datum)->refname)));
2043 case PLPGSQL_DTYPE_ROW:
2044 /* always assignable? */
2046 case PLPGSQL_DTYPE_REC:
2047 /* always assignable? What about NEW/OLD? */
2049 case PLPGSQL_DTYPE_RECFIELD:
2050 /* always assignable? */
2052 case PLPGSQL_DTYPE_ARRAYELEM:
2053 /* always assignable? */
2055 case PLPGSQL_DTYPE_TRIGARG:
2056 yyerror("cannot assign to tg_argv");
2059 elog(ERROR, "unrecognized dtype: %d", datum->dtype);
2065 * Given the first datum and name in the INTO list, continue to read
2066 * comma-separated scalar variables until we run out. Then construct
2067 * and return a fake "row" variable that represents the list of
2070 static PLpgSQL_row *
2071 read_into_scalar_list(const char *initial_name,
2072 PLpgSQL_datum *initial_datum)
2075 char *fieldnames[1024];
2080 check_assignable(initial_datum);
2081 fieldnames[0] = pstrdup(initial_name);
2082 varnos[0] = initial_datum->dno;
2085 while ((tok = yylex()) == ',')
2087 /* Check for array overflow */
2088 if (nfields >= 1024)
2090 plpgsql_error_lineno = plpgsql_scanner_lineno();
2092 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2093 errmsg("too many INTO variables specified")));
2100 check_assignable(yylval.scalar);
2101 fieldnames[nfields] = pstrdup(yytext);
2102 varnos[nfields++] = yylval.scalar->dno;
2106 plpgsql_error_lineno = plpgsql_scanner_lineno();
2108 (errcode(ERRCODE_SYNTAX_ERROR),
2109 errmsg("\"%s\" is not a variable",
2115 * We read an extra, non-comma character from yylex(), so push it
2116 * back onto the input stream
2118 plpgsql_push_back_token(tok);
2120 row = palloc(sizeof(PLpgSQL_row));
2121 row->dtype = PLPGSQL_DTYPE_ROW;
2122 row->refname = pstrdup("*internal*");
2123 row->lineno = plpgsql_scanner_lineno();
2124 row->rowtupdesc = NULL;
2125 row->nfields = nfields;
2126 row->fieldnames = palloc(sizeof(char *) * nfields);
2127 row->varnos = palloc(sizeof(int) * nfields);
2128 while (--nfields >= 0)
2130 row->fieldnames[nfields] = fieldnames[nfields];
2131 row->varnos[nfields] = varnos[nfields];
2134 plpgsql_adddatum((PLpgSQL_datum *)row);
2140 * When the PL/PgSQL parser expects to see a SQL statement, it is very
2141 * liberal in what it accepts; for example, we often assume an
2142 * unrecognized keyword is the beginning of a SQL statement. This
2143 * avoids the need to duplicate parts of the SQL grammar in the
2144 * PL/PgSQL grammar, but it means we can accept wildly malformed
2145 * input. To try and catch some of the more obviously invalid input,
2146 * we run the strings we expect to be SQL statements through the main
2149 * We only invoke the raw parser (not the analyzer); this doesn't do
2150 * any database access and does not check any semantic rules, it just
2151 * checks for basic syntactic correctness. We do this here, rather
2152 * than after parsing has finished, because a malformed SQL statement
2153 * may cause the PL/PgSQL parser to become confused about statement
2154 * borders. So it is best to bail out as early as we can.
2157 check_sql_expr(const char *stmt)
2159 ErrorContextCallback syntax_errcontext;
2160 ErrorContextCallback *previous_errcontext;
2161 MemoryContext oldCxt;
2163 if (!plpgsql_check_syntax)
2167 * Setup error traceback support for ereport(). The previous
2168 * ereport callback is installed by pl_comp.c, but we don't want
2169 * that to be invoked (since it will try to transpose the syntax
2170 * error to be relative to the CREATE FUNCTION), so temporarily
2171 * remove it from the list of callbacks.
2173 Assert(error_context_stack->callback == plpgsql_compile_error_callback);
2175 previous_errcontext = error_context_stack;
2176 syntax_errcontext.callback = plpgsql_sql_error_callback;
2177 syntax_errcontext.arg = (char *) stmt;
2178 syntax_errcontext.previous = error_context_stack->previous;
2179 error_context_stack = &syntax_errcontext;
2181 oldCxt = MemoryContextSwitchTo(compile_tmp_cxt);
2182 (void) raw_parser(stmt);
2183 MemoryContextSwitchTo(oldCxt);
2185 /* Restore former ereport callback */
2186 error_context_stack = previous_errcontext;
2190 plpgsql_sql_error_callback(void *arg)
2192 char *sql_stmt = (char *) arg;
2194 Assert(plpgsql_error_funcname);
2196 errcontext("SQL statement in PL/PgSQL function \"%s\" near line %d",
2197 plpgsql_error_funcname, plpgsql_error_lineno);
2198 internalerrquery(sql_stmt);
2199 internalerrposition(geterrposition());
2203 #include "pl_scan.c"