2 /**********************************************************************
3 * gram.y - Parser for the PL/pgSQL
7 * $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.68 2005/04/05 18:05:46 tgl 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_nsitem *nsitem;
96 PLpgSQL_diag_item *diagitem;
99 %type <declhdr> decl_sect
100 %type <varname> decl_varname
101 %type <str> decl_renname
102 %type <ival> decl_const decl_notnull
103 %type <expr> decl_defval decl_cursor_query
104 %type <dtype> decl_datatype
105 %type <row> decl_cursor_args
106 %type <list> decl_cursor_arglist
107 %type <nsitem> decl_aliasitem
108 %type <str> decl_stmts decl_stmt
110 %type <expr> expr_until_semi expr_until_rightbracket
111 %type <expr> expr_until_then expr_until_loop
112 %type <expr> opt_exitcond
114 %type <ival> assign_var cursor_variable
115 %type <var> cursor_varptr
116 %type <variable> decl_cursor_arg
117 %type <forvariable> for_variable
118 %type <stmt> for_control
120 %type <str> opt_lblname opt_label
121 %type <str> opt_exitlabel
122 %type <str> execsql_start
124 %type <list> proc_sect proc_stmts stmt_else loop_body
125 %type <stmt> proc_stmt pl_block
126 %type <stmt> stmt_assign stmt_if stmt_loop stmt_while stmt_exit
127 %type <stmt> stmt_return stmt_return_next stmt_raise stmt_execsql
128 %type <stmt> stmt_for stmt_select stmt_perform
129 %type <stmt> stmt_dynexecute stmt_getdiag
130 %type <stmt> stmt_open stmt_fetch stmt_close stmt_null
132 %type <list> exception_sect proc_exceptions
133 %type <exception> proc_exception
134 %type <condition> proc_conditions
136 %type <list> raise_params
137 %type <ival> raise_level raise_param
138 %type <str> raise_msg
140 %type <list> getdiag_list
141 %type <diagitem> getdiag_list_item
142 %type <ival> getdiag_kind getdiag_target
206 %token T_SCALAR /* a VAR, RECFIELD, or TRIGARG */
219 pl_function : T_FUNCTION comp_optsect pl_block opt_semi
221 yylval.program = (PLpgSQL_stmt_block *)$3;
223 | T_TRIGGER comp_optsect pl_block opt_semi
225 yylval.program = (PLpgSQL_stmt_block *)$3;
233 comp_options : comp_options comp_option
237 comp_option : O_OPTION O_DUMP
239 plpgsql_DumpExecTree = true;
247 pl_block : decl_sect K_BEGIN lno proc_sect exception_sect K_END
249 PLpgSQL_stmt_block *new;
251 new = palloc0(sizeof(PLpgSQL_stmt_block));
253 new->cmd_type = PLPGSQL_STMT_BLOCK;
255 new->label = $1.label;
256 new->n_initvars = $1.n_initvars;
257 new->initvarnos = $1.initvarnos;
259 new->exceptions = $5;
263 $$ = (PLpgSQL_stmt *)new;
268 decl_sect : opt_label
270 plpgsql_ns_setlocal(false);
273 $$.initvarnos = NULL;
274 plpgsql_add_initdatums(NULL);
276 | opt_label decl_start
278 plpgsql_ns_setlocal(false);
281 $$.initvarnos = NULL;
282 plpgsql_add_initdatums(NULL);
284 | opt_label decl_start decl_stmts
286 plpgsql_ns_setlocal(false);
291 $$.n_initvars = plpgsql_add_initdatums(&($$.initvarnos));
295 decl_start : K_DECLARE
297 plpgsql_ns_setlocal(true);
301 decl_stmts : decl_stmts decl_stmt
307 decl_stmt : '<' '<' opt_lblname '>' '>'
315 decl_statement : decl_varname decl_const decl_datatype decl_notnull decl_defval
317 PLpgSQL_variable *var;
319 var = plpgsql_build_variable($1.name, $1.lineno,
323 if (var->dtype == PLPGSQL_DTYPE_VAR)
324 ((PLpgSQL_var *) var)->isconst = $2;
327 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
328 errmsg("row or record variable cannot be CONSTANT")));
332 if (var->dtype == PLPGSQL_DTYPE_VAR)
333 ((PLpgSQL_var *) var)->notnull = $4;
336 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
337 errmsg("row or record variable cannot be NOT NULL")));
341 if (var->dtype == PLPGSQL_DTYPE_VAR)
342 ((PLpgSQL_var *) var)->default_val = $5;
345 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
346 errmsg("default value for row or record variable is not supported")));
349 | decl_varname K_ALIAS K_FOR decl_aliasitem ';'
351 plpgsql_ns_additem($4->itemtype,
352 $4->itemno, $1.name);
354 | K_RENAME decl_renname K_TO decl_renname ';'
356 plpgsql_ns_rename($2, $4);
358 | decl_varname K_CURSOR
359 { plpgsql_ns_push(NULL); }
360 decl_cursor_args decl_is_from decl_cursor_query
363 PLpgSQL_expr *curname_def;
368 /* pop local namespace for cursor args */
371 new = (PLpgSQL_var *)
372 plpgsql_build_variable($1.name, $1.lineno,
373 plpgsql_build_datatype(REFCURSOROID,
377 curname_def = palloc0(sizeof(PLpgSQL_expr));
379 curname_def->dtype = PLPGSQL_DTYPE_EXPR;
380 strcpy(buf, "SELECT '");
382 cp2 = buf + strlen(buf);
385 if (*cp1 == '\\' || *cp1 == '\'')
389 strcpy(cp2, "'::refcursor");
390 curname_def->query = pstrdup(buf);
391 new->default_val = curname_def;
393 new->cursor_explicit_expr = $6;
395 new->cursor_explicit_argrow = -1;
397 new->cursor_explicit_argrow = $4->rowno;
405 plpgsql_ns_setlocal(false);
406 query = read_sql_stmt("");
407 plpgsql_ns_setlocal(true);
417 | '(' decl_cursor_arglist ')'
423 new = palloc0(sizeof(PLpgSQL_row));
424 new->dtype = PLPGSQL_DTYPE_ROW;
425 new->lineno = plpgsql_scanner_lineno();
426 new->rowtupdesc = NULL;
427 new->nfields = list_length($2);
428 new->fieldnames = palloc(new->nfields * sizeof(char *));
429 new->varnos = palloc(new->nfields * sizeof(int));
434 PLpgSQL_variable *arg = (PLpgSQL_variable *) lfirst(l);
435 new->fieldnames[i] = arg->refname;
436 new->varnos[i] = arg->dno;
441 plpgsql_adddatum((PLpgSQL_datum *) new);
446 decl_cursor_arglist : decl_cursor_arglist decl_cursor_arg
448 $$ = lappend($1, $2);
456 decl_cursor_arg : decl_varname decl_datatype
458 $$ = plpgsql_build_variable($1.name, $1.lineno,
463 decl_is_from : K_IS | /* Oracle */
466 decl_aliasitem : T_WORD
471 plpgsql_convert_ident(yytext, &name, 1);
473 yyerror("only positional parameters may be aliased");
475 plpgsql_ns_setlocal(false);
476 nsi = plpgsql_ns_lookup(name, NULL);
479 plpgsql_error_lineno = plpgsql_scanner_lineno();
481 (errcode(ERRCODE_UNDEFINED_PARAMETER),
482 errmsg("function has no parameter \"%s\"",
486 plpgsql_ns_setlocal(true);
494 decl_varname : T_WORD
498 plpgsql_convert_ident(yytext, &name, 1);
500 $$.lineno = plpgsql_scanner_lineno();
504 decl_renname : T_WORD
508 plpgsql_convert_ident(yytext, &name, 1);
509 /* the result must be palloc'd, see plpgsql_ns_rename */
523 * If there's a lookahead token, read_datatype
526 $$ = read_datatype(yychar);
541 plpgsql_ns_setlocal(false);
542 $$ = plpgsql_read_expression(';', ";");
543 plpgsql_ns_setlocal(true);
547 decl_defkey : K_ASSIGN
559 proc_stmts : proc_stmts proc_stmt
564 $$ = lappend($1, $2);
575 proc_stmt : pl_block ';'
615 stmt_perform : K_PERFORM lno expr_until_semi
617 PLpgSQL_stmt_perform *new;
619 new = palloc0(sizeof(PLpgSQL_stmt_perform));
620 new->cmd_type = PLPGSQL_STMT_PERFORM;
624 $$ = (PLpgSQL_stmt *)new;
628 stmt_assign : assign_var lno K_ASSIGN expr_until_semi
630 PLpgSQL_stmt_assign *new;
632 new = palloc0(sizeof(PLpgSQL_stmt_assign));
633 new->cmd_type = PLPGSQL_STMT_ASSIGN;
638 $$ = (PLpgSQL_stmt *)new;
642 stmt_getdiag : K_GET K_DIAGNOSTICS lno getdiag_list ';'
644 PLpgSQL_stmt_getdiag *new;
646 new = palloc0(sizeof(PLpgSQL_stmt_getdiag));
647 new->cmd_type = PLPGSQL_STMT_GETDIAG;
649 new->diag_items = $4;
651 $$ = (PLpgSQL_stmt *)new;
655 getdiag_list : getdiag_list ',' getdiag_list_item
657 $$ = lappend($1, $3);
665 getdiag_list_item : getdiag_target K_ASSIGN getdiag_kind
667 PLpgSQL_diag_item *new;
669 new = palloc(sizeof(PLpgSQL_diag_item));
677 getdiag_kind : K_ROW_COUNT
679 $$ = PLPGSQL_GETDIAG_ROW_COUNT;
683 $$ = PLPGSQL_GETDIAG_RESULT_OID;
687 getdiag_target : T_SCALAR
689 check_assignable(yylval.scalar);
690 $$ = yylval.scalar->dno;
695 assign_var : T_SCALAR
697 check_assignable(yylval.scalar);
698 $$ = yylval.scalar->dno;
702 check_assignable((PLpgSQL_datum *) yylval.row);
703 $$ = yylval.row->rowno;
707 check_assignable((PLpgSQL_datum *) yylval.rec);
708 $$ = yylval.rec->recno;
710 | assign_var '[' expr_until_rightbracket
712 PLpgSQL_arrayelem *new;
714 new = palloc0(sizeof(PLpgSQL_arrayelem));
715 new->dtype = PLPGSQL_DTYPE_ARRAYELEM;
717 new->arrayparentno = $1;
719 plpgsql_adddatum((PLpgSQL_datum *)new);
725 stmt_if : K_IF lno expr_until_then proc_sect stmt_else K_END K_IF ';'
727 PLpgSQL_stmt_if *new;
729 new = palloc0(sizeof(PLpgSQL_stmt_if));
730 new->cmd_type = PLPGSQL_STMT_IF;
734 new->false_body = $5;
736 $$ = (PLpgSQL_stmt *)new;
744 | K_ELSIF lno expr_until_then proc_sect stmt_else
747 * Translate the structure: into:
749 * IF c1 THEN IF c1 THEN
759 PLpgSQL_stmt_if *new_if;
761 /* first create a new if-statement */
762 new_if = palloc0(sizeof(PLpgSQL_stmt_if));
763 new_if->cmd_type = PLPGSQL_STMT_IF;
766 new_if->true_body = $4;
767 new_if->false_body = $5;
769 /* wrap the if-statement in a "container" list */
770 $$ = list_make1(new_if);
779 stmt_loop : opt_label K_LOOP lno loop_body
781 PLpgSQL_stmt_loop *new;
783 new = palloc0(sizeof(PLpgSQL_stmt_loop));
784 new->cmd_type = PLPGSQL_STMT_LOOP;
791 $$ = (PLpgSQL_stmt *)new;
795 stmt_while : opt_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;
808 $$ = (PLpgSQL_stmt *)new;
812 stmt_for : opt_label K_FOR for_control loop_body
814 /* This runs after we've scanned the loop body */
815 if ($3->cmd_type == PLPGSQL_STMT_FORI)
817 PLpgSQL_stmt_fori *new;
819 new = (PLpgSQL_stmt_fori *) $3;
822 $$ = (PLpgSQL_stmt *) new;
824 else if ($3->cmd_type == PLPGSQL_STMT_FORS)
826 PLpgSQL_stmt_fors *new;
828 new = (PLpgSQL_stmt_fors *) $3;
831 $$ = (PLpgSQL_stmt *) new;
835 PLpgSQL_stmt_dynfors *new;
837 Assert($3->cmd_type == PLPGSQL_STMT_DYNFORS);
838 new = (PLpgSQL_stmt_dynfors *) $3;
841 $$ = (PLpgSQL_stmt *) new;
844 /* close namespace started in opt_label */
850 lno for_variable K_IN
854 /* Simple case: EXECUTE is a dynamic FOR loop */
855 if (tok == K_EXECUTE)
857 PLpgSQL_stmt_dynfors *new;
860 expr = plpgsql_read_expression(K_LOOP, "LOOP");
862 new = palloc0(sizeof(PLpgSQL_stmt_dynfors));
863 new->cmd_type = PLPGSQL_STMT_DYNFORS;
871 plpgsql_error_lineno = $1;
872 yyerror("loop variable of loop over rows must be a record or row variable");
876 $$ = (PLpgSQL_stmt *) new;
881 bool reverse = false;
884 * We have to distinguish between two
885 * alternatives: FOR var IN a .. b and FOR
886 * var IN query. Unfortunately this is
887 * tricky, since the query in the second
888 * form needn't start with a SELECT
889 * keyword. We use the ugly hack of
890 * looking for two periods after the first
891 * token. We also check for the REVERSE
892 * keyword, which means it must be an
895 if (tok == K_REVERSE)
898 plpgsql_push_back_token(tok);
901 * Read tokens until we see either a ".."
902 * or a LOOP. The text we read may not
903 * necessarily be a well-formed SQL
904 * statement, so we need to invoke
905 * read_sql_construct directly.
907 expr1 = read_sql_construct(K_DOTDOT,
917 /* Saw "..", so it must be an integer loop */
920 PLpgSQL_stmt_fori *new;
922 /* First expression is well-formed */
923 check_sql_expr(expr1->query);
925 expr2 = plpgsql_read_expression(K_LOOP, "LOOP");
927 fvar = (PLpgSQL_var *)
928 plpgsql_build_variable($2.name,
930 plpgsql_build_datatype(INT4OID,
934 /* put the for-variable into the local block */
935 plpgsql_add_initdatums(NULL);
937 new = palloc0(sizeof(PLpgSQL_stmt_fori));
938 new->cmd_type = PLPGSQL_STMT_FORI;
941 new->reverse = reverse;
945 $$ = (PLpgSQL_stmt *) new;
950 * No "..", so it must be a query loop. We've prefixed an
951 * extra SELECT to the query text, so we need to remove that
952 * before performing syntax checking.
955 PLpgSQL_stmt_fors *new;
958 yyerror("cannot specify REVERSE in query FOR loop");
960 Assert(strncmp(expr1->query, "SELECT ", 7) == 0);
961 tmp_query = pstrdup(expr1->query + 7);
963 expr1->query = tmp_query;
965 check_sql_expr(expr1->query);
967 new = palloc0(sizeof(PLpgSQL_stmt_fors));
968 new->cmd_type = PLPGSQL_STMT_FORS;
976 plpgsql_error_lineno = $1;
977 yyerror("loop variable of loop over rows must be record or row variable");
981 $$ = (PLpgSQL_stmt *) new;
987 for_variable : T_SCALAR
991 plpgsql_convert_ident(yytext, &name, 1);
993 $$.lineno = plpgsql_scanner_lineno();
1001 plpgsql_convert_ident(yytext, &name, 1);
1003 $$.lineno = plpgsql_scanner_lineno();
1011 plpgsql_convert_ident(yytext, &name, 1);
1013 $$.lineno = plpgsql_scanner_lineno();
1014 $$.rec = yylval.rec;
1021 plpgsql_convert_ident(yytext, &name, 1);
1023 $$.lineno = plpgsql_scanner_lineno();
1024 $$.row = yylval.row;
1029 stmt_select : K_SELECT lno
1031 $$ = make_select_stmt();
1036 stmt_exit : K_EXIT lno opt_exitlabel opt_exitcond
1038 PLpgSQL_stmt_exit *new;
1040 new = palloc0(sizeof(PLpgSQL_stmt_exit));
1041 new->cmd_type = PLPGSQL_STMT_EXIT;
1046 $$ = (PLpgSQL_stmt *)new;
1050 stmt_return : K_RETURN lno
1052 PLpgSQL_stmt_return *new;
1054 new = palloc0(sizeof(PLpgSQL_stmt_return));
1055 new->cmd_type = PLPGSQL_STMT_RETURN;
1060 if (plpgsql_curr_compile->fn_retset)
1063 yyerror("RETURN cannot have a parameter in function returning set; use RETURN NEXT");
1065 else if (plpgsql_curr_compile->out_param_varno >= 0)
1068 yyerror("RETURN cannot have a parameter in function with OUT parameters");
1069 new->retvarno = plpgsql_curr_compile->out_param_varno;
1071 else if (plpgsql_curr_compile->fn_rettype == VOIDOID)
1074 yyerror("function returning void cannot specify RETURN expression");
1076 else if (plpgsql_curr_compile->fn_retistuple)
1081 /* we allow this to support RETURN NULL in triggers */
1085 new->retvarno = yylval.row->rowno;
1089 new->retvarno = yylval.rec->recno;
1093 yyerror("RETURN must specify a record or row variable in function returning tuple");
1097 yyerror("RETURN must specify a record or row variable in function returning tuple");
1102 * Note that a well-formed expression is
1103 * _required_ here; anything else is a
1104 * compile-time error.
1106 new->expr = plpgsql_read_expression(';', ";");
1109 $$ = (PLpgSQL_stmt *)new;
1113 stmt_return_next: K_RETURN_NEXT lno
1115 PLpgSQL_stmt_return_next *new;
1117 if (!plpgsql_curr_compile->fn_retset)
1118 yyerror("cannot use RETURN NEXT in a non-SETOF function");
1120 new = palloc0(sizeof(PLpgSQL_stmt_return_next));
1121 new->cmd_type = PLPGSQL_STMT_RETURN_NEXT;
1126 if (plpgsql_curr_compile->out_param_varno >= 0)
1129 yyerror("RETURN NEXT cannot have a parameter in function with OUT parameters");
1130 new->retvarno = plpgsql_curr_compile->out_param_varno;
1132 else if (plpgsql_curr_compile->fn_retistuple)
1137 new->retvarno = yylval.row->rowno;
1141 new->retvarno = yylval.rec->recno;
1145 yyerror("RETURN NEXT must specify a record or row variable in function returning tuple");
1149 yyerror("RETURN NEXT must specify a record or row variable in function returning tuple");
1152 new->expr = plpgsql_read_expression(';', ";");
1154 $$ = (PLpgSQL_stmt *)new;
1158 stmt_raise : K_RAISE lno raise_level raise_msg raise_params ';'
1160 PLpgSQL_stmt_raise *new;
1162 new = palloc(sizeof(PLpgSQL_stmt_raise));
1164 new->cmd_type = PLPGSQL_STMT_RAISE;
1166 new->elog_level = $3;
1170 $$ = (PLpgSQL_stmt *)new;
1172 | K_RAISE lno raise_level raise_msg ';'
1174 PLpgSQL_stmt_raise *new;
1176 new = palloc(sizeof(PLpgSQL_stmt_raise));
1178 new->cmd_type = PLPGSQL_STMT_RAISE;
1180 new->elog_level = $3;
1184 $$ = (PLpgSQL_stmt *)new;
1188 raise_msg : T_STRING
1190 $$ = plpgsql_get_string_value();
1194 raise_level : K_EXCEPTION
1220 raise_params : raise_params raise_param
1222 $$ = lappend_int($1, $2);
1226 $$ = list_make1_int($1);
1230 raise_param : ',' T_SCALAR
1232 $$ = yylval.scalar->dno;
1236 loop_body : proc_sect K_END K_LOOP ';'
1240 stmt_execsql : execsql_start lno
1242 PLpgSQL_stmt_execsql *new;
1244 new = palloc(sizeof(PLpgSQL_stmt_execsql));
1245 new->cmd_type = PLPGSQL_STMT_EXECSQL;
1247 new->sqlstmt = read_sql_stmt($1);
1249 $$ = (PLpgSQL_stmt *)new;
1253 stmt_dynexecute : K_EXECUTE lno expr_until_semi
1255 PLpgSQL_stmt_dynexecute *new;
1257 new = palloc(sizeof(PLpgSQL_stmt_dynexecute));
1258 new->cmd_type = PLPGSQL_STMT_DYNEXECUTE;
1262 $$ = (PLpgSQL_stmt *)new;
1266 stmt_open : K_OPEN lno cursor_varptr
1268 PLpgSQL_stmt_open *new;
1271 new = palloc0(sizeof(PLpgSQL_stmt_open));
1272 new->cmd_type = PLPGSQL_STMT_OPEN;
1274 new->curvar = $3->varno;
1276 if ($3->cursor_explicit_expr == NULL)
1281 plpgsql_error_lineno = $2;
1283 (errcode(ERRCODE_SYNTAX_ERROR),
1284 errmsg("syntax error at \"%s\"",
1286 errdetail("Expected FOR to open a reference cursor.")));
1290 if (tok == K_EXECUTE)
1292 new->dynquery = read_sql_stmt("SELECT ");
1296 plpgsql_push_back_token(tok);
1297 new->query = read_sql_stmt("");
1302 if ($3->cursor_explicit_argrow >= 0)
1309 plpgsql_error_lineno = plpgsql_scanner_lineno();
1311 (errcode(ERRCODE_SYNTAX_ERROR),
1312 errmsg("cursor \"%s\" has arguments",
1317 * Push back the '(', else read_sql_stmt
1318 * will complain about unbalanced parens.
1320 plpgsql_push_back_token(tok);
1322 new->argquery = read_sql_stmt("SELECT ");
1325 * Now remove the leading and trailing parens,
1326 * because we want "select 1, 2", not
1329 cp = new->argquery->query;
1331 if (strncmp(cp, "SELECT", 6) != 0)
1333 plpgsql_error_lineno = plpgsql_scanner_lineno();
1334 /* internal error */
1335 elog(ERROR, "expected \"SELECT (\", got \"%s\"",
1336 new->argquery->query);
1339 while (*cp == ' ') /* could be more than 1 space here */
1343 plpgsql_error_lineno = plpgsql_scanner_lineno();
1344 /* internal error */
1345 elog(ERROR, "expected \"SELECT (\", got \"%s\"",
1346 new->argquery->query);
1350 cp += strlen(cp) - 1;
1353 yyerror("expected \")\"");
1361 plpgsql_error_lineno = plpgsql_scanner_lineno();
1363 (errcode(ERRCODE_SYNTAX_ERROR),
1364 errmsg("cursor \"%s\" has no arguments",
1370 plpgsql_error_lineno = plpgsql_scanner_lineno();
1372 (errcode(ERRCODE_SYNTAX_ERROR),
1373 errmsg("syntax error at \"%s\"",
1379 $$ = (PLpgSQL_stmt *)new;
1383 stmt_fetch : K_FETCH lno cursor_variable K_INTO
1385 PLpgSQL_stmt_fetch *new;
1387 new = (PLpgSQL_stmt_fetch *)make_fetch_stmt();
1390 $$ = (PLpgSQL_stmt *)new;
1395 stmt_close : K_CLOSE lno cursor_variable ';'
1397 PLpgSQL_stmt_close *new;
1399 new = palloc(sizeof(PLpgSQL_stmt_close));
1400 new->cmd_type = PLPGSQL_STMT_CLOSE;
1404 $$ = (PLpgSQL_stmt *)new;
1408 stmt_null : K_NULL ';'
1410 /* We do not bother building a node for NULL */
1415 cursor_varptr : T_SCALAR
1417 if (yylval.scalar->dtype != PLPGSQL_DTYPE_VAR)
1418 yyerror("cursor variable must be a simple variable");
1420 if (((PLpgSQL_var *) yylval.scalar)->datatype->typoid != REFCURSOROID)
1422 plpgsql_error_lineno = plpgsql_scanner_lineno();
1424 (errcode(ERRCODE_DATATYPE_MISMATCH),
1425 errmsg("\"%s\" must be of type cursor or refcursor",
1426 ((PLpgSQL_var *) yylval.scalar)->refname)));
1428 $$ = (PLpgSQL_var *) yylval.scalar;
1432 cursor_variable : T_SCALAR
1434 if (yylval.scalar->dtype != PLPGSQL_DTYPE_VAR)
1435 yyerror("cursor variable must be a simple variable");
1437 if (((PLpgSQL_var *) yylval.scalar)->datatype->typoid != REFCURSOROID)
1439 plpgsql_error_lineno = plpgsql_scanner_lineno();
1441 (errcode(ERRCODE_DATATYPE_MISMATCH),
1442 errmsg("\"%s\" must be of type refcursor",
1443 ((PLpgSQL_var *) yylval.scalar)->refname)));
1445 $$ = yylval.scalar->dno;
1449 execsql_start : T_WORD
1450 { $$ = pstrdup(yytext); }
1452 { $$ = pstrdup(yytext); }
1457 | K_EXCEPTION proc_exceptions
1461 proc_exceptions : proc_exceptions proc_exception
1463 $$ = lappend($1, $2);
1467 $$ = list_make1($1);
1471 proc_exception : K_WHEN lno proc_conditions K_THEN proc_sect
1473 PLpgSQL_exception *new;
1475 new = palloc0(sizeof(PLpgSQL_exception));
1477 new->conditions = $3;
1484 proc_conditions : proc_conditions K_OR opt_lblname
1486 PLpgSQL_condition *old;
1488 for (old = $1; old->next != NULL; old = old->next)
1490 old->next = plpgsql_parse_err_condition($3);
1496 $$ = plpgsql_parse_err_condition($1);
1501 { $$ = plpgsql_read_expression(';', ";"); }
1504 expr_until_rightbracket :
1505 { $$ = plpgsql_read_expression(']', "]"); }
1509 { $$ = plpgsql_read_expression(K_THEN, "THEN"); }
1513 { $$ = plpgsql_read_expression(K_LOOP, "LOOP"); }
1518 plpgsql_ns_push(NULL);
1521 | '<' '<' opt_lblname '>' '>'
1523 plpgsql_ns_push($3);
1534 plpgsql_convert_ident(yytext, &name, 1);
1539 /* just to give a better error than "syntax error" */
1540 yyerror("no such label");
1546 | K_WHEN expr_until_semi
1550 opt_lblname : T_WORD
1554 plpgsql_convert_ident(yytext, &name, 1);
1561 $$ = plpgsql_error_lineno = plpgsql_scanner_lineno();
1569 plpgsql_read_expression(int until, const char *expected)
1571 return read_sql_construct(until, 0, expected, "SELECT ", true, true, NULL);
1574 static PLpgSQL_expr *
1575 read_sql_stmt(const char *sqlstart)
1577 return read_sql_construct(';', 0, ";", sqlstart, false, true, NULL);
1581 * Read a SQL construct and build a PLpgSQL_expr for it.
1583 * until: token code for expected terminator
1584 * until2: token code for alternate terminator (pass 0 if none)
1585 * expected: text to use in complaining that terminator was not found
1586 * sqlstart: text to prefix to the accumulated SQL text
1587 * isexpression: whether to say we're reading an "expression" or a "statement"
1588 * valid_sql: whether to check the syntax of the expression (plus sqlstart)
1589 * endtoken: if not NULL, ending token is stored at *endtoken
1590 * (this is only interesting if until2 isn't zero)
1592 static PLpgSQL_expr *
1593 read_sql_construct(int until,
1595 const char *expected,
1596 const char *sqlstart,
1610 lno = plpgsql_scanner_lineno();
1611 plpgsql_dstring_init(&ds);
1612 plpgsql_dstring_append(&ds, sqlstart);
1617 if (tok == until && parenlevel == 0)
1619 if (tok == until2 && parenlevel == 0)
1621 if (tok == '(' || tok == '[')
1623 else if (tok == ')' || tok == ']')
1628 (errcode(ERRCODE_SYNTAX_ERROR),
1629 errmsg("mismatched parentheses")));
1632 * End of function definition is an error, and we don't expect to
1633 * hit a semicolon either (unless it's the until symbol, in which
1634 * case we should have fallen out above).
1636 if (tok == 0 || tok == ';')
1638 plpgsql_error_lineno = lno;
1639 if (parenlevel != 0)
1641 (errcode(ERRCODE_SYNTAX_ERROR),
1642 errmsg("mismatched parentheses")));
1645 (errcode(ERRCODE_SYNTAX_ERROR),
1646 errmsg("missing \"%s\" at end of SQL expression",
1650 (errcode(ERRCODE_SYNTAX_ERROR),
1651 errmsg("missing \"%s\" at end of SQL statement",
1655 if (plpgsql_SpaceScanned)
1656 plpgsql_dstring_append(&ds, " ");
1658 /* Check for array overflow */
1659 if (nparams >= 1024)
1661 plpgsql_error_lineno = lno;
1663 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1664 errmsg("too many variables specified in SQL statement")));
1670 params[nparams] = yylval.scalar->dno;
1671 snprintf(buf, sizeof(buf), " $%d ", ++nparams);
1672 plpgsql_dstring_append(&ds, buf);
1676 params[nparams] = yylval.row->rowno;
1677 snprintf(buf, sizeof(buf), " $%d ", ++nparams);
1678 plpgsql_dstring_append(&ds, buf);
1682 params[nparams] = yylval.rec->recno;
1683 snprintf(buf, sizeof(buf), " $%d ", ++nparams);
1684 plpgsql_dstring_append(&ds, buf);
1688 plpgsql_dstring_append(&ds, yytext);
1696 expr = palloc(sizeof(PLpgSQL_expr) + sizeof(int) * nparams - sizeof(int));
1697 expr->dtype = PLPGSQL_DTYPE_EXPR;
1698 expr->query = pstrdup(plpgsql_dstring_get(&ds));
1700 expr->nparams = nparams;
1701 while(nparams-- > 0)
1702 expr->params[nparams] = params[nparams];
1703 plpgsql_dstring_free(&ds);
1706 check_sql_expr(expr->query);
1711 static PLpgSQL_type *
1712 read_datatype(int tok)
1716 PLpgSQL_type *result;
1717 bool needspace = false;
1720 lno = plpgsql_scanner_lineno();
1722 /* Often there will be a lookahead token, but if not, get one */
1728 /* lexer found word%TYPE and did its thing already */
1729 return yylval.dtype;
1732 plpgsql_dstring_init(&ds);
1738 plpgsql_error_lineno = lno;
1739 if (parenlevel != 0)
1741 (errcode(ERRCODE_SYNTAX_ERROR),
1742 errmsg("mismatched parentheses")));
1744 (errcode(ERRCODE_SYNTAX_ERROR),
1745 errmsg("incomplete datatype declaration")));
1747 /* Possible followers for datatype in a declaration */
1748 if (tok == K_NOT || tok == K_ASSIGN || tok == K_DEFAULT)
1750 /* Possible followers for datatype in a cursor_arg list */
1751 if ((tok == ',' || tok == ')') && parenlevel == 0)
1755 else if (tok == ')')
1758 plpgsql_dstring_append(&ds, " ");
1760 plpgsql_dstring_append(&ds, yytext);
1765 plpgsql_push_back_token(tok);
1767 plpgsql_error_lineno = lno; /* in case of error in parse_datatype */
1769 result = plpgsql_parse_datatype(plpgsql_dstring_get(&ds));
1771 plpgsql_dstring_free(&ds);
1776 static PLpgSQL_stmt *
1777 make_select_stmt(void)
1784 PLpgSQL_row *row = NULL;
1785 PLpgSQL_rec *rec = NULL;
1787 bool have_into = false;
1789 plpgsql_dstring_init(&ds);
1790 plpgsql_dstring_append(&ds, "SELECT ");
1800 plpgsql_error_lineno = plpgsql_scanner_lineno();
1802 (errcode(ERRCODE_SYNTAX_ERROR),
1803 errmsg("unexpected end of function definition")));
1809 plpgsql_error_lineno = plpgsql_scanner_lineno();
1811 (errcode(ERRCODE_SYNTAX_ERROR),
1812 errmsg("INTO specified more than once")));
1828 row = read_into_scalar_list(yytext, yylval.scalar);
1833 /* Treat the INTO as non-special */
1834 plpgsql_dstring_append(&ds, " INTO ");
1835 plpgsql_push_back_token(tok);
1841 if (plpgsql_SpaceScanned)
1842 plpgsql_dstring_append(&ds, " ");
1844 /* Check for array overflow */
1845 if (nparams >= 1024)
1847 plpgsql_error_lineno = plpgsql_scanner_lineno();
1849 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1850 errmsg("too many parameters specified in SQL statement")));
1856 params[nparams] = yylval.scalar->dno;
1857 snprintf(buf, sizeof(buf), " $%d ", ++nparams);
1858 plpgsql_dstring_append(&ds, buf);
1862 params[nparams] = yylval.row->rowno;
1863 snprintf(buf, sizeof(buf), " $%d ", ++nparams);
1864 plpgsql_dstring_append(&ds, buf);
1868 params[nparams] = yylval.rec->recno;
1869 snprintf(buf, sizeof(buf), " $%d ", ++nparams);
1870 plpgsql_dstring_append(&ds, buf);
1874 plpgsql_dstring_append(&ds, yytext);
1879 expr = palloc(sizeof(PLpgSQL_expr) + sizeof(int) * nparams - sizeof(int));
1880 expr->dtype = PLPGSQL_DTYPE_EXPR;
1881 expr->query = pstrdup(plpgsql_dstring_get(&ds));
1883 expr->nparams = nparams;
1884 while(nparams-- > 0)
1885 expr->params[nparams] = params[nparams];
1886 plpgsql_dstring_free(&ds);
1890 PLpgSQL_stmt_select *select;
1892 select = palloc0(sizeof(PLpgSQL_stmt_select));
1893 select->cmd_type = PLPGSQL_STMT_SELECT;
1896 select->query = expr;
1898 return (PLpgSQL_stmt *)select;
1902 PLpgSQL_stmt_execsql *execsql;
1904 execsql = palloc(sizeof(PLpgSQL_stmt_execsql));
1905 execsql->cmd_type = PLPGSQL_STMT_EXECSQL;
1906 execsql->sqlstmt = expr;
1908 return (PLpgSQL_stmt *)execsql;
1913 static PLpgSQL_stmt *
1914 make_fetch_stmt(void)
1917 PLpgSQL_row *row = NULL;
1918 PLpgSQL_rec *rec = NULL;
1919 PLpgSQL_stmt_fetch *fetch;
1921 /* We have already parsed everything through the INTO keyword */
1935 row = read_into_scalar_list(yytext, yylval.scalar);
1939 yyerror("syntax error");
1944 yyerror("syntax error");
1946 fetch = palloc0(sizeof(PLpgSQL_stmt_select));
1947 fetch->cmd_type = PLPGSQL_STMT_FETCH;
1951 return (PLpgSQL_stmt *)fetch;
1956 check_assignable(PLpgSQL_datum *datum)
1958 switch (datum->dtype)
1960 case PLPGSQL_DTYPE_VAR:
1961 if (((PLpgSQL_var *) datum)->isconst)
1963 plpgsql_error_lineno = plpgsql_scanner_lineno();
1965 (errcode(ERRCODE_ERROR_IN_ASSIGNMENT),
1966 errmsg("\"%s\" is declared CONSTANT",
1967 ((PLpgSQL_var *) datum)->refname)));
1970 case PLPGSQL_DTYPE_ROW:
1971 /* always assignable? */
1973 case PLPGSQL_DTYPE_REC:
1974 /* always assignable? What about NEW/OLD? */
1976 case PLPGSQL_DTYPE_RECFIELD:
1977 /* always assignable? */
1979 case PLPGSQL_DTYPE_ARRAYELEM:
1980 /* always assignable? */
1982 case PLPGSQL_DTYPE_TRIGARG:
1983 yyerror("cannot assign to tg_argv");
1986 elog(ERROR, "unrecognized dtype: %d", datum->dtype);
1992 * Given the first datum and name in the INTO list, continue to read
1993 * comma-separated scalar variables until we run out. Then construct
1994 * and return a fake "row" variable that represents the list of
1997 static PLpgSQL_row *
1998 read_into_scalar_list(const char *initial_name,
1999 PLpgSQL_datum *initial_datum)
2002 char *fieldnames[1024];
2007 check_assignable(initial_datum);
2008 fieldnames[0] = pstrdup(initial_name);
2009 varnos[0] = initial_datum->dno;
2012 while ((tok = yylex()) == ',')
2014 /* Check for array overflow */
2015 if (nfields >= 1024)
2017 plpgsql_error_lineno = plpgsql_scanner_lineno();
2019 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2020 errmsg("too many INTO variables specified")));
2027 check_assignable(yylval.scalar);
2028 fieldnames[nfields] = pstrdup(yytext);
2029 varnos[nfields++] = yylval.scalar->dno;
2033 plpgsql_error_lineno = plpgsql_scanner_lineno();
2035 (errcode(ERRCODE_SYNTAX_ERROR),
2036 errmsg("\"%s\" is not a variable",
2042 * We read an extra, non-comma character from yylex(), so push it
2043 * back onto the input stream
2045 plpgsql_push_back_token(tok);
2047 row = palloc(sizeof(PLpgSQL_row));
2048 row->dtype = PLPGSQL_DTYPE_ROW;
2049 row->refname = pstrdup("*internal*");
2050 row->lineno = plpgsql_scanner_lineno();
2051 row->rowtupdesc = NULL;
2052 row->nfields = nfields;
2053 row->fieldnames = palloc(sizeof(char *) * nfields);
2054 row->varnos = palloc(sizeof(int) * nfields);
2055 while (--nfields >= 0)
2057 row->fieldnames[nfields] = fieldnames[nfields];
2058 row->varnos[nfields] = varnos[nfields];
2061 plpgsql_adddatum((PLpgSQL_datum *)row);
2067 * When the PL/PgSQL parser expects to see a SQL statement, it is very
2068 * liberal in what it accepts; for example, we often assume an
2069 * unrecognized keyword is the beginning of a SQL statement. This
2070 * avoids the need to duplicate parts of the SQL grammar in the
2071 * PL/PgSQL grammar, but it means we can accept wildly malformed
2072 * input. To try and catch some of the more obviously invalid input,
2073 * we run the strings we expect to be SQL statements through the main
2076 * We only invoke the raw parser (not the analyzer); this doesn't do
2077 * any database access and does not check any semantic rules, it just
2078 * checks for basic syntactic correctness. We do this here, rather
2079 * than after parsing has finished, because a malformed SQL statement
2080 * may cause the PL/PgSQL parser to become confused about statement
2081 * borders. So it is best to bail out as early as we can.
2084 check_sql_expr(const char *stmt)
2086 ErrorContextCallback syntax_errcontext;
2087 ErrorContextCallback *previous_errcontext;
2088 MemoryContext oldCxt;
2090 if (!plpgsql_check_syntax)
2094 * Setup error traceback support for ereport(). The previous
2095 * ereport callback is installed by pl_comp.c, but we don't want
2096 * that to be invoked (since it will try to transpose the syntax
2097 * error to be relative to the CREATE FUNCTION), so temporarily
2098 * remove it from the list of callbacks.
2100 Assert(error_context_stack->callback == plpgsql_compile_error_callback);
2102 previous_errcontext = error_context_stack;
2103 syntax_errcontext.callback = plpgsql_sql_error_callback;
2104 syntax_errcontext.arg = (char *) stmt;
2105 syntax_errcontext.previous = error_context_stack->previous;
2106 error_context_stack = &syntax_errcontext;
2108 oldCxt = MemoryContextSwitchTo(compile_tmp_cxt);
2109 (void) raw_parser(stmt);
2110 MemoryContextSwitchTo(oldCxt);
2112 /* Restore former ereport callback */
2113 error_context_stack = previous_errcontext;
2117 plpgsql_sql_error_callback(void *arg)
2119 char *sql_stmt = (char *) arg;
2121 Assert(plpgsql_error_funcname);
2123 errcontext("SQL statement in PL/PgSQL function \"%s\" near line %d",
2124 plpgsql_error_funcname, plpgsql_error_lineno);
2125 internalerrquery(sql_stmt);
2126 internalerrposition(geterrposition());
2130 #include "pl_scan.c"