2 /**********************************************************************
3 * gram.y - Parser for the PL/pgSQL
7 * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.34 2002/08/08 01:36:04 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 **********************************************************************/
42 static PLpgSQL_expr *read_sql_construct(int until,
45 const char *sqlstart);
46 static PLpgSQL_expr *read_sql_stmt(const char *sqlstart);
47 static PLpgSQL_type *read_datatype(int tok);
48 static PLpgSQL_stmt *make_select_stmt(void);
49 static PLpgSQL_stmt *make_fetch_stmt(void);
50 static PLpgSQL_expr *make_tupret_expr(PLpgSQL_row *row);
51 static void check_assignable(PLpgSQL_datum *datum);
73 PLpgSQL_diag_item *dtitems;
87 PLpgSQL_datum *variable; /* a VAR, RECFIELD, or TRIGARG */
94 PLpgSQL_stmt_block *program;
95 PLpgSQL_nsitem *nsitem;
98 %type <declhdr> decl_sect
99 %type <varname> decl_varname
100 %type <str> decl_renname
101 %type <ival> decl_const, decl_notnull
102 %type <expr> decl_defval, decl_cursor_query
103 %type <dtype> decl_datatype
104 %type <row> decl_rowtype, decl_cursor_args, decl_cursor_arglist
105 %type <nsitem> decl_aliasitem
106 %type <str> decl_stmts, decl_stmt
108 %type <expr> expr_until_semi, expr_until_then, expr_until_loop
109 %type <expr> opt_exitcond
111 %type <ival> assign_var, cursor_variable
112 %type <var> fori_var, cursor_varptr, decl_cursor_arg
113 %type <varname> fori_varname
114 %type <forilow> fori_lower
115 %type <rec> fors_target
117 %type <str> opt_lblname, opt_label
118 %type <str> opt_exitlabel
119 %type <str> execsql_start
121 %type <stmts> proc_sect, proc_stmts, stmt_else, loop_body
122 %type <stmt> proc_stmt, pl_block
123 %type <stmt> stmt_assign, stmt_if, stmt_loop, stmt_while, stmt_exit
124 %type <stmt> stmt_return, stmt_raise, stmt_execsql, stmt_fori
125 %type <stmt> stmt_fors, stmt_select, stmt_perform
126 %type <stmt> stmt_dynexecute, stmt_dynfors, stmt_getdiag
127 %type <stmt> stmt_open, stmt_fetch, stmt_close
129 %type <intlist> raise_params
130 %type <ival> raise_level, raise_param
131 %type <str> raise_msg
133 %type <dtlist> getdiag_list
134 %type <ival> getdiag_item, getdiag_target
196 %token T_VARIABLE /* a VAR, RECFIELD, or TRIGARG */
209 pl_function : T_FUNCTION comp_optsect pl_block opt_semi
211 yylval.program = (PLpgSQL_stmt_block *)$3;
213 | T_TRIGGER comp_optsect pl_block opt_semi
215 yylval.program = (PLpgSQL_stmt_block *)$3;
223 comp_options : comp_options comp_option
227 comp_option : O_OPTION O_DUMP
229 plpgsql_DumpExecTree = 1;
237 pl_block : decl_sect K_BEGIN lno proc_sect K_END
239 PLpgSQL_stmt_block *new;
241 new = malloc(sizeof(PLpgSQL_stmt_block));
242 memset(new, 0, sizeof(PLpgSQL_stmt_block));
244 new->cmd_type = PLPGSQL_STMT_BLOCK;
246 new->label = $1.label;
247 new->n_initvars = $1.n_initvars;
248 new->initvarnos = $1.initvarnos;
253 $$ = (PLpgSQL_stmt *)new;
258 decl_sect : opt_label
260 plpgsql_ns_setlocal(false);
263 $$.initvarnos = NULL;
264 plpgsql_add_initdatums(NULL);
266 | opt_label decl_start
268 plpgsql_ns_setlocal(false);
271 $$.initvarnos = NULL;
272 plpgsql_add_initdatums(NULL);
274 | opt_label decl_start decl_stmts
276 plpgsql_ns_setlocal(false);
281 $$.n_initvars = plpgsql_add_initdatums(&($$.initvarnos));
285 decl_start : K_DECLARE
287 plpgsql_ns_setlocal(true);
291 decl_stmts : decl_stmts decl_stmt
297 decl_stmt : '<' '<' opt_lblname '>' '>'
305 decl_statement : decl_varname decl_const decl_datatype decl_notnull decl_defval
309 new = malloc(sizeof(PLpgSQL_var));
310 memset(new, 0, sizeof(PLpgSQL_var));
312 new->dtype = PLPGSQL_DTYPE_VAR;
313 new->refname = $1.name;
314 new->lineno = $1.lineno;
319 new->default_val = $5;
321 plpgsql_adddatum((PLpgSQL_datum *)new);
322 plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, new->varno,
325 | decl_varname K_RECORD ';'
329 new = malloc(sizeof(PLpgSQL_rec));
331 new->dtype = PLPGSQL_DTYPE_REC;
332 new->refname = $1.name;
333 new->lineno = $1.lineno;
335 plpgsql_adddatum((PLpgSQL_datum *)new);
336 plpgsql_ns_additem(PLPGSQL_NSTYPE_REC, new->recno,
339 | decl_varname decl_rowtype ';'
341 $2->dtype = PLPGSQL_DTYPE_ROW;
342 $2->refname = $1.name;
343 $2->lineno = $1.lineno;
345 plpgsql_adddatum((PLpgSQL_datum *)$2);
346 plpgsql_ns_additem(PLPGSQL_NSTYPE_ROW, $2->rowno,
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 K_SELECT decl_cursor_query
363 PLpgSQL_expr *curname_def;
368 /* pop local namespace for cursor args */
371 new = malloc(sizeof(PLpgSQL_var));
372 memset(new, 0, sizeof(PLpgSQL_var));
374 curname_def = malloc(sizeof(PLpgSQL_expr));
375 memset(curname_def, 0, sizeof(PLpgSQL_expr));
377 new->dtype = PLPGSQL_DTYPE_VAR;
378 new->refname = $1.name;
379 new->lineno = $1.lineno;
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 = strdup(buf);
393 new->default_val = curname_def;
395 new->datatype = plpgsql_parse_datatype("refcursor");
397 new->cursor_explicit_expr = $7;
399 new->cursor_explicit_argrow = -1;
401 new->cursor_explicit_argrow = $4->rowno;
403 plpgsql_adddatum((PLpgSQL_datum *)new);
404 plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, new->varno,
413 plpgsql_ns_setlocal(false);
414 query = read_sql_stmt("SELECT ");
415 plpgsql_ns_setlocal(true);
425 | '(' decl_cursor_arglist ')'
427 /* Copy the temp arrays to malloc'd storage */
428 int nfields = $2->nfields;
432 ftmp = malloc(nfields * sizeof(char *));
433 vtmp = malloc(nfields * sizeof(int));
434 memcpy(ftmp, $2->fieldnames, nfields * sizeof(char *));
435 memcpy(vtmp, $2->varnos, nfields * sizeof(int));
437 pfree((char *)($2->fieldnames));
438 pfree((char *)($2->varnos));
440 $2->fieldnames = ftmp;
443 plpgsql_adddatum((PLpgSQL_datum *)$2);
449 decl_cursor_arglist : decl_cursor_arg
453 new = malloc(sizeof(PLpgSQL_row));
454 memset(new, 0, sizeof(PLpgSQL_row));
456 new->dtype = PLPGSQL_DTYPE_ROW;
457 new->refname = strdup("*internal*");
458 new->lineno = yylineno;
459 new->rowtypeclass = InvalidOid;
461 * We make temporary fieldnames/varnos arrays that
462 * are much bigger than necessary. We will resize
463 * them to just the needed size in the
464 * decl_cursor_args production.
466 new->fieldnames = palloc(1024 * sizeof(char *));
467 new->varnos = palloc(1024 * sizeof(int));
470 new->fieldnames[0] = $1->refname;
471 new->varnos[0] = $1->varno;
475 | decl_cursor_arglist ',' decl_cursor_arg
477 int i = $1->nfields++;
479 $1->fieldnames[i] = $3->refname;
480 $1->varnos[i] = $3->varno;
486 decl_cursor_arg : decl_varname decl_datatype
490 new = malloc(sizeof(PLpgSQL_var));
491 memset(new, 0, sizeof(PLpgSQL_var));
493 new->dtype = PLPGSQL_DTYPE_VAR;
494 new->refname = $1.name;
495 new->lineno = $1.lineno;
498 new->isconst = false;
499 new->notnull = false;
501 plpgsql_adddatum((PLpgSQL_datum *)new);
502 plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, new->varno,
509 decl_is_from : K_IS | /* Oracle */
512 decl_aliasitem : T_WORD
517 plpgsql_convert_ident(yytext, &name, 1);
520 plpgsql_error_lineno = yylineno;
521 elog(ERROR, "can only alias positional parameters");
523 plpgsql_ns_setlocal(false);
524 nsi = plpgsql_ns_lookup(name, NULL);
527 plpgsql_error_lineno = yylineno;
528 elog(ERROR, "function has no parameter %s", name);
531 plpgsql_ns_setlocal(true);
545 decl_varname : T_WORD
549 plpgsql_convert_ident(yytext, &name, 1);
550 /* name should be malloc'd for use as varname */
551 $$.name = strdup(name);
552 $$.lineno = yylineno;
557 decl_renname : T_WORD
561 plpgsql_convert_ident(yytext, &name, 1);
562 /* the result must be palloc'd, see plpgsql_ns_rename */
576 * If there's a lookahead token, read_datatype
579 $$ = read_datatype(yychar);
600 expr = malloc(sizeof(PLpgSQL_expr));
601 plpgsql_dstring_init(&ds);
602 plpgsql_dstring_append(&ds, "SELECT ");
604 expr->dtype = PLPGSQL_DTYPE_EXPR;
612 plpgsql_error_lineno = lno;
613 elog(ERROR, "unexpected end of file");
617 plpgsql_error_lineno = lno;
618 elog(ERROR, "expected ; after NULL");
621 plpgsql_dstring_free(&ds);
627 plpgsql_dstring_append(&ds, yytext);
628 while ((tok = yylex()) != ';')
632 plpgsql_error_lineno = lno;
633 elog(ERROR, "unterminated default value");
635 if (plpgsql_SpaceScanned)
636 plpgsql_dstring_append(&ds, " ");
637 plpgsql_dstring_append(&ds, yytext);
639 expr->query = strdup(plpgsql_dstring_get(&ds));
640 plpgsql_dstring_free(&ds);
648 decl_defkey : K_ASSIGN
656 new = malloc(sizeof(PLpgSQL_stmts));
657 memset(new, 0, sizeof(PLpgSQL_stmts));
664 proc_stmts : proc_stmts proc_stmt
666 if ($1->stmts_used == $1->stmts_alloc) {
667 $1->stmts_alloc *= 2;
668 $1->stmts = realloc($1->stmts, sizeof(PLpgSQL_stmt *) * $1->stmts_alloc);
670 $1->stmts[$1->stmts_used++] = (struct PLpgSQL_stmt *)$2;
678 new = malloc(sizeof(PLpgSQL_stmts));
679 memset(new, 0, sizeof(PLpgSQL_stmts));
681 new->stmts_alloc = 64;
683 new->stmts = malloc(sizeof(PLpgSQL_stmt *) * new->stmts_alloc);
684 new->stmts[0] = (struct PLpgSQL_stmt *)$1;
691 proc_stmt : pl_block ';'
731 stmt_perform : K_PERFORM lno expr_until_semi
733 PLpgSQL_stmt_assign *new;
735 new = malloc(sizeof(PLpgSQL_stmt_assign));
736 memset(new, 0, sizeof(PLpgSQL_stmt_assign));
738 new->cmd_type = PLPGSQL_STMT_ASSIGN;
743 $$ = (PLpgSQL_stmt *)new;
747 stmt_assign : assign_var lno K_ASSIGN expr_until_semi
749 PLpgSQL_stmt_assign *new;
751 new = malloc(sizeof(PLpgSQL_stmt_assign));
752 memset(new, 0, sizeof(PLpgSQL_stmt_assign));
754 new->cmd_type = PLPGSQL_STMT_ASSIGN;
759 $$ = (PLpgSQL_stmt *)new;
763 stmt_getdiag : K_GET K_DIAGNOSTICS lno getdiag_list ';'
765 PLpgSQL_stmt_getdiag *new;
767 new = malloc(sizeof(PLpgSQL_stmt_getdiag));
768 memset(new, 0, sizeof(PLpgSQL_stmt_getdiag));
770 new->cmd_type = PLPGSQL_STMT_GETDIAG;
772 new->ndtitems = $4.nused;
773 new->dtitems = malloc(sizeof(PLpgSQL_diag_item) * $4.nused);
774 memcpy(new->dtitems, $4.dtitems, sizeof(PLpgSQL_diag_item) * $4.nused);
776 $$ = (PLpgSQL_stmt *)new;
780 getdiag_list : getdiag_list ',' getdiag_target K_ASSIGN getdiag_item
782 if ($1.nused == $1.nalloc)
785 $1.dtitems = repalloc($1.dtitems, sizeof(PLpgSQL_diag_item) * $1.nalloc);
787 $1.dtitems[$1.nused].target = $3;
788 $1.dtitems[$1.nused].item = $5;
791 $$.nalloc = $1.nalloc;
793 $$.dtitems = $1.dtitems;
795 | getdiag_target K_ASSIGN getdiag_item
799 $$.dtitems = palloc(sizeof(PLpgSQL_diag_item) * $$.nalloc);
800 $$.dtitems[0].target = $1;
801 $$.dtitems[0].item = $3;
805 getdiag_item : K_ROW_COUNT
807 $$ = PLPGSQL_GETDIAG_ROW_COUNT;
811 $$ = PLPGSQL_GETDIAG_RESULT_OID;
815 getdiag_target : T_VARIABLE
817 check_assignable(yylval.variable);
818 $$ = yylval.variable->dno;
823 assign_var : T_VARIABLE
825 check_assignable(yylval.variable);
826 $$ = yylval.variable->dno;
830 stmt_if : K_IF lno expr_until_then proc_sect stmt_else K_END K_IF ';'
832 PLpgSQL_stmt_if *new;
834 new = malloc(sizeof(PLpgSQL_stmt_if));
835 memset(new, 0, sizeof(PLpgSQL_stmt_if));
837 new->cmd_type = PLPGSQL_STMT_IF;
841 new->false_body = $5;
843 $$ = (PLpgSQL_stmt *)new;
851 new = malloc(sizeof(PLpgSQL_stmts));
852 memset(new, 0, sizeof(PLpgSQL_stmts));
855 | K_ELSIF lno expr_until_then proc_sect stmt_else
858 * Translate the structure: into:
860 * IF c1 THEN IF c1 THEN
873 PLpgSQL_stmt_if *new_if;
875 /* first create a new if-statement */
876 new_if = malloc(sizeof(PLpgSQL_stmt_if));
877 memset(new_if, 0, sizeof(PLpgSQL_stmt_if));
879 new_if->cmd_type = PLPGSQL_STMT_IF;
882 new_if->true_body = $4;
883 new_if->false_body = $5;
885 /* this is a 'container' for the if-statement */
886 new = malloc(sizeof(PLpgSQL_stmts));
887 memset(new, 0, sizeof(PLpgSQL_stmts));
889 new->stmts_alloc = 64;
891 new->stmts = malloc(sizeof(PLpgSQL_stmt *) * new->stmts_alloc);
892 new->stmts[0] = (struct PLpgSQL_stmt *)new_if;
904 stmt_loop : opt_label K_LOOP lno loop_body
906 PLpgSQL_stmt_loop *new;
908 new = malloc(sizeof(PLpgSQL_stmt_loop));
909 memset(new, 0, sizeof(PLpgSQL_stmt_loop));
911 new->cmd_type = PLPGSQL_STMT_LOOP;
918 $$ = (PLpgSQL_stmt *)new;
922 stmt_while : opt_label K_WHILE lno expr_until_loop loop_body
924 PLpgSQL_stmt_while *new;
926 new = malloc(sizeof(PLpgSQL_stmt_while));
927 memset(new, 0, sizeof(PLpgSQL_stmt_while));
929 new->cmd_type = PLPGSQL_STMT_WHILE;
937 $$ = (PLpgSQL_stmt *)new;
941 stmt_fori : opt_label K_FOR lno fori_var K_IN fori_lower expr_until_loop loop_body
943 PLpgSQL_stmt_fori *new;
945 new = malloc(sizeof(PLpgSQL_stmt_fori));
946 memset(new, 0, sizeof(PLpgSQL_stmt_fori));
948 new->cmd_type = PLPGSQL_STMT_FORI;
952 new->reverse = $6.reverse;
953 new->lower = $6.expr;
959 $$ = (PLpgSQL_stmt *)new;
963 fori_var : fori_varname
967 new = malloc(sizeof(PLpgSQL_var));
968 memset(new, 0, sizeof(PLpgSQL_var));
970 new->dtype = PLPGSQL_DTYPE_VAR;
971 new->refname = $1.name;
972 new->lineno = $1.lineno;
974 new->datatype = plpgsql_parse_datatype("integer");
975 new->isconst = false;
976 new->notnull = false;
977 new->default_val = NULL;
979 plpgsql_adddatum((PLpgSQL_datum *)new);
980 plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, new->varno,
983 plpgsql_add_initdatums(NULL);
989 fori_varname : T_VARIABLE
993 plpgsql_convert_ident(yytext, &name, 1);
994 /* name should be malloc'd for use as varname */
995 $$.name = strdup(name);
996 $$.lineno = yylineno;
1003 plpgsql_convert_ident(yytext, &name, 1);
1004 /* name should be malloc'd for use as varname */
1005 $$.name = strdup(name);
1006 $$.lineno = yylineno;
1016 if (tok == K_REVERSE)
1023 plpgsql_push_back_token(tok);
1026 $$.expr = plpgsql_read_expression(K_DOTDOT, "..");
1030 stmt_fors : opt_label K_FOR lno fors_target K_IN K_SELECT expr_until_loop loop_body
1032 PLpgSQL_stmt_fors *new;
1034 new = malloc(sizeof(PLpgSQL_stmt_fors));
1035 memset(new, 0, sizeof(PLpgSQL_stmt_fors));
1037 new->cmd_type = PLPGSQL_STMT_FORS;
1042 case PLPGSQL_DTYPE_REC:
1045 case PLPGSQL_DTYPE_ROW:
1046 new->row = (PLpgSQL_row *)$4;
1049 elog(ERROR, "unknown dtype %d in stmt_fors", $4->dtype);
1056 $$ = (PLpgSQL_stmt *)new;
1060 stmt_dynfors : opt_label K_FOR lno fors_target K_IN K_EXECUTE expr_until_loop loop_body
1062 PLpgSQL_stmt_dynfors *new;
1064 new = malloc(sizeof(PLpgSQL_stmt_dynfors));
1065 memset(new, 0, sizeof(PLpgSQL_stmt_dynfors));
1067 new->cmd_type = PLPGSQL_STMT_DYNFORS;
1072 case PLPGSQL_DTYPE_REC:
1075 case PLPGSQL_DTYPE_ROW:
1076 new->row = (PLpgSQL_row *)$4;
1079 elog(ERROR, "unknown dtype %d in stmt_dynfors", $4->dtype);
1086 $$ = (PLpgSQL_stmt *)new;
1090 fors_target : T_RECORD
1091 { $$ = yylval.rec; }
1094 $$ = (PLpgSQL_rec *)(yylval.row);
1098 stmt_select : K_SELECT lno
1100 $$ = make_select_stmt();
1105 stmt_exit : K_EXIT lno opt_exitlabel opt_exitcond
1107 PLpgSQL_stmt_exit *new;
1109 new = malloc(sizeof(PLpgSQL_stmt_exit));
1110 memset(new, 0, sizeof(PLpgSQL_stmt_exit));
1112 new->cmd_type = PLPGSQL_STMT_EXIT;
1117 $$ = (PLpgSQL_stmt *)new;
1121 stmt_return : K_RETURN lno
1123 PLpgSQL_stmt_return *new;
1124 PLpgSQL_expr *expr = NULL;
1127 new = malloc(sizeof(PLpgSQL_stmt_return));
1128 memset(new, 0, sizeof(PLpgSQL_stmt_return));
1130 if (plpgsql_curr_compile->fn_retistuple)
1132 new->retistuple = true;
1134 switch (tok = yylex())
1141 expr = make_tupret_expr(yylval.row);
1145 new->retrecno = yylval.rec->recno;
1150 yyerror("return type mismatch in function returning table row");
1154 yyerror("expected ';'");
1156 new->retistuple = false;
1157 expr = plpgsql_read_expression(';', ";");
1160 new->cmd_type = PLPGSQL_STMT_RETURN;
1164 $$ = (PLpgSQL_stmt *)new;
1168 stmt_raise : K_RAISE lno raise_level raise_msg raise_params ';'
1170 PLpgSQL_stmt_raise *new;
1172 new = malloc(sizeof(PLpgSQL_stmt_raise));
1174 new->cmd_type = PLPGSQL_STMT_RAISE;
1176 new->elog_level = $3;
1178 new->nparams = $5.nused;
1179 new->params = malloc(sizeof(int) * $5.nused);
1180 memcpy(new->params, $5.nums, sizeof(int) * $5.nused);
1182 $$ = (PLpgSQL_stmt *)new;
1184 | K_RAISE lno raise_level raise_msg ';'
1186 PLpgSQL_stmt_raise *new;
1188 new = malloc(sizeof(PLpgSQL_stmt_raise));
1190 new->cmd_type = PLPGSQL_STMT_RAISE;
1192 new->elog_level = $3;
1197 $$ = (PLpgSQL_stmt *)new;
1201 raise_msg : T_STRING
1203 $$ = strdup(yytext);
1207 raise_level : K_EXCEPTION
1233 raise_params : raise_params raise_param
1235 if ($1.nused == $1.nalloc)
1238 $1.nums = repalloc($1.nums, sizeof(int) * $1.nalloc);
1240 $1.nums[$1.nused++] = $2;
1242 $$.nalloc = $1.nalloc;
1243 $$.nused = $1.nused;
1250 $$.nums = palloc(sizeof(int) * $$.nalloc);
1255 raise_param : ',' T_VARIABLE
1257 $$ = yylval.variable->dno;
1261 loop_body : proc_sect K_END K_LOOP ';'
1265 stmt_execsql : execsql_start lno
1267 PLpgSQL_stmt_execsql *new;
1269 new = malloc(sizeof(PLpgSQL_stmt_execsql));
1270 new->cmd_type = PLPGSQL_STMT_EXECSQL;
1272 new->sqlstmt = read_sql_stmt($1);
1274 $$ = (PLpgSQL_stmt *)new;
1278 stmt_dynexecute : K_EXECUTE lno expr_until_semi
1280 PLpgSQL_stmt_dynexecute *new;
1282 new = malloc(sizeof(PLpgSQL_stmt_dynexecute));
1283 new->cmd_type = PLPGSQL_STMT_DYNEXECUTE;
1287 $$ = (PLpgSQL_stmt *)new;
1291 stmt_open : K_OPEN lno cursor_varptr
1293 PLpgSQL_stmt_open *new;
1296 new = malloc(sizeof(PLpgSQL_stmt_open));
1297 memset(new, 0, sizeof(PLpgSQL_stmt_open));
1299 new->cmd_type = PLPGSQL_STMT_OPEN;
1301 new->curvar = $3->varno;
1303 if ($3->cursor_explicit_expr == NULL)
1309 plpgsql_error_lineno = $2;
1310 elog(ERROR, "syntax error at \"%s\" - expected FOR to open a reference cursor", yytext);
1317 new->query = read_sql_stmt("SELECT ");
1321 new->dynquery = read_sql_stmt("SELECT ");
1325 plpgsql_error_lineno = $2;
1326 elog(ERROR, "syntax error at \"%s\"", yytext);
1332 if ($3->cursor_explicit_argrow >= 0)
1340 plpgsql_error_lineno = yylineno;
1341 elog(ERROR, "cursor %s has arguments",
1346 * Push back the '(', else read_sql_stmt
1347 * will complain about unbalanced parens.
1349 plpgsql_push_back_token(tok);
1351 new->argquery = read_sql_stmt("SELECT ");
1354 * Now remove the leading and trailing parens,
1355 * because we want "select 1, 2", not
1358 cp = new->argquery->query;
1360 if (strncmp(cp, "SELECT", 6) != 0)
1362 plpgsql_error_lineno = yylineno;
1363 elog(ERROR, "expected 'SELECT (', got '%s' (internal error)",
1364 new->argquery->query);
1367 while (*cp == ' ') /* could be more than 1 space here */
1371 plpgsql_error_lineno = yylineno;
1372 elog(ERROR, "expected 'SELECT (', got '%s' (internal error)",
1373 new->argquery->query);
1377 cp += strlen(cp) - 1;
1381 plpgsql_error_lineno = yylineno;
1382 elog(ERROR, "missing )");
1392 plpgsql_error_lineno = yylineno;
1393 elog(ERROR, "cursor %s has no arguments", $3->refname);
1398 plpgsql_error_lineno = yylineno;
1399 elog(ERROR, "syntax error at \"%s\"", yytext);
1404 $$ = (PLpgSQL_stmt *)new;
1408 stmt_fetch : K_FETCH lno cursor_variable K_INTO
1410 PLpgSQL_stmt_fetch *new;
1412 new = (PLpgSQL_stmt_fetch *)make_fetch_stmt();
1415 $$ = (PLpgSQL_stmt *)new;
1420 stmt_close : K_CLOSE lno cursor_variable ';'
1422 PLpgSQL_stmt_close *new;
1424 new = malloc(sizeof(PLpgSQL_stmt_close));
1425 new->cmd_type = PLPGSQL_STMT_CLOSE;
1429 $$ = (PLpgSQL_stmt *)new;
1433 cursor_varptr : T_VARIABLE
1435 if (yylval.variable->dtype != PLPGSQL_DTYPE_VAR)
1437 plpgsql_error_lineno = yylineno;
1438 elog(ERROR, "cursor variable must be a simple variable");
1440 if (((PLpgSQL_var *) yylval.variable)->datatype->typoid != REFCURSOROID)
1442 plpgsql_error_lineno = yylineno;
1443 elog(ERROR, "%s must be of type cursor or refcursor",
1444 ((PLpgSQL_var *) yylval.variable)->refname);
1446 $$ = (PLpgSQL_var *) yylval.variable;
1450 cursor_variable : T_VARIABLE
1452 if (yylval.variable->dtype != PLPGSQL_DTYPE_VAR)
1454 plpgsql_error_lineno = yylineno;
1455 elog(ERROR, "cursor variable must be a simple variable");
1457 if (((PLpgSQL_var *) yylval.variable)->datatype->typoid != REFCURSOROID)
1459 plpgsql_error_lineno = yylineno;
1460 elog(ERROR, "%s must be of type refcursor",
1461 ((PLpgSQL_var *) yylval.variable)->refname);
1463 $$ = yylval.variable->dno;
1467 execsql_start : T_WORD
1468 { $$ = strdup(yytext); }
1470 { $$ = strdup(yytext); }
1474 { $$ = plpgsql_read_expression(';', ";"); }
1478 { $$ = plpgsql_read_expression(K_THEN, "THEN"); }
1482 { $$ = plpgsql_read_expression(K_LOOP, "LOOP"); }
1487 plpgsql_ns_push(NULL);
1490 | '<' '<' opt_lblname '>' '>'
1492 plpgsql_ns_push($3);
1500 { $$ = strdup(yytext); }
1505 | K_WHEN expr_until_semi
1509 opt_lblname : T_WORD
1513 plpgsql_convert_ident(yytext, &name, 1);
1521 plpgsql_error_lineno = yylineno;
1530 plpgsql_read_expression(int until, const char *expected)
1532 return read_sql_construct(until, expected, true, "SELECT ");
1535 static PLpgSQL_expr *
1536 read_sql_stmt(const char *sqlstart)
1538 return read_sql_construct(';', ";", false, sqlstart);
1541 static PLpgSQL_expr *
1542 read_sql_construct(int until,
1543 const char *expected,
1545 const char *sqlstart)
1557 plpgsql_dstring_init(&ds);
1558 plpgsql_dstring_append(&ds, (char *) sqlstart);
1565 else if (tok == ')')
1569 elog(ERROR, "mismatched parentheses");
1571 else if (parenlevel == 0 && tok == until)
1574 * End of function definition is an error, and we don't expect to
1575 * hit a semicolon either (unless it's the until symbol, in which
1576 * case we should have fallen out above).
1578 if (tok == 0 || tok == ';')
1580 plpgsql_error_lineno = lno;
1581 if (parenlevel != 0)
1582 elog(ERROR, "mismatched parentheses");
1584 elog(ERROR, "missing %s at end of SQL expression",
1587 elog(ERROR, "missing %s at end of SQL statement",
1591 if (plpgsql_SpaceScanned)
1592 plpgsql_dstring_append(&ds, " ");
1596 params[nparams] = yylval.variable->dno;
1597 sprintf(buf, " $%d ", ++nparams);
1598 plpgsql_dstring_append(&ds, buf);
1602 plpgsql_dstring_append(&ds, yytext);
1607 expr = malloc(sizeof(PLpgSQL_expr) + sizeof(int) * nparams - sizeof(int));
1608 expr->dtype = PLPGSQL_DTYPE_EXPR;
1609 expr->query = strdup(plpgsql_dstring_get(&ds));
1611 expr->nparams = nparams;
1612 while(nparams-- > 0)
1613 expr->params[nparams] = params[nparams];
1614 plpgsql_dstring_free(&ds);
1619 static PLpgSQL_type *
1620 read_datatype(int tok)
1624 PLpgSQL_type *result;
1625 bool needspace = false;
1630 /* Often there will be a lookahead token, but if not, get one */
1636 /* lexer found word%TYPE and did its thing already */
1637 return yylval.dtype;
1640 plpgsql_dstring_init(&ds);
1646 plpgsql_error_lineno = lno;
1647 if (parenlevel != 0)
1648 elog(ERROR, "mismatched parentheses");
1649 elog(ERROR, "incomplete datatype declaration");
1651 /* Possible followers for datatype in a declaration */
1652 if (tok == K_NOT || tok == K_ASSIGN || tok == K_DEFAULT)
1654 /* Possible followers for datatype in a cursor_arg list */
1655 if ((tok == ',' || tok == ')') && parenlevel == 0)
1659 else if (tok == ')')
1662 plpgsql_dstring_append(&ds, " ");
1664 plpgsql_dstring_append(&ds, yytext);
1669 plpgsql_push_back_token(tok);
1671 plpgsql_error_lineno = lno; /* in case of error in parse_datatype */
1673 result = plpgsql_parse_datatype(plpgsql_dstring_get(&ds));
1675 plpgsql_dstring_free(&ds);
1681 static PLpgSQL_stmt *
1682 make_select_stmt(void)
1689 PLpgSQL_row *row = NULL;
1690 PLpgSQL_rec *rec = NULL;
1692 int have_nexttok = 0;
1695 plpgsql_dstring_init(&ds);
1696 plpgsql_dstring_append(&ds, "SELECT ");
1707 plpgsql_error_lineno = yylineno;
1708 elog(ERROR, "unexpected end of file");
1714 plpgsql_error_lineno = yylineno;
1715 elog(ERROR, "INTO specified more than once");
1733 char *fieldnames[1024];
1736 check_assignable(yylval.variable);
1737 fieldnames[0] = strdup(yytext);
1738 varnos[0] = yylval.variable->dno;
1740 while ((tok = yylex()) == ',')
1746 check_assignable(yylval.variable);
1747 fieldnames[nfields] = strdup(yytext);
1748 varnos[nfields++] = yylval.variable->dno;
1752 plpgsql_error_lineno = yylineno;
1753 elog(ERROR, "plpgsql: %s is not a variable",
1759 row = malloc(sizeof(PLpgSQL_row));
1760 row->dtype = PLPGSQL_DTYPE_ROW;
1761 row->refname = strdup("*internal*");
1762 row->lineno = yylineno;
1763 row->rowtypeclass = InvalidOid;
1764 row->nfields = nfields;
1765 row->fieldnames = malloc(sizeof(char *) * nfields);
1766 row->varnos = malloc(sizeof(int) * nfields);
1767 while (--nfields >= 0)
1769 row->fieldnames[nfields] = fieldnames[nfields];
1770 row->varnos[nfields] = varnos[nfields];
1773 plpgsql_adddatum((PLpgSQL_datum *)row);
1780 /* Treat the INTO as non-special */
1781 plpgsql_dstring_append(&ds, " INTO ");
1788 if (plpgsql_SpaceScanned)
1789 plpgsql_dstring_append(&ds, " ");
1793 params[nparams] = yylval.variable->dno;
1794 sprintf(buf, " $%d ", ++nparams);
1795 plpgsql_dstring_append(&ds, buf);
1799 plpgsql_dstring_append(&ds, yytext);
1804 expr = malloc(sizeof(PLpgSQL_expr) + sizeof(int) * nparams - sizeof(int));
1805 expr->dtype = PLPGSQL_DTYPE_EXPR;
1806 expr->query = strdup(plpgsql_dstring_get(&ds));
1808 expr->nparams = nparams;
1809 while(nparams-- > 0)
1810 expr->params[nparams] = params[nparams];
1811 plpgsql_dstring_free(&ds);
1815 PLpgSQL_stmt_select *select;
1817 select = malloc(sizeof(PLpgSQL_stmt_select));
1818 memset(select, 0, sizeof(PLpgSQL_stmt_select));
1819 select->cmd_type = PLPGSQL_STMT_SELECT;
1822 select->query = expr;
1824 return (PLpgSQL_stmt *)select;
1828 PLpgSQL_stmt_execsql *execsql;
1830 execsql = malloc(sizeof(PLpgSQL_stmt_execsql));
1831 execsql->cmd_type = PLPGSQL_STMT_EXECSQL;
1832 execsql->sqlstmt = expr;
1834 return (PLpgSQL_stmt *)execsql;
1839 static PLpgSQL_stmt *
1840 make_fetch_stmt(void)
1843 PLpgSQL_row *row = NULL;
1844 PLpgSQL_rec *rec = NULL;
1845 PLpgSQL_stmt_fetch *fetch;
1846 int have_nexttok = 0;
1848 /* We have already parsed everything through the INTO keyword */
1864 char *fieldnames[1024];
1867 check_assignable(yylval.variable);
1868 fieldnames[0] = strdup(yytext);
1869 varnos[0] = yylval.variable->dno;
1871 while ((tok = yylex()) == ',')
1877 check_assignable(yylval.variable);
1878 fieldnames[nfields] = strdup(yytext);
1879 varnos[nfields++] = yylval.variable->dno;
1883 plpgsql_error_lineno = yylineno;
1884 elog(ERROR, "plpgsql: %s is not a variable",
1890 row = malloc(sizeof(PLpgSQL_row));
1891 row->dtype = PLPGSQL_DTYPE_ROW;
1892 row->refname = strdup("*internal*");
1893 row->lineno = yylineno;
1894 row->rowtypeclass = InvalidOid;
1895 row->nfields = nfields;
1896 row->fieldnames = malloc(sizeof(char *) * nfields);
1897 row->varnos = malloc(sizeof(int) * nfields);
1898 while (--nfields >= 0)
1900 row->fieldnames[nfields] = fieldnames[nfields];
1901 row->varnos[nfields] = varnos[nfields];
1904 plpgsql_adddatum((PLpgSQL_datum *)row);
1909 plpgsql_error_lineno = yylineno;
1910 elog(ERROR, "syntax error at '%s'", yytext);
1918 plpgsql_error_lineno = yylineno;
1919 elog(ERROR, "syntax error at '%s'", yytext);
1922 fetch = malloc(sizeof(PLpgSQL_stmt_select));
1923 memset(fetch, 0, sizeof(PLpgSQL_stmt_fetch));
1924 fetch->cmd_type = PLPGSQL_STMT_FETCH;
1928 return (PLpgSQL_stmt *)fetch;
1932 static PLpgSQL_expr *
1933 make_tupret_expr(PLpgSQL_row *row)
1940 expr = malloc(sizeof(PLpgSQL_expr) + sizeof(int) * (row->nfields - 1));
1941 expr->dtype = PLPGSQL_DTYPE_EXPR;
1943 plpgsql_dstring_init(&ds);
1944 plpgsql_dstring_append(&ds, "SELECT ");
1946 for (i = 0; i < row->nfields; i++)
1948 sprintf(buf, "%s$%d", (i > 0) ? "," : "", i + 1);
1949 plpgsql_dstring_append(&ds, buf);
1950 expr->params[i] = row->varnos[i];
1953 expr->query = strdup(plpgsql_dstring_get(&ds));
1955 expr->plan_argtypes = NULL;
1956 expr->nparams = row->nfields;
1958 plpgsql_dstring_free(&ds);
1963 check_assignable(PLpgSQL_datum *datum)
1965 switch (datum->dtype)
1967 case PLPGSQL_DTYPE_VAR:
1968 if (((PLpgSQL_var *) datum)->isconst)
1970 plpgsql_error_lineno = yylineno;
1971 elog(ERROR, "%s is declared CONSTANT",
1972 ((PLpgSQL_var *) datum)->refname);
1975 case PLPGSQL_DTYPE_RECFIELD:
1976 /* always assignable? */
1978 case PLPGSQL_DTYPE_TRIGARG:
1979 plpgsql_error_lineno = yylineno;
1980 elog(ERROR, "cannot assign to tg_argv");
1983 elog(ERROR, "check_assignable: unexpected datum type");