2 /**********************************************************************
3 * gram.y - Parser for the PL/pgSQL
7 * $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.71 2005/05/26 03:18:53 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);
90 PLpgSQL_datum *scalar; /* a VAR, RECFIELD, or TRIGARG */
91 PLpgSQL_variable *variable; /* a VAR, REC, or ROW */
97 PLpgSQL_stmt_block *program;
98 PLpgSQL_condition *condition;
99 PLpgSQL_exception *exception;
100 PLpgSQL_nsitem *nsitem;
101 PLpgSQL_diag_item *diagitem;
104 %type <fict_vars> fict_vars_sect
105 %type <declhdr> decl_sect
106 %type <varname> decl_varname
107 %type <str> decl_renname
108 %type <ival> decl_const decl_notnull
109 %type <expr> decl_defval decl_cursor_query
110 %type <dtype> decl_datatype
111 %type <row> decl_cursor_args
112 %type <list> decl_cursor_arglist
113 %type <nsitem> decl_aliasitem
114 %type <str> decl_stmts decl_stmt
116 %type <expr> expr_until_semi expr_until_rightbracket
117 %type <expr> expr_until_then expr_until_loop
118 %type <expr> opt_exitcond
120 %type <ival> assign_var cursor_variable
121 %type <var> cursor_varptr
122 %type <variable> decl_cursor_arg
123 %type <forvariable> for_variable
124 %type <stmt> for_control
126 %type <str> opt_lblname opt_label
127 %type <str> opt_exitlabel
128 %type <str> execsql_start
130 %type <list> proc_sect proc_stmts stmt_else loop_body
131 %type <stmt> proc_stmt pl_block
132 %type <stmt> stmt_assign stmt_if stmt_loop stmt_while stmt_exit
133 %type <stmt> stmt_return stmt_return_next stmt_raise stmt_execsql
134 %type <stmt> stmt_for stmt_select stmt_perform
135 %type <stmt> stmt_dynexecute stmt_getdiag
136 %type <stmt> stmt_open stmt_fetch stmt_close stmt_null
138 %type <list> exception_sect proc_exceptions
139 %type <exception> proc_exception
140 %type <condition> proc_conditions
142 %type <list> raise_params
143 %type <ival> raise_level raise_param
144 %type <str> raise_msg
146 %type <list> getdiag_list
147 %type <diagitem> getdiag_list_item
148 %type <ival> getdiag_kind getdiag_target
212 %token T_SCALAR /* a VAR, RECFIELD, or TRIGARG */
225 pl_function : T_FUNCTION comp_optsect pl_block opt_semi
227 yylval.program = (PLpgSQL_stmt_block *)$3;
229 | T_TRIGGER comp_optsect pl_block opt_semi
231 yylval.program = (PLpgSQL_stmt_block *)$3;
239 comp_options : comp_options comp_option
243 comp_option : O_OPTION O_DUMP
245 plpgsql_DumpExecTree = true;
253 pl_block : decl_sect fict_vars_sect K_BEGIN lno proc_sect exception_sect K_END
255 PLpgSQL_stmt_block *new;
257 new = palloc0(sizeof(PLpgSQL_stmt_block));
259 new->cmd_type = PLPGSQL_STMT_BLOCK;
261 new->label = $1.label;
262 new->n_initvars = $1.n_initvars;
263 new->initvarnos = $1.initvarnos;
265 new->exceptions = $6;
267 new->sqlstate_varno = $2.sqlstate_varno;
268 new->sqlerrm_varno = $2.sqlerrm_varno;
272 $$ = (PLpgSQL_stmt *)new;
278 PLpgSQL_variable *var;
280 plpgsql_ns_setlocal(false);
281 var = plpgsql_build_variable("sqlstate", 0,
282 plpgsql_build_datatype(TEXTOID, -1), true);
283 $$.sqlstate_varno = var->dno;
284 var = plpgsql_build_variable("sqlerrm", 0,
285 plpgsql_build_datatype(TEXTOID, -1), true);
286 $$.sqlerrm_varno = var->dno;
287 plpgsql_add_initdatums(NULL);
291 decl_sect : opt_label
293 plpgsql_ns_setlocal(false);
296 $$.initvarnos = NULL;
297 plpgsql_add_initdatums(NULL);
299 | opt_label decl_start
301 plpgsql_ns_setlocal(false);
304 $$.initvarnos = NULL;
305 plpgsql_add_initdatums(NULL);
307 | opt_label decl_start decl_stmts
309 plpgsql_ns_setlocal(false);
314 $$.n_initvars = plpgsql_add_initdatums(&($$.initvarnos));
318 decl_start : K_DECLARE
320 plpgsql_ns_setlocal(true);
324 decl_stmts : decl_stmts decl_stmt
330 decl_stmt : '<' '<' opt_lblname '>' '>'
338 decl_statement : decl_varname decl_const decl_datatype decl_notnull decl_defval
340 PLpgSQL_variable *var;
342 var = plpgsql_build_variable($1.name, $1.lineno,
346 if (var->dtype == PLPGSQL_DTYPE_VAR)
347 ((PLpgSQL_var *) var)->isconst = $2;
350 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
351 errmsg("row or record variable cannot be CONSTANT")));
355 if (var->dtype == PLPGSQL_DTYPE_VAR)
356 ((PLpgSQL_var *) var)->notnull = $4;
359 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
360 errmsg("row or record variable cannot be NOT NULL")));
364 if (var->dtype == PLPGSQL_DTYPE_VAR)
365 ((PLpgSQL_var *) var)->default_val = $5;
368 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
369 errmsg("default value for row or record variable is not supported")));
372 | decl_varname K_ALIAS K_FOR decl_aliasitem ';'
374 plpgsql_ns_additem($4->itemtype,
375 $4->itemno, $1.name);
377 | K_RENAME decl_renname K_TO decl_renname ';'
379 plpgsql_ns_rename($2, $4);
381 | decl_varname K_CURSOR
382 { plpgsql_ns_push(NULL); }
383 decl_cursor_args decl_is_from decl_cursor_query
386 PLpgSQL_expr *curname_def;
391 /* pop local namespace for cursor args */
394 new = (PLpgSQL_var *)
395 plpgsql_build_variable($1.name, $1.lineno,
396 plpgsql_build_datatype(REFCURSOROID,
400 curname_def = palloc0(sizeof(PLpgSQL_expr));
402 curname_def->dtype = PLPGSQL_DTYPE_EXPR;
403 strcpy(buf, "SELECT '");
405 cp2 = buf + strlen(buf);
408 if (*cp1 == '\\' || *cp1 == '\'')
412 strcpy(cp2, "'::refcursor");
413 curname_def->query = pstrdup(buf);
414 new->default_val = curname_def;
416 new->cursor_explicit_expr = $6;
418 new->cursor_explicit_argrow = -1;
420 new->cursor_explicit_argrow = $4->rowno;
428 plpgsql_ns_setlocal(false);
429 query = read_sql_stmt("");
430 plpgsql_ns_setlocal(true);
440 | '(' decl_cursor_arglist ')'
446 new = palloc0(sizeof(PLpgSQL_row));
447 new->dtype = PLPGSQL_DTYPE_ROW;
448 new->lineno = plpgsql_scanner_lineno();
449 new->rowtupdesc = NULL;
450 new->nfields = list_length($2);
451 new->fieldnames = palloc(new->nfields * sizeof(char *));
452 new->varnos = palloc(new->nfields * sizeof(int));
457 PLpgSQL_variable *arg = (PLpgSQL_variable *) lfirst(l);
458 new->fieldnames[i] = arg->refname;
459 new->varnos[i] = arg->dno;
464 plpgsql_adddatum((PLpgSQL_datum *) new);
469 decl_cursor_arglist : decl_cursor_arglist decl_cursor_arg
471 $$ = lappend($1, $2);
479 decl_cursor_arg : decl_varname decl_datatype
481 $$ = plpgsql_build_variable($1.name, $1.lineno,
486 decl_is_from : K_IS | /* Oracle */
489 decl_aliasitem : T_WORD
494 plpgsql_convert_ident(yytext, &name, 1);
496 yyerror("only positional parameters may be aliased");
498 plpgsql_ns_setlocal(false);
499 nsi = plpgsql_ns_lookup(name, NULL);
502 plpgsql_error_lineno = plpgsql_scanner_lineno();
504 (errcode(ERRCODE_UNDEFINED_PARAMETER),
505 errmsg("function has no parameter \"%s\"",
509 plpgsql_ns_setlocal(true);
517 decl_varname : T_WORD
521 plpgsql_convert_ident(yytext, &name, 1);
523 $$.lineno = plpgsql_scanner_lineno();
527 decl_renname : T_WORD
531 plpgsql_convert_ident(yytext, &name, 1);
532 /* the result must be palloc'd, see plpgsql_ns_rename */
546 * If there's a lookahead token, read_datatype
549 $$ = read_datatype(yychar);
564 plpgsql_ns_setlocal(false);
565 $$ = plpgsql_read_expression(';', ";");
566 plpgsql_ns_setlocal(true);
570 decl_defkey : K_ASSIGN
582 proc_stmts : proc_stmts proc_stmt
587 $$ = lappend($1, $2);
598 proc_stmt : pl_block ';'
638 stmt_perform : K_PERFORM lno expr_until_semi
640 PLpgSQL_stmt_perform *new;
642 new = palloc0(sizeof(PLpgSQL_stmt_perform));
643 new->cmd_type = PLPGSQL_STMT_PERFORM;
647 $$ = (PLpgSQL_stmt *)new;
651 stmt_assign : assign_var lno K_ASSIGN expr_until_semi
653 PLpgSQL_stmt_assign *new;
655 new = palloc0(sizeof(PLpgSQL_stmt_assign));
656 new->cmd_type = PLPGSQL_STMT_ASSIGN;
661 $$ = (PLpgSQL_stmt *)new;
665 stmt_getdiag : K_GET K_DIAGNOSTICS lno getdiag_list ';'
667 PLpgSQL_stmt_getdiag *new;
669 new = palloc0(sizeof(PLpgSQL_stmt_getdiag));
670 new->cmd_type = PLPGSQL_STMT_GETDIAG;
672 new->diag_items = $4;
674 $$ = (PLpgSQL_stmt *)new;
678 getdiag_list : getdiag_list ',' getdiag_list_item
680 $$ = lappend($1, $3);
688 getdiag_list_item : getdiag_target K_ASSIGN getdiag_kind
690 PLpgSQL_diag_item *new;
692 new = palloc(sizeof(PLpgSQL_diag_item));
700 getdiag_kind : K_ROW_COUNT
702 $$ = PLPGSQL_GETDIAG_ROW_COUNT;
706 $$ = PLPGSQL_GETDIAG_RESULT_OID;
710 getdiag_target : T_SCALAR
712 check_assignable(yylval.scalar);
713 $$ = yylval.scalar->dno;
718 assign_var : T_SCALAR
720 check_assignable(yylval.scalar);
721 $$ = yylval.scalar->dno;
725 check_assignable((PLpgSQL_datum *) yylval.row);
726 $$ = yylval.row->rowno;
730 check_assignable((PLpgSQL_datum *) yylval.rec);
731 $$ = yylval.rec->recno;
733 | assign_var '[' expr_until_rightbracket
735 PLpgSQL_arrayelem *new;
737 new = palloc0(sizeof(PLpgSQL_arrayelem));
738 new->dtype = PLPGSQL_DTYPE_ARRAYELEM;
740 new->arrayparentno = $1;
742 plpgsql_adddatum((PLpgSQL_datum *)new);
748 stmt_if : K_IF lno expr_until_then proc_sect stmt_else K_END K_IF ';'
750 PLpgSQL_stmt_if *new;
752 new = palloc0(sizeof(PLpgSQL_stmt_if));
753 new->cmd_type = PLPGSQL_STMT_IF;
757 new->false_body = $5;
759 $$ = (PLpgSQL_stmt *)new;
767 | K_ELSIF lno expr_until_then proc_sect stmt_else
770 * Translate the structure: into:
772 * IF c1 THEN IF c1 THEN
782 PLpgSQL_stmt_if *new_if;
784 /* first create a new if-statement */
785 new_if = palloc0(sizeof(PLpgSQL_stmt_if));
786 new_if->cmd_type = PLPGSQL_STMT_IF;
789 new_if->true_body = $4;
790 new_if->false_body = $5;
792 /* wrap the if-statement in a "container" list */
793 $$ = list_make1(new_if);
802 stmt_loop : opt_label K_LOOP lno loop_body
804 PLpgSQL_stmt_loop *new;
806 new = palloc0(sizeof(PLpgSQL_stmt_loop));
807 new->cmd_type = PLPGSQL_STMT_LOOP;
814 $$ = (PLpgSQL_stmt *)new;
818 stmt_while : opt_label K_WHILE lno expr_until_loop loop_body
820 PLpgSQL_stmt_while *new;
822 new = palloc0(sizeof(PLpgSQL_stmt_while));
823 new->cmd_type = PLPGSQL_STMT_WHILE;
831 $$ = (PLpgSQL_stmt *)new;
835 stmt_for : opt_label K_FOR for_control loop_body
837 /* This runs after we've scanned the loop body */
838 if ($3->cmd_type == PLPGSQL_STMT_FORI)
840 PLpgSQL_stmt_fori *new;
842 new = (PLpgSQL_stmt_fori *) $3;
845 $$ = (PLpgSQL_stmt *) new;
847 else if ($3->cmd_type == PLPGSQL_STMT_FORS)
849 PLpgSQL_stmt_fors *new;
851 new = (PLpgSQL_stmt_fors *) $3;
854 $$ = (PLpgSQL_stmt *) new;
858 PLpgSQL_stmt_dynfors *new;
860 Assert($3->cmd_type == PLPGSQL_STMT_DYNFORS);
861 new = (PLpgSQL_stmt_dynfors *) $3;
864 $$ = (PLpgSQL_stmt *) new;
867 /* close namespace started in opt_label */
873 lno for_variable K_IN
877 /* Simple case: EXECUTE is a dynamic FOR loop */
878 if (tok == K_EXECUTE)
880 PLpgSQL_stmt_dynfors *new;
883 expr = plpgsql_read_expression(K_LOOP, "LOOP");
885 new = palloc0(sizeof(PLpgSQL_stmt_dynfors));
886 new->cmd_type = PLPGSQL_STMT_DYNFORS;
894 plpgsql_error_lineno = $1;
895 yyerror("loop variable of loop over rows must be a record or row variable");
899 $$ = (PLpgSQL_stmt *) new;
904 bool reverse = false;
907 * We have to distinguish between two
908 * alternatives: FOR var IN a .. b and FOR
909 * var IN query. Unfortunately this is
910 * tricky, since the query in the second
911 * form needn't start with a SELECT
912 * keyword. We use the ugly hack of
913 * looking for two periods after the first
914 * token. We also check for the REVERSE
915 * keyword, which means it must be an
918 if (tok == K_REVERSE)
921 plpgsql_push_back_token(tok);
924 * Read tokens until we see either a ".."
925 * or a LOOP. The text we read may not
926 * necessarily be a well-formed SQL
927 * statement, so we need to invoke
928 * read_sql_construct directly.
930 expr1 = read_sql_construct(K_DOTDOT,
940 /* Saw "..", so it must be an integer loop */
943 PLpgSQL_stmt_fori *new;
945 /* First expression is well-formed */
946 check_sql_expr(expr1->query);
948 expr2 = plpgsql_read_expression(K_LOOP, "LOOP");
950 fvar = (PLpgSQL_var *)
951 plpgsql_build_variable($2.name,
953 plpgsql_build_datatype(INT4OID,
957 /* put the for-variable into the local block */
958 plpgsql_add_initdatums(NULL);
960 new = palloc0(sizeof(PLpgSQL_stmt_fori));
961 new->cmd_type = PLPGSQL_STMT_FORI;
964 new->reverse = reverse;
968 $$ = (PLpgSQL_stmt *) new;
973 * No "..", so it must be a query loop. We've prefixed an
974 * extra SELECT to the query text, so we need to remove that
975 * before performing syntax checking.
978 PLpgSQL_stmt_fors *new;
981 yyerror("cannot specify REVERSE in query FOR loop");
983 Assert(strncmp(expr1->query, "SELECT ", 7) == 0);
984 tmp_query = pstrdup(expr1->query + 7);
986 expr1->query = tmp_query;
988 check_sql_expr(expr1->query);
990 new = palloc0(sizeof(PLpgSQL_stmt_fors));
991 new->cmd_type = PLPGSQL_STMT_FORS;
999 plpgsql_error_lineno = $1;
1000 yyerror("loop variable of loop over rows must be record or row variable");
1004 $$ = (PLpgSQL_stmt *) new;
1010 for_variable : T_SCALAR
1014 plpgsql_convert_ident(yytext, &name, 1);
1016 $$.lineno = plpgsql_scanner_lineno();
1024 plpgsql_convert_ident(yytext, &name, 1);
1026 $$.lineno = plpgsql_scanner_lineno();
1034 plpgsql_convert_ident(yytext, &name, 1);
1036 $$.lineno = plpgsql_scanner_lineno();
1037 $$.rec = yylval.rec;
1044 plpgsql_convert_ident(yytext, &name, 1);
1046 $$.lineno = plpgsql_scanner_lineno();
1047 $$.row = yylval.row;
1052 stmt_select : K_SELECT lno
1054 $$ = make_select_stmt();
1059 stmt_exit : K_EXIT lno opt_exitlabel opt_exitcond
1061 PLpgSQL_stmt_exit *new;
1063 new = palloc0(sizeof(PLpgSQL_stmt_exit));
1064 new->cmd_type = PLPGSQL_STMT_EXIT;
1069 $$ = (PLpgSQL_stmt *)new;
1073 stmt_return : K_RETURN lno
1075 PLpgSQL_stmt_return *new;
1077 new = palloc0(sizeof(PLpgSQL_stmt_return));
1078 new->cmd_type = PLPGSQL_STMT_RETURN;
1083 if (plpgsql_curr_compile->fn_retset)
1086 yyerror("RETURN cannot have a parameter in function returning set; use RETURN NEXT");
1088 else if (plpgsql_curr_compile->out_param_varno >= 0)
1091 yyerror("RETURN cannot have a parameter in function with OUT parameters");
1092 new->retvarno = plpgsql_curr_compile->out_param_varno;
1094 else if (plpgsql_curr_compile->fn_rettype == VOIDOID)
1097 yyerror("RETURN cannot have a parameter in function returning void");
1099 else if (plpgsql_curr_compile->fn_retistuple)
1104 /* we allow this to support RETURN NULL in triggers */
1108 new->retvarno = yylval.row->rowno;
1112 new->retvarno = yylval.rec->recno;
1116 yyerror("RETURN must specify a record or row variable in function returning tuple");
1120 yyerror("RETURN must specify a record or row variable in function returning tuple");
1125 * Note that a well-formed expression is
1126 * _required_ here; anything else is a
1127 * compile-time error.
1129 new->expr = plpgsql_read_expression(';', ";");
1132 $$ = (PLpgSQL_stmt *)new;
1136 stmt_return_next: K_RETURN_NEXT lno
1138 PLpgSQL_stmt_return_next *new;
1140 if (!plpgsql_curr_compile->fn_retset)
1141 yyerror("cannot use RETURN NEXT in a non-SETOF function");
1143 new = palloc0(sizeof(PLpgSQL_stmt_return_next));
1144 new->cmd_type = PLPGSQL_STMT_RETURN_NEXT;
1149 if (plpgsql_curr_compile->out_param_varno >= 0)
1152 yyerror("RETURN NEXT cannot have a parameter in function with OUT parameters");
1153 new->retvarno = plpgsql_curr_compile->out_param_varno;
1155 else if (plpgsql_curr_compile->fn_retistuple)
1160 new->retvarno = yylval.row->rowno;
1164 new->retvarno = yylval.rec->recno;
1168 yyerror("RETURN NEXT must specify a record or row variable in function returning tuple");
1172 yyerror("RETURN NEXT must specify a record or row variable in function returning tuple");
1175 new->expr = plpgsql_read_expression(';', ";");
1177 $$ = (PLpgSQL_stmt *)new;
1181 stmt_raise : K_RAISE lno raise_level raise_msg raise_params ';'
1183 PLpgSQL_stmt_raise *new;
1185 new = palloc(sizeof(PLpgSQL_stmt_raise));
1187 new->cmd_type = PLPGSQL_STMT_RAISE;
1189 new->elog_level = $3;
1193 $$ = (PLpgSQL_stmt *)new;
1195 | K_RAISE lno raise_level raise_msg ';'
1197 PLpgSQL_stmt_raise *new;
1199 new = palloc(sizeof(PLpgSQL_stmt_raise));
1201 new->cmd_type = PLPGSQL_STMT_RAISE;
1203 new->elog_level = $3;
1207 $$ = (PLpgSQL_stmt *)new;
1211 raise_msg : T_STRING
1213 $$ = plpgsql_get_string_value();
1217 raise_level : K_EXCEPTION
1243 raise_params : raise_params raise_param
1245 $$ = lappend_int($1, $2);
1249 $$ = list_make1_int($1);
1253 raise_param : ',' T_SCALAR
1255 $$ = yylval.scalar->dno;
1259 loop_body : proc_sect K_END K_LOOP ';'
1263 stmt_execsql : execsql_start lno
1265 PLpgSQL_stmt_execsql *new;
1267 new = palloc(sizeof(PLpgSQL_stmt_execsql));
1268 new->cmd_type = PLPGSQL_STMT_EXECSQL;
1270 new->sqlstmt = read_sql_stmt($1);
1272 $$ = (PLpgSQL_stmt *)new;
1276 stmt_dynexecute : K_EXECUTE lno expr_until_semi
1278 PLpgSQL_stmt_dynexecute *new;
1280 new = palloc(sizeof(PLpgSQL_stmt_dynexecute));
1281 new->cmd_type = PLPGSQL_STMT_DYNEXECUTE;
1285 $$ = (PLpgSQL_stmt *)new;
1289 stmt_open : K_OPEN lno cursor_varptr
1291 PLpgSQL_stmt_open *new;
1294 new = palloc0(sizeof(PLpgSQL_stmt_open));
1295 new->cmd_type = PLPGSQL_STMT_OPEN;
1297 new->curvar = $3->varno;
1299 if ($3->cursor_explicit_expr == NULL)
1304 plpgsql_error_lineno = $2;
1306 (errcode(ERRCODE_SYNTAX_ERROR),
1307 errmsg("syntax error at \"%s\"",
1309 errdetail("Expected FOR to open a reference cursor.")));
1313 if (tok == K_EXECUTE)
1315 new->dynquery = read_sql_stmt("SELECT ");
1319 plpgsql_push_back_token(tok);
1320 new->query = read_sql_stmt("");
1325 if ($3->cursor_explicit_argrow >= 0)
1332 plpgsql_error_lineno = plpgsql_scanner_lineno();
1334 (errcode(ERRCODE_SYNTAX_ERROR),
1335 errmsg("cursor \"%s\" has arguments",
1340 * Push back the '(', else read_sql_stmt
1341 * will complain about unbalanced parens.
1343 plpgsql_push_back_token(tok);
1345 new->argquery = read_sql_stmt("SELECT ");
1348 * Now remove the leading and trailing parens,
1349 * because we want "select 1, 2", not
1352 cp = new->argquery->query;
1354 if (strncmp(cp, "SELECT", 6) != 0)
1356 plpgsql_error_lineno = plpgsql_scanner_lineno();
1357 /* internal error */
1358 elog(ERROR, "expected \"SELECT (\", got \"%s\"",
1359 new->argquery->query);
1362 while (*cp == ' ') /* could be more than 1 space here */
1366 plpgsql_error_lineno = plpgsql_scanner_lineno();
1367 /* internal error */
1368 elog(ERROR, "expected \"SELECT (\", got \"%s\"",
1369 new->argquery->query);
1373 cp += strlen(cp) - 1;
1376 yyerror("expected \")\"");
1384 plpgsql_error_lineno = plpgsql_scanner_lineno();
1386 (errcode(ERRCODE_SYNTAX_ERROR),
1387 errmsg("cursor \"%s\" has no arguments",
1393 plpgsql_error_lineno = plpgsql_scanner_lineno();
1395 (errcode(ERRCODE_SYNTAX_ERROR),
1396 errmsg("syntax error at \"%s\"",
1402 $$ = (PLpgSQL_stmt *)new;
1406 stmt_fetch : K_FETCH lno cursor_variable K_INTO
1408 PLpgSQL_stmt_fetch *new;
1410 new = (PLpgSQL_stmt_fetch *)make_fetch_stmt();
1413 $$ = (PLpgSQL_stmt *)new;
1418 stmt_close : K_CLOSE lno cursor_variable ';'
1420 PLpgSQL_stmt_close *new;
1422 new = palloc(sizeof(PLpgSQL_stmt_close));
1423 new->cmd_type = PLPGSQL_STMT_CLOSE;
1427 $$ = (PLpgSQL_stmt *)new;
1431 stmt_null : K_NULL ';'
1433 /* We do not bother building a node for NULL */
1438 cursor_varptr : T_SCALAR
1440 if (yylval.scalar->dtype != PLPGSQL_DTYPE_VAR)
1441 yyerror("cursor variable must be a simple variable");
1443 if (((PLpgSQL_var *) yylval.scalar)->datatype->typoid != REFCURSOROID)
1445 plpgsql_error_lineno = plpgsql_scanner_lineno();
1447 (errcode(ERRCODE_DATATYPE_MISMATCH),
1448 errmsg("\"%s\" must be of type cursor or refcursor",
1449 ((PLpgSQL_var *) yylval.scalar)->refname)));
1451 $$ = (PLpgSQL_var *) yylval.scalar;
1455 cursor_variable : T_SCALAR
1457 if (yylval.scalar->dtype != PLPGSQL_DTYPE_VAR)
1458 yyerror("cursor variable must be a simple variable");
1460 if (((PLpgSQL_var *) yylval.scalar)->datatype->typoid != REFCURSOROID)
1462 plpgsql_error_lineno = plpgsql_scanner_lineno();
1464 (errcode(ERRCODE_DATATYPE_MISMATCH),
1465 errmsg("\"%s\" must be of type refcursor",
1466 ((PLpgSQL_var *) yylval.scalar)->refname)));
1468 $$ = yylval.scalar->dno;
1472 execsql_start : T_WORD
1473 { $$ = pstrdup(yytext); }
1475 { $$ = pstrdup(yytext); }
1480 | K_EXCEPTION proc_exceptions
1484 proc_exceptions : proc_exceptions proc_exception
1486 $$ = lappend($1, $2);
1490 $$ = list_make1($1);
1494 proc_exception : K_WHEN lno proc_conditions K_THEN proc_sect
1496 PLpgSQL_exception *new;
1498 new = palloc0(sizeof(PLpgSQL_exception));
1500 new->conditions = $3;
1507 proc_conditions : proc_conditions K_OR opt_lblname
1509 PLpgSQL_condition *old;
1511 for (old = $1; old->next != NULL; old = old->next)
1513 old->next = plpgsql_parse_err_condition($3);
1519 $$ = plpgsql_parse_err_condition($1);
1524 { $$ = plpgsql_read_expression(';', ";"); }
1527 expr_until_rightbracket :
1528 { $$ = plpgsql_read_expression(']', "]"); }
1532 { $$ = plpgsql_read_expression(K_THEN, "THEN"); }
1536 { $$ = plpgsql_read_expression(K_LOOP, "LOOP"); }
1541 plpgsql_ns_push(NULL);
1544 | '<' '<' opt_lblname '>' '>'
1546 plpgsql_ns_push($3);
1557 plpgsql_convert_ident(yytext, &name, 1);
1562 /* just to give a better error than "syntax error" */
1563 yyerror("no such label");
1569 | K_WHEN expr_until_semi
1573 opt_lblname : T_WORD
1577 plpgsql_convert_ident(yytext, &name, 1);
1584 $$ = plpgsql_error_lineno = plpgsql_scanner_lineno();
1592 plpgsql_read_expression(int until, const char *expected)
1594 return read_sql_construct(until, 0, expected, "SELECT ", true, true, NULL);
1597 static PLpgSQL_expr *
1598 read_sql_stmt(const char *sqlstart)
1600 return read_sql_construct(';', 0, ";", sqlstart, false, true, NULL);
1604 * Read a SQL construct and build a PLpgSQL_expr for it.
1606 * until: token code for expected terminator
1607 * until2: token code for alternate terminator (pass 0 if none)
1608 * expected: text to use in complaining that terminator was not found
1609 * sqlstart: text to prefix to the accumulated SQL text
1610 * isexpression: whether to say we're reading an "expression" or a "statement"
1611 * valid_sql: whether to check the syntax of the expression (plus sqlstart)
1612 * endtoken: if not NULL, ending token is stored at *endtoken
1613 * (this is only interesting if until2 isn't zero)
1615 static PLpgSQL_expr *
1616 read_sql_construct(int until,
1618 const char *expected,
1619 const char *sqlstart,
1633 lno = plpgsql_scanner_lineno();
1634 plpgsql_dstring_init(&ds);
1635 plpgsql_dstring_append(&ds, sqlstart);
1640 if (tok == until && parenlevel == 0)
1642 if (tok == until2 && parenlevel == 0)
1644 if (tok == '(' || tok == '[')
1646 else if (tok == ')' || tok == ']')
1651 (errcode(ERRCODE_SYNTAX_ERROR),
1652 errmsg("mismatched parentheses")));
1655 * End of function definition is an error, and we don't expect to
1656 * hit a semicolon either (unless it's the until symbol, in which
1657 * case we should have fallen out above).
1659 if (tok == 0 || tok == ';')
1661 plpgsql_error_lineno = lno;
1662 if (parenlevel != 0)
1664 (errcode(ERRCODE_SYNTAX_ERROR),
1665 errmsg("mismatched parentheses")));
1668 (errcode(ERRCODE_SYNTAX_ERROR),
1669 errmsg("missing \"%s\" at end of SQL expression",
1673 (errcode(ERRCODE_SYNTAX_ERROR),
1674 errmsg("missing \"%s\" at end of SQL statement",
1678 if (plpgsql_SpaceScanned)
1679 plpgsql_dstring_append(&ds, " ");
1681 /* Check for array overflow */
1682 if (nparams >= 1024)
1684 plpgsql_error_lineno = lno;
1686 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1687 errmsg("too many variables specified in SQL statement")));
1693 params[nparams] = yylval.scalar->dno;
1694 snprintf(buf, sizeof(buf), " $%d ", ++nparams);
1695 plpgsql_dstring_append(&ds, buf);
1699 params[nparams] = yylval.row->rowno;
1700 snprintf(buf, sizeof(buf), " $%d ", ++nparams);
1701 plpgsql_dstring_append(&ds, buf);
1705 params[nparams] = yylval.rec->recno;
1706 snprintf(buf, sizeof(buf), " $%d ", ++nparams);
1707 plpgsql_dstring_append(&ds, buf);
1711 plpgsql_dstring_append(&ds, yytext);
1719 expr = palloc(sizeof(PLpgSQL_expr) + sizeof(int) * nparams - sizeof(int));
1720 expr->dtype = PLPGSQL_DTYPE_EXPR;
1721 expr->query = pstrdup(plpgsql_dstring_get(&ds));
1723 expr->nparams = nparams;
1724 while(nparams-- > 0)
1725 expr->params[nparams] = params[nparams];
1726 plpgsql_dstring_free(&ds);
1729 check_sql_expr(expr->query);
1734 static PLpgSQL_type *
1735 read_datatype(int tok)
1739 PLpgSQL_type *result;
1740 bool needspace = false;
1743 lno = plpgsql_scanner_lineno();
1745 /* Often there will be a lookahead token, but if not, get one */
1751 /* lexer found word%TYPE and did its thing already */
1752 return yylval.dtype;
1755 plpgsql_dstring_init(&ds);
1761 plpgsql_error_lineno = lno;
1762 if (parenlevel != 0)
1764 (errcode(ERRCODE_SYNTAX_ERROR),
1765 errmsg("mismatched parentheses")));
1767 (errcode(ERRCODE_SYNTAX_ERROR),
1768 errmsg("incomplete datatype declaration")));
1770 /* Possible followers for datatype in a declaration */
1771 if (tok == K_NOT || tok == K_ASSIGN || tok == K_DEFAULT)
1773 /* Possible followers for datatype in a cursor_arg list */
1774 if ((tok == ',' || tok == ')') && parenlevel == 0)
1778 else if (tok == ')')
1781 plpgsql_dstring_append(&ds, " ");
1783 plpgsql_dstring_append(&ds, yytext);
1788 plpgsql_push_back_token(tok);
1790 plpgsql_error_lineno = lno; /* in case of error in parse_datatype */
1792 result = plpgsql_parse_datatype(plpgsql_dstring_get(&ds));
1794 plpgsql_dstring_free(&ds);
1799 static PLpgSQL_stmt *
1800 make_select_stmt(void)
1807 PLpgSQL_row *row = NULL;
1808 PLpgSQL_rec *rec = NULL;
1810 bool have_into = false;
1812 plpgsql_dstring_init(&ds);
1813 plpgsql_dstring_append(&ds, "SELECT ");
1823 plpgsql_error_lineno = plpgsql_scanner_lineno();
1825 (errcode(ERRCODE_SYNTAX_ERROR),
1826 errmsg("unexpected end of function definition")));
1832 plpgsql_error_lineno = plpgsql_scanner_lineno();
1834 (errcode(ERRCODE_SYNTAX_ERROR),
1835 errmsg("INTO specified more than once")));
1851 row = read_into_scalar_list(yytext, yylval.scalar);
1856 /* Treat the INTO as non-special */
1857 plpgsql_dstring_append(&ds, " INTO ");
1858 plpgsql_push_back_token(tok);
1864 if (plpgsql_SpaceScanned)
1865 plpgsql_dstring_append(&ds, " ");
1867 /* Check for array overflow */
1868 if (nparams >= 1024)
1870 plpgsql_error_lineno = plpgsql_scanner_lineno();
1872 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1873 errmsg("too many parameters specified in SQL statement")));
1879 params[nparams] = yylval.scalar->dno;
1880 snprintf(buf, sizeof(buf), " $%d ", ++nparams);
1881 plpgsql_dstring_append(&ds, buf);
1885 params[nparams] = yylval.row->rowno;
1886 snprintf(buf, sizeof(buf), " $%d ", ++nparams);
1887 plpgsql_dstring_append(&ds, buf);
1891 params[nparams] = yylval.rec->recno;
1892 snprintf(buf, sizeof(buf), " $%d ", ++nparams);
1893 plpgsql_dstring_append(&ds, buf);
1897 plpgsql_dstring_append(&ds, yytext);
1902 expr = palloc(sizeof(PLpgSQL_expr) + sizeof(int) * nparams - sizeof(int));
1903 expr->dtype = PLPGSQL_DTYPE_EXPR;
1904 expr->query = pstrdup(plpgsql_dstring_get(&ds));
1906 expr->nparams = nparams;
1907 while(nparams-- > 0)
1908 expr->params[nparams] = params[nparams];
1909 plpgsql_dstring_free(&ds);
1913 PLpgSQL_stmt_select *select;
1915 select = palloc0(sizeof(PLpgSQL_stmt_select));
1916 select->cmd_type = PLPGSQL_STMT_SELECT;
1919 select->query = expr;
1921 return (PLpgSQL_stmt *)select;
1925 PLpgSQL_stmt_execsql *execsql;
1927 execsql = palloc(sizeof(PLpgSQL_stmt_execsql));
1928 execsql->cmd_type = PLPGSQL_STMT_EXECSQL;
1929 execsql->sqlstmt = expr;
1931 return (PLpgSQL_stmt *)execsql;
1936 static PLpgSQL_stmt *
1937 make_fetch_stmt(void)
1940 PLpgSQL_row *row = NULL;
1941 PLpgSQL_rec *rec = NULL;
1942 PLpgSQL_stmt_fetch *fetch;
1944 /* We have already parsed everything through the INTO keyword */
1958 row = read_into_scalar_list(yytext, yylval.scalar);
1962 yyerror("syntax error");
1967 yyerror("syntax error");
1969 fetch = palloc0(sizeof(PLpgSQL_stmt_select));
1970 fetch->cmd_type = PLPGSQL_STMT_FETCH;
1974 return (PLpgSQL_stmt *)fetch;
1979 check_assignable(PLpgSQL_datum *datum)
1981 switch (datum->dtype)
1983 case PLPGSQL_DTYPE_VAR:
1984 if (((PLpgSQL_var *) datum)->isconst)
1986 plpgsql_error_lineno = plpgsql_scanner_lineno();
1988 (errcode(ERRCODE_ERROR_IN_ASSIGNMENT),
1989 errmsg("\"%s\" is declared CONSTANT",
1990 ((PLpgSQL_var *) datum)->refname)));
1993 case PLPGSQL_DTYPE_ROW:
1994 /* always assignable? */
1996 case PLPGSQL_DTYPE_REC:
1997 /* always assignable? What about NEW/OLD? */
1999 case PLPGSQL_DTYPE_RECFIELD:
2000 /* always assignable? */
2002 case PLPGSQL_DTYPE_ARRAYELEM:
2003 /* always assignable? */
2005 case PLPGSQL_DTYPE_TRIGARG:
2006 yyerror("cannot assign to tg_argv");
2009 elog(ERROR, "unrecognized dtype: %d", datum->dtype);
2015 * Given the first datum and name in the INTO list, continue to read
2016 * comma-separated scalar variables until we run out. Then construct
2017 * and return a fake "row" variable that represents the list of
2020 static PLpgSQL_row *
2021 read_into_scalar_list(const char *initial_name,
2022 PLpgSQL_datum *initial_datum)
2025 char *fieldnames[1024];
2030 check_assignable(initial_datum);
2031 fieldnames[0] = pstrdup(initial_name);
2032 varnos[0] = initial_datum->dno;
2035 while ((tok = yylex()) == ',')
2037 /* Check for array overflow */
2038 if (nfields >= 1024)
2040 plpgsql_error_lineno = plpgsql_scanner_lineno();
2042 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2043 errmsg("too many INTO variables specified")));
2050 check_assignable(yylval.scalar);
2051 fieldnames[nfields] = pstrdup(yytext);
2052 varnos[nfields++] = yylval.scalar->dno;
2056 plpgsql_error_lineno = plpgsql_scanner_lineno();
2058 (errcode(ERRCODE_SYNTAX_ERROR),
2059 errmsg("\"%s\" is not a variable",
2065 * We read an extra, non-comma character from yylex(), so push it
2066 * back onto the input stream
2068 plpgsql_push_back_token(tok);
2070 row = palloc(sizeof(PLpgSQL_row));
2071 row->dtype = PLPGSQL_DTYPE_ROW;
2072 row->refname = pstrdup("*internal*");
2073 row->lineno = plpgsql_scanner_lineno();
2074 row->rowtupdesc = NULL;
2075 row->nfields = nfields;
2076 row->fieldnames = palloc(sizeof(char *) * nfields);
2077 row->varnos = palloc(sizeof(int) * nfields);
2078 while (--nfields >= 0)
2080 row->fieldnames[nfields] = fieldnames[nfields];
2081 row->varnos[nfields] = varnos[nfields];
2084 plpgsql_adddatum((PLpgSQL_datum *)row);
2090 * When the PL/PgSQL parser expects to see a SQL statement, it is very
2091 * liberal in what it accepts; for example, we often assume an
2092 * unrecognized keyword is the beginning of a SQL statement. This
2093 * avoids the need to duplicate parts of the SQL grammar in the
2094 * PL/PgSQL grammar, but it means we can accept wildly malformed
2095 * input. To try and catch some of the more obviously invalid input,
2096 * we run the strings we expect to be SQL statements through the main
2099 * We only invoke the raw parser (not the analyzer); this doesn't do
2100 * any database access and does not check any semantic rules, it just
2101 * checks for basic syntactic correctness. We do this here, rather
2102 * than after parsing has finished, because a malformed SQL statement
2103 * may cause the PL/PgSQL parser to become confused about statement
2104 * borders. So it is best to bail out as early as we can.
2107 check_sql_expr(const char *stmt)
2109 ErrorContextCallback syntax_errcontext;
2110 ErrorContextCallback *previous_errcontext;
2111 MemoryContext oldCxt;
2113 if (!plpgsql_check_syntax)
2117 * Setup error traceback support for ereport(). The previous
2118 * ereport callback is installed by pl_comp.c, but we don't want
2119 * that to be invoked (since it will try to transpose the syntax
2120 * error to be relative to the CREATE FUNCTION), so temporarily
2121 * remove it from the list of callbacks.
2123 Assert(error_context_stack->callback == plpgsql_compile_error_callback);
2125 previous_errcontext = error_context_stack;
2126 syntax_errcontext.callback = plpgsql_sql_error_callback;
2127 syntax_errcontext.arg = (char *) stmt;
2128 syntax_errcontext.previous = error_context_stack->previous;
2129 error_context_stack = &syntax_errcontext;
2131 oldCxt = MemoryContextSwitchTo(compile_tmp_cxt);
2132 (void) raw_parser(stmt);
2133 MemoryContextSwitchTo(oldCxt);
2135 /* Restore former ereport callback */
2136 error_context_stack = previous_errcontext;
2140 plpgsql_sql_error_callback(void *arg)
2142 char *sql_stmt = (char *) arg;
2144 Assert(plpgsql_error_funcname);
2146 errcontext("SQL statement in PL/PgSQL function \"%s\" near line %d",
2147 plpgsql_error_funcname, plpgsql_error_lineno);
2148 internalerrquery(sql_stmt);
2149 internalerrposition(geterrposition());
2153 #include "pl_scan.c"