2 /**********************************************************************
3 * gram.y - Parser for the PL/pgSQL
7 * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.42 2003/04/27 22:21:22 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_rightbracket
109 %type <expr> expr_until_then expr_until_loop
110 %type <expr> opt_exitcond
112 %type <ival> assign_var cursor_variable
113 %type <var> fori_var cursor_varptr decl_cursor_arg
114 %type <varname> fori_varname
115 %type <forilow> fori_lower
116 %type <rec> fors_target
118 %type <str> opt_lblname opt_label
119 %type <str> opt_exitlabel
120 %type <str> execsql_start
122 %type <stmts> proc_sect proc_stmts stmt_else loop_body
123 %type <stmt> proc_stmt pl_block
124 %type <stmt> stmt_assign stmt_if stmt_loop stmt_while stmt_exit
125 %type <stmt> stmt_return stmt_return_next stmt_raise stmt_execsql
126 %type <stmt> stmt_fori stmt_fors stmt_select stmt_perform
127 %type <stmt> stmt_dynexecute stmt_dynfors stmt_getdiag
128 %type <stmt> stmt_open stmt_fetch stmt_close
130 %type <intlist> raise_params
131 %type <ival> raise_level raise_param
132 %type <str> raise_msg
134 %type <dtlist> getdiag_list
135 %type <ival> getdiag_item getdiag_target
199 %token T_VARIABLE /* a VAR, RECFIELD, or TRIGARG */
212 pl_function : T_FUNCTION comp_optsect pl_block opt_semi
214 yylval.program = (PLpgSQL_stmt_block *)$3;
216 | T_TRIGGER comp_optsect pl_block opt_semi
218 yylval.program = (PLpgSQL_stmt_block *)$3;
226 comp_options : comp_options comp_option
230 comp_option : O_OPTION O_DUMP
232 plpgsql_DumpExecTree = 1;
240 pl_block : decl_sect K_BEGIN lno proc_sect K_END
242 PLpgSQL_stmt_block *new;
244 new = malloc(sizeof(PLpgSQL_stmt_block));
245 memset(new, 0, sizeof(PLpgSQL_stmt_block));
247 new->cmd_type = PLPGSQL_STMT_BLOCK;
249 new->label = $1.label;
250 new->n_initvars = $1.n_initvars;
251 new->initvarnos = $1.initvarnos;
256 $$ = (PLpgSQL_stmt *)new;
261 decl_sect : opt_label
263 plpgsql_ns_setlocal(false);
266 $$.initvarnos = NULL;
267 plpgsql_add_initdatums(NULL);
269 | opt_label decl_start
271 plpgsql_ns_setlocal(false);
274 $$.initvarnos = NULL;
275 plpgsql_add_initdatums(NULL);
277 | opt_label decl_start decl_stmts
279 plpgsql_ns_setlocal(false);
284 $$.n_initvars = plpgsql_add_initdatums(&($$.initvarnos));
288 decl_start : K_DECLARE
290 plpgsql_ns_setlocal(true);
294 decl_stmts : decl_stmts decl_stmt
300 decl_stmt : '<' '<' opt_lblname '>' '>'
308 decl_statement : decl_varname decl_const decl_datatype decl_notnull decl_defval
310 if (!OidIsValid($3->typrelid))
312 /* Ordinary scalar datatype */
315 var = malloc(sizeof(PLpgSQL_var));
316 memset(var, 0, sizeof(PLpgSQL_var));
318 var->dtype = PLPGSQL_DTYPE_VAR;
319 var->refname = $1.name;
320 var->lineno = $1.lineno;
325 var->default_val = $5;
327 plpgsql_adddatum((PLpgSQL_datum *)var);
328 plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR,
334 /* Composite type --- treat as rowtype */
337 row = build_rowtype($3->typrelid);
338 row->dtype = PLPGSQL_DTYPE_ROW;
339 row->refname = $1.name;
340 row->lineno = $1.lineno;
343 elog(ERROR, "Rowtype variable cannot be CONSTANT");
345 elog(ERROR, "Rowtype variable cannot be NOT NULL");
347 elog(ERROR, "Default value for rowtype variable is not supported");
349 plpgsql_adddatum((PLpgSQL_datum *)row);
350 plpgsql_ns_additem(PLPGSQL_NSTYPE_ROW,
356 | decl_varname K_RECORD ';'
360 var = malloc(sizeof(PLpgSQL_rec));
362 var->dtype = PLPGSQL_DTYPE_REC;
363 var->refname = $1.name;
364 var->lineno = $1.lineno;
366 plpgsql_adddatum((PLpgSQL_datum *)var);
367 plpgsql_ns_additem(PLPGSQL_NSTYPE_REC, var->recno,
370 | decl_varname decl_rowtype ';'
372 $2->dtype = PLPGSQL_DTYPE_ROW;
373 $2->refname = $1.name;
374 $2->lineno = $1.lineno;
376 plpgsql_adddatum((PLpgSQL_datum *)$2);
377 plpgsql_ns_additem(PLPGSQL_NSTYPE_ROW, $2->rowno,
380 | decl_varname K_ALIAS K_FOR decl_aliasitem ';'
382 plpgsql_ns_additem($4->itemtype,
383 $4->itemno, $1.name);
385 | K_RENAME decl_renname K_TO decl_renname ';'
387 plpgsql_ns_rename($2, $4);
389 | decl_varname K_CURSOR
390 { plpgsql_ns_push(NULL); }
391 decl_cursor_args decl_is_from K_SELECT decl_cursor_query
394 PLpgSQL_expr *curname_def;
399 /* pop local namespace for cursor args */
402 new = malloc(sizeof(PLpgSQL_var));
403 memset(new, 0, sizeof(PLpgSQL_var));
405 curname_def = malloc(sizeof(PLpgSQL_expr));
406 memset(curname_def, 0, sizeof(PLpgSQL_expr));
408 new->dtype = PLPGSQL_DTYPE_VAR;
409 new->refname = $1.name;
410 new->lineno = $1.lineno;
412 curname_def->dtype = PLPGSQL_DTYPE_EXPR;
413 strcpy(buf, "SELECT '");
415 cp2 = buf + strlen(buf);
418 if (*cp1 == '\\' || *cp1 == '\'')
422 strcpy(cp2, "'::refcursor");
423 curname_def->query = strdup(buf);
424 new->default_val = curname_def;
426 new->datatype = plpgsql_parse_datatype("refcursor");
428 new->cursor_explicit_expr = $7;
430 new->cursor_explicit_argrow = -1;
432 new->cursor_explicit_argrow = $4->rowno;
434 plpgsql_adddatum((PLpgSQL_datum *)new);
435 plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, new->varno,
444 plpgsql_ns_setlocal(false);
445 query = read_sql_stmt("SELECT ");
446 plpgsql_ns_setlocal(true);
456 | '(' decl_cursor_arglist ')'
458 /* Copy the temp arrays to malloc'd storage */
459 int nfields = $2->nfields;
463 ftmp = malloc(nfields * sizeof(char *));
464 vtmp = malloc(nfields * sizeof(int));
465 memcpy(ftmp, $2->fieldnames, nfields * sizeof(char *));
466 memcpy(vtmp, $2->varnos, nfields * sizeof(int));
468 pfree((char *)($2->fieldnames));
469 pfree((char *)($2->varnos));
471 $2->fieldnames = ftmp;
474 plpgsql_adddatum((PLpgSQL_datum *)$2);
480 decl_cursor_arglist : decl_cursor_arg
484 new = malloc(sizeof(PLpgSQL_row));
485 memset(new, 0, sizeof(PLpgSQL_row));
487 new->dtype = PLPGSQL_DTYPE_ROW;
488 new->refname = strdup("*internal*");
489 new->lineno = yylineno;
490 new->rowtypeclass = InvalidOid;
492 * We make temporary fieldnames/varnos arrays that
493 * are much bigger than necessary. We will resize
494 * them to just the needed size in the
495 * decl_cursor_args production.
497 new->fieldnames = palloc(1024 * sizeof(char *));
498 new->varnos = palloc(1024 * sizeof(int));
501 new->fieldnames[0] = $1->refname;
502 new->varnos[0] = $1->varno;
506 | decl_cursor_arglist ',' decl_cursor_arg
508 int i = $1->nfields++;
510 $1->fieldnames[i] = $3->refname;
511 $1->varnos[i] = $3->varno;
517 decl_cursor_arg : decl_varname decl_datatype
521 new = malloc(sizeof(PLpgSQL_var));
522 memset(new, 0, sizeof(PLpgSQL_var));
524 new->dtype = PLPGSQL_DTYPE_VAR;
525 new->refname = $1.name;
526 new->lineno = $1.lineno;
529 new->isconst = false;
530 new->notnull = false;
532 plpgsql_adddatum((PLpgSQL_datum *)new);
533 plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, new->varno,
540 decl_is_from : K_IS | /* Oracle */
543 decl_aliasitem : T_WORD
548 plpgsql_convert_ident(yytext, &name, 1);
550 yyerror("can only alias positional parameters");
552 plpgsql_ns_setlocal(false);
553 nsi = plpgsql_ns_lookup(name, NULL);
556 plpgsql_error_lineno = yylineno;
557 elog(ERROR, "function has no parameter %s", name);
560 plpgsql_ns_setlocal(true);
574 decl_varname : T_WORD
578 plpgsql_convert_ident(yytext, &name, 1);
579 /* name should be malloc'd for use as varname */
580 $$.name = strdup(name);
581 $$.lineno = yylineno;
586 decl_renname : T_WORD
590 plpgsql_convert_ident(yytext, &name, 1);
591 /* the result must be palloc'd, see plpgsql_ns_rename */
605 * If there's a lookahead token, read_datatype
608 $$ = read_datatype(yychar);
629 expr = malloc(sizeof(PLpgSQL_expr));
630 plpgsql_dstring_init(&ds);
631 plpgsql_dstring_append(&ds, "SELECT ");
633 expr->dtype = PLPGSQL_DTYPE_EXPR;
641 yyerror("unexpected end of file");
644 yyerror("expected ; after NULL");
647 plpgsql_dstring_free(&ds);
653 plpgsql_dstring_append(&ds, yytext);
654 while ((tok = yylex()) != ';')
657 yyerror("unterminated default value");
659 if (plpgsql_SpaceScanned)
660 plpgsql_dstring_append(&ds, " ");
661 plpgsql_dstring_append(&ds, yytext);
663 expr->query = strdup(plpgsql_dstring_get(&ds));
664 plpgsql_dstring_free(&ds);
672 decl_defkey : K_ASSIGN
680 new = malloc(sizeof(PLpgSQL_stmts));
681 memset(new, 0, sizeof(PLpgSQL_stmts));
688 proc_stmts : proc_stmts proc_stmt
690 if ($1->stmts_used == $1->stmts_alloc)
692 $1->stmts_alloc *= 2;
693 $1->stmts = realloc($1->stmts, sizeof(PLpgSQL_stmt *) * $1->stmts_alloc);
695 $1->stmts[$1->stmts_used++] = (struct PLpgSQL_stmt *)$2;
703 new = malloc(sizeof(PLpgSQL_stmts));
704 memset(new, 0, sizeof(PLpgSQL_stmts));
706 new->stmts_alloc = 64;
708 new->stmts = malloc(sizeof(PLpgSQL_stmt *) * new->stmts_alloc);
709 new->stmts[0] = (struct PLpgSQL_stmt *)$1;
716 proc_stmt : pl_block ';'
758 stmt_perform : K_PERFORM lno expr_until_semi
760 PLpgSQL_stmt_perform *new;
762 new = malloc(sizeof(PLpgSQL_stmt_perform));
763 memset(new, 0, sizeof(PLpgSQL_stmt_perform));
765 new->cmd_type = PLPGSQL_STMT_PERFORM;
769 $$ = (PLpgSQL_stmt *)new;
773 stmt_assign : assign_var lno K_ASSIGN expr_until_semi
775 PLpgSQL_stmt_assign *new;
777 new = malloc(sizeof(PLpgSQL_stmt_assign));
778 memset(new, 0, sizeof(PLpgSQL_stmt_assign));
780 new->cmd_type = PLPGSQL_STMT_ASSIGN;
785 $$ = (PLpgSQL_stmt *)new;
789 stmt_getdiag : K_GET K_DIAGNOSTICS lno getdiag_list ';'
791 PLpgSQL_stmt_getdiag *new;
793 new = malloc(sizeof(PLpgSQL_stmt_getdiag));
794 memset(new, 0, sizeof(PLpgSQL_stmt_getdiag));
796 new->cmd_type = PLPGSQL_STMT_GETDIAG;
798 new->ndtitems = $4.nused;
799 new->dtitems = malloc(sizeof(PLpgSQL_diag_item) * $4.nused);
800 memcpy(new->dtitems, $4.dtitems, sizeof(PLpgSQL_diag_item) * $4.nused);
802 $$ = (PLpgSQL_stmt *)new;
806 getdiag_list : getdiag_list ',' getdiag_target K_ASSIGN getdiag_item
808 if ($1.nused == $1.nalloc)
811 $1.dtitems = repalloc($1.dtitems, sizeof(PLpgSQL_diag_item) * $1.nalloc);
813 $1.dtitems[$1.nused].target = $3;
814 $1.dtitems[$1.nused].item = $5;
817 $$.nalloc = $1.nalloc;
819 $$.dtitems = $1.dtitems;
821 | getdiag_target K_ASSIGN getdiag_item
825 $$.dtitems = palloc(sizeof(PLpgSQL_diag_item) * $$.nalloc);
826 $$.dtitems[0].target = $1;
827 $$.dtitems[0].item = $3;
831 getdiag_item : K_ROW_COUNT
833 $$ = PLPGSQL_GETDIAG_ROW_COUNT;
837 $$ = PLPGSQL_GETDIAG_RESULT_OID;
841 getdiag_target : T_VARIABLE
843 check_assignable(yylval.variable);
844 $$ = yylval.variable->dno;
849 assign_var : T_VARIABLE
851 check_assignable(yylval.variable);
852 $$ = yylval.variable->dno;
854 | assign_var '[' expr_until_rightbracket
856 PLpgSQL_arrayelem *new;
858 new = malloc(sizeof(PLpgSQL_arrayelem));
859 memset(new, 0, sizeof(PLpgSQL_arrayelem));
861 new->dtype = PLPGSQL_DTYPE_ARRAYELEM;
863 new->arrayparentno = $1;
865 plpgsql_adddatum((PLpgSQL_datum *)new);
871 stmt_if : K_IF lno expr_until_then proc_sect stmt_else K_END K_IF ';'
873 PLpgSQL_stmt_if *new;
875 new = malloc(sizeof(PLpgSQL_stmt_if));
876 memset(new, 0, sizeof(PLpgSQL_stmt_if));
878 new->cmd_type = PLPGSQL_STMT_IF;
882 new->false_body = $5;
884 $$ = (PLpgSQL_stmt *)new;
892 new = malloc(sizeof(PLpgSQL_stmts));
893 memset(new, 0, sizeof(PLpgSQL_stmts));
896 | K_ELSIF lno expr_until_then proc_sect stmt_else
899 * Translate the structure: into:
901 * IF c1 THEN IF c1 THEN
914 PLpgSQL_stmt_if *new_if;
916 /* first create a new if-statement */
917 new_if = malloc(sizeof(PLpgSQL_stmt_if));
918 memset(new_if, 0, sizeof(PLpgSQL_stmt_if));
920 new_if->cmd_type = PLPGSQL_STMT_IF;
923 new_if->true_body = $4;
924 new_if->false_body = $5;
926 /* this is a 'container' for the if-statement */
927 new = malloc(sizeof(PLpgSQL_stmts));
928 memset(new, 0, sizeof(PLpgSQL_stmts));
930 new->stmts_alloc = 64;
932 new->stmts = malloc(sizeof(PLpgSQL_stmt *) * new->stmts_alloc);
933 new->stmts[0] = (struct PLpgSQL_stmt *)new_if;
945 stmt_loop : opt_label K_LOOP lno loop_body
947 PLpgSQL_stmt_loop *new;
949 new = malloc(sizeof(PLpgSQL_stmt_loop));
950 memset(new, 0, sizeof(PLpgSQL_stmt_loop));
952 new->cmd_type = PLPGSQL_STMT_LOOP;
959 $$ = (PLpgSQL_stmt *)new;
963 stmt_while : opt_label K_WHILE lno expr_until_loop loop_body
965 PLpgSQL_stmt_while *new;
967 new = malloc(sizeof(PLpgSQL_stmt_while));
968 memset(new, 0, sizeof(PLpgSQL_stmt_while));
970 new->cmd_type = PLPGSQL_STMT_WHILE;
978 $$ = (PLpgSQL_stmt *)new;
982 stmt_fori : opt_label K_FOR lno fori_var K_IN fori_lower expr_until_loop loop_body
984 PLpgSQL_stmt_fori *new;
986 new = malloc(sizeof(PLpgSQL_stmt_fori));
987 memset(new, 0, sizeof(PLpgSQL_stmt_fori));
989 new->cmd_type = PLPGSQL_STMT_FORI;
993 new->reverse = $6.reverse;
994 new->lower = $6.expr;
1000 $$ = (PLpgSQL_stmt *)new;
1004 fori_var : fori_varname
1008 new = malloc(sizeof(PLpgSQL_var));
1009 memset(new, 0, sizeof(PLpgSQL_var));
1011 new->dtype = PLPGSQL_DTYPE_VAR;
1012 new->refname = $1.name;
1013 new->lineno = $1.lineno;
1015 new->datatype = plpgsql_parse_datatype("integer");
1016 new->isconst = false;
1017 new->notnull = false;
1018 new->default_val = NULL;
1020 plpgsql_adddatum((PLpgSQL_datum *)new);
1021 plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, new->varno,
1024 plpgsql_add_initdatums(NULL);
1030 fori_varname : T_VARIABLE
1034 plpgsql_convert_ident(yytext, &name, 1);
1035 /* name should be malloc'd for use as varname */
1036 $$.name = strdup(name);
1037 $$.lineno = yylineno;
1044 plpgsql_convert_ident(yytext, &name, 1);
1045 /* name should be malloc'd for use as varname */
1046 $$.name = strdup(name);
1047 $$.lineno = yylineno;
1057 if (tok == K_REVERSE)
1064 plpgsql_push_back_token(tok);
1067 $$.expr = plpgsql_read_expression(K_DOTDOT, "..");
1071 stmt_fors : opt_label K_FOR lno fors_target K_IN K_SELECT expr_until_loop loop_body
1073 PLpgSQL_stmt_fors *new;
1075 new = malloc(sizeof(PLpgSQL_stmt_fors));
1076 memset(new, 0, sizeof(PLpgSQL_stmt_fors));
1078 new->cmd_type = PLPGSQL_STMT_FORS;
1083 case PLPGSQL_DTYPE_REC:
1086 case PLPGSQL_DTYPE_ROW:
1087 new->row = (PLpgSQL_row *)$4;
1090 elog(ERROR, "unknown dtype %d in stmt_fors", $4->dtype);
1097 $$ = (PLpgSQL_stmt *)new;
1101 stmt_dynfors : opt_label K_FOR lno fors_target K_IN K_EXECUTE expr_until_loop loop_body
1103 PLpgSQL_stmt_dynfors *new;
1105 new = malloc(sizeof(PLpgSQL_stmt_dynfors));
1106 memset(new, 0, sizeof(PLpgSQL_stmt_dynfors));
1108 new->cmd_type = PLPGSQL_STMT_DYNFORS;
1113 case PLPGSQL_DTYPE_REC:
1116 case PLPGSQL_DTYPE_ROW:
1117 new->row = (PLpgSQL_row *)$4;
1120 elog(ERROR, "unknown dtype %d in stmt_dynfors", $4->dtype);
1127 $$ = (PLpgSQL_stmt *)new;
1131 fors_target : T_RECORD
1132 { $$ = yylval.rec; }
1135 $$ = (PLpgSQL_rec *)(yylval.row);
1139 stmt_select : K_SELECT lno
1141 $$ = make_select_stmt();
1146 stmt_exit : K_EXIT lno opt_exitlabel opt_exitcond
1148 PLpgSQL_stmt_exit *new;
1150 new = malloc(sizeof(PLpgSQL_stmt_exit));
1151 memset(new, 0, sizeof(PLpgSQL_stmt_exit));
1153 new->cmd_type = PLPGSQL_STMT_EXIT;
1158 $$ = (PLpgSQL_stmt *)new;
1162 stmt_return : K_RETURN lno
1164 PLpgSQL_stmt_return *new;
1166 new = malloc(sizeof(PLpgSQL_stmt_return));
1167 memset(new, 0, sizeof(PLpgSQL_stmt_return));
1169 if (plpgsql_curr_compile->fn_retistuple &&
1170 !plpgsql_curr_compile->fn_retset)
1180 new->expr = make_tupret_expr(yylval.row);
1184 new->retrecno = yylval.rec->recno;
1189 yyerror("return type mismatch in function returning tuple");
1193 yyerror("expected ';'");
1196 new->expr = plpgsql_read_expression(';', ";");
1198 new->cmd_type = PLPGSQL_STMT_RETURN;
1201 $$ = (PLpgSQL_stmt *)new;
1205 stmt_return_next: K_RETURN_NEXT lno
1207 PLpgSQL_stmt_return_next *new;
1209 new = malloc(sizeof(PLpgSQL_stmt_return_next));
1210 memset(new, 0, sizeof(PLpgSQL_stmt_return_next));
1212 new->cmd_type = PLPGSQL_STMT_RETURN_NEXT;
1215 if (plpgsql_curr_compile->fn_retistuple)
1219 if (tok == T_RECORD)
1220 new->rec = yylval.rec;
1221 else if (tok == T_ROW)
1222 new->row = yylval.row;
1224 yyerror("Incorrect argument to RETURN NEXT");
1227 yyerror("Expected ';'");
1230 new->expr = plpgsql_read_expression(';', ";");
1232 $$ = (PLpgSQL_stmt *)new;
1236 stmt_raise : K_RAISE lno raise_level raise_msg raise_params ';'
1238 PLpgSQL_stmt_raise *new;
1240 new = malloc(sizeof(PLpgSQL_stmt_raise));
1242 new->cmd_type = PLPGSQL_STMT_RAISE;
1244 new->elog_level = $3;
1246 new->nparams = $5.nused;
1247 new->params = malloc(sizeof(int) * $5.nused);
1248 memcpy(new->params, $5.nums, sizeof(int) * $5.nused);
1250 $$ = (PLpgSQL_stmt *)new;
1252 | K_RAISE lno raise_level raise_msg ';'
1254 PLpgSQL_stmt_raise *new;
1256 new = malloc(sizeof(PLpgSQL_stmt_raise));
1258 new->cmd_type = PLPGSQL_STMT_RAISE;
1260 new->elog_level = $3;
1265 $$ = (PLpgSQL_stmt *)new;
1269 raise_msg : T_STRING
1271 $$ = strdup(yytext);
1275 raise_level : K_EXCEPTION
1301 raise_params : raise_params raise_param
1303 if ($1.nused == $1.nalloc)
1306 $1.nums = repalloc($1.nums, sizeof(int) * $1.nalloc);
1308 $1.nums[$1.nused++] = $2;
1310 $$.nalloc = $1.nalloc;
1311 $$.nused = $1.nused;
1318 $$.nums = palloc(sizeof(int) * $$.nalloc);
1323 raise_param : ',' T_VARIABLE
1325 $$ = yylval.variable->dno;
1329 loop_body : proc_sect K_END K_LOOP ';'
1333 stmt_execsql : execsql_start lno
1335 PLpgSQL_stmt_execsql *new;
1337 new = malloc(sizeof(PLpgSQL_stmt_execsql));
1338 new->cmd_type = PLPGSQL_STMT_EXECSQL;
1340 new->sqlstmt = read_sql_stmt($1);
1342 $$ = (PLpgSQL_stmt *)new;
1346 stmt_dynexecute : K_EXECUTE lno expr_until_semi
1348 PLpgSQL_stmt_dynexecute *new;
1350 new = malloc(sizeof(PLpgSQL_stmt_dynexecute));
1351 new->cmd_type = PLPGSQL_STMT_DYNEXECUTE;
1355 $$ = (PLpgSQL_stmt *)new;
1359 stmt_open : K_OPEN lno cursor_varptr
1361 PLpgSQL_stmt_open *new;
1364 new = malloc(sizeof(PLpgSQL_stmt_open));
1365 memset(new, 0, sizeof(PLpgSQL_stmt_open));
1367 new->cmd_type = PLPGSQL_STMT_OPEN;
1369 new->curvar = $3->varno;
1371 if ($3->cursor_explicit_expr == NULL)
1377 plpgsql_error_lineno = $2;
1378 elog(ERROR, "syntax error at \"%s\" - expected FOR to open a reference cursor", yytext);
1385 new->query = read_sql_stmt("SELECT ");
1389 new->dynquery = read_sql_stmt("SELECT ");
1393 plpgsql_error_lineno = $2;
1394 elog(ERROR, "syntax error at \"%s\"", yytext);
1400 if ($3->cursor_explicit_argrow >= 0)
1408 plpgsql_error_lineno = yylineno;
1409 elog(ERROR, "cursor %s has arguments",
1414 * Push back the '(', else read_sql_stmt
1415 * will complain about unbalanced parens.
1417 plpgsql_push_back_token(tok);
1419 new->argquery = read_sql_stmt("SELECT ");
1422 * Now remove the leading and trailing parens,
1423 * because we want "select 1, 2", not
1426 cp = new->argquery->query;
1428 if (strncmp(cp, "SELECT", 6) != 0)
1430 plpgsql_error_lineno = yylineno;
1431 elog(ERROR, "expected 'SELECT (', got '%s' (internal error)",
1432 new->argquery->query);
1435 while (*cp == ' ') /* could be more than 1 space here */
1439 plpgsql_error_lineno = yylineno;
1440 elog(ERROR, "expected 'SELECT (', got '%s' (internal error)",
1441 new->argquery->query);
1445 cp += strlen(cp) - 1;
1448 yyerror("missing )");
1457 plpgsql_error_lineno = yylineno;
1458 elog(ERROR, "cursor %s has no arguments", $3->refname);
1463 plpgsql_error_lineno = yylineno;
1464 elog(ERROR, "syntax error at \"%s\"", yytext);
1469 $$ = (PLpgSQL_stmt *)new;
1473 stmt_fetch : K_FETCH lno cursor_variable K_INTO
1475 PLpgSQL_stmt_fetch *new;
1477 new = (PLpgSQL_stmt_fetch *)make_fetch_stmt();
1480 $$ = (PLpgSQL_stmt *)new;
1485 stmt_close : K_CLOSE lno cursor_variable ';'
1487 PLpgSQL_stmt_close *new;
1489 new = malloc(sizeof(PLpgSQL_stmt_close));
1490 new->cmd_type = PLPGSQL_STMT_CLOSE;
1494 $$ = (PLpgSQL_stmt *)new;
1498 cursor_varptr : T_VARIABLE
1500 if (yylval.variable->dtype != PLPGSQL_DTYPE_VAR)
1501 yyerror("cursor variable must be a simple variable");
1503 if (((PLpgSQL_var *) yylval.variable)->datatype->typoid != REFCURSOROID)
1505 plpgsql_error_lineno = yylineno;
1506 elog(ERROR, "%s must be of type cursor or refcursor",
1507 ((PLpgSQL_var *) yylval.variable)->refname);
1509 $$ = (PLpgSQL_var *) yylval.variable;
1513 cursor_variable : T_VARIABLE
1515 if (yylval.variable->dtype != PLPGSQL_DTYPE_VAR)
1516 yyerror("cursor variable must be a simple variable");
1518 if (((PLpgSQL_var *) yylval.variable)->datatype->typoid != REFCURSOROID)
1520 plpgsql_error_lineno = yylineno;
1521 elog(ERROR, "%s must be of type refcursor",
1522 ((PLpgSQL_var *) yylval.variable)->refname);
1524 $$ = yylval.variable->dno;
1528 execsql_start : T_WORD
1529 { $$ = strdup(yytext); }
1531 { $$ = strdup(yytext); }
1535 { $$ = plpgsql_read_expression(';', ";"); }
1538 expr_until_rightbracket :
1539 { $$ = plpgsql_read_expression(']', "]"); }
1543 { $$ = plpgsql_read_expression(K_THEN, "THEN"); }
1547 { $$ = plpgsql_read_expression(K_LOOP, "LOOP"); }
1552 plpgsql_ns_push(NULL);
1555 | '<' '<' opt_lblname '>' '>'
1557 plpgsql_ns_push($3);
1565 { $$ = strdup(yytext); }
1570 | K_WHEN expr_until_semi
1574 opt_lblname : T_WORD
1578 plpgsql_convert_ident(yytext, &name, 1);
1586 plpgsql_error_lineno = yylineno;
1595 plpgsql_read_expression(int until, const char *expected)
1597 return read_sql_construct(until, expected, true, "SELECT ");
1600 static PLpgSQL_expr *
1601 read_sql_stmt(const char *sqlstart)
1603 return read_sql_construct(';', ";", false, sqlstart);
1606 static PLpgSQL_expr *
1607 read_sql_construct(int until,
1608 const char *expected,
1610 const char *sqlstart)
1622 plpgsql_dstring_init(&ds);
1623 plpgsql_dstring_append(&ds, (char *) sqlstart);
1628 if (tok == until && parenlevel == 0)
1630 if (tok == '(' || tok == '[')
1632 else if (tok == ')' || tok == ']')
1636 elog(ERROR, "mismatched parentheses");
1639 * End of function definition is an error, and we don't expect to
1640 * hit a semicolon either (unless it's the until symbol, in which
1641 * case we should have fallen out above).
1643 if (tok == 0 || tok == ';')
1645 plpgsql_error_lineno = lno;
1646 if (parenlevel != 0)
1647 elog(ERROR, "mismatched parentheses");
1649 elog(ERROR, "missing %s at end of SQL expression",
1652 elog(ERROR, "missing %s at end of SQL statement",
1656 if (plpgsql_SpaceScanned)
1657 plpgsql_dstring_append(&ds, " ");
1661 params[nparams] = yylval.variable->dno;
1662 snprintf(buf, sizeof(buf), " $%d ", ++nparams);
1663 plpgsql_dstring_append(&ds, buf);
1667 plpgsql_dstring_append(&ds, yytext);
1672 expr = malloc(sizeof(PLpgSQL_expr) + sizeof(int) * nparams - sizeof(int));
1673 expr->dtype = PLPGSQL_DTYPE_EXPR;
1674 expr->query = strdup(plpgsql_dstring_get(&ds));
1676 expr->nparams = nparams;
1677 while(nparams-- > 0)
1678 expr->params[nparams] = params[nparams];
1679 plpgsql_dstring_free(&ds);
1684 static PLpgSQL_type *
1685 read_datatype(int tok)
1689 PLpgSQL_type *result;
1690 bool needspace = false;
1695 /* Often there will be a lookahead token, but if not, get one */
1701 /* lexer found word%TYPE and did its thing already */
1702 return yylval.dtype;
1705 plpgsql_dstring_init(&ds);
1711 plpgsql_error_lineno = lno;
1712 if (parenlevel != 0)
1713 elog(ERROR, "mismatched parentheses");
1714 elog(ERROR, "incomplete datatype declaration");
1716 /* Possible followers for datatype in a declaration */
1717 if (tok == K_NOT || tok == K_ASSIGN || tok == K_DEFAULT)
1719 /* Possible followers for datatype in a cursor_arg list */
1720 if ((tok == ',' || tok == ')') && parenlevel == 0)
1724 else if (tok == ')')
1727 plpgsql_dstring_append(&ds, " ");
1729 plpgsql_dstring_append(&ds, yytext);
1734 plpgsql_push_back_token(tok);
1736 plpgsql_error_lineno = lno; /* in case of error in parse_datatype */
1738 result = plpgsql_parse_datatype(plpgsql_dstring_get(&ds));
1740 plpgsql_dstring_free(&ds);
1746 static PLpgSQL_stmt *
1747 make_select_stmt(void)
1754 PLpgSQL_row *row = NULL;
1755 PLpgSQL_rec *rec = NULL;
1757 int have_nexttok = 0;
1760 plpgsql_dstring_init(&ds);
1761 plpgsql_dstring_append(&ds, "SELECT ");
1772 plpgsql_error_lineno = yylineno;
1773 elog(ERROR, "unexpected end of file");
1779 plpgsql_error_lineno = yylineno;
1780 elog(ERROR, "INTO specified more than once");
1798 char *fieldnames[1024];
1801 check_assignable(yylval.variable);
1802 fieldnames[0] = strdup(yytext);
1803 varnos[0] = yylval.variable->dno;
1805 while ((tok = yylex()) == ',')
1811 check_assignable(yylval.variable);
1812 fieldnames[nfields] = strdup(yytext);
1813 varnos[nfields++] = yylval.variable->dno;
1817 plpgsql_error_lineno = yylineno;
1818 elog(ERROR, "plpgsql: %s is not a variable",
1824 row = malloc(sizeof(PLpgSQL_row));
1825 row->dtype = PLPGSQL_DTYPE_ROW;
1826 row->refname = strdup("*internal*");
1827 row->lineno = yylineno;
1828 row->rowtypeclass = InvalidOid;
1829 row->nfields = nfields;
1830 row->fieldnames = malloc(sizeof(char *) * nfields);
1831 row->varnos = malloc(sizeof(int) * nfields);
1832 while (--nfields >= 0)
1834 row->fieldnames[nfields] = fieldnames[nfields];
1835 row->varnos[nfields] = varnos[nfields];
1838 plpgsql_adddatum((PLpgSQL_datum *)row);
1845 /* Treat the INTO as non-special */
1846 plpgsql_dstring_append(&ds, " INTO ");
1853 if (plpgsql_SpaceScanned)
1854 plpgsql_dstring_append(&ds, " ");
1858 params[nparams] = yylval.variable->dno;
1859 snprintf(buf, sizeof(buf), " $%d ", ++nparams);
1860 plpgsql_dstring_append(&ds, buf);
1864 plpgsql_dstring_append(&ds, yytext);
1869 expr = malloc(sizeof(PLpgSQL_expr) + sizeof(int) * nparams - sizeof(int));
1870 expr->dtype = PLPGSQL_DTYPE_EXPR;
1871 expr->query = strdup(plpgsql_dstring_get(&ds));
1873 expr->nparams = nparams;
1874 while(nparams-- > 0)
1875 expr->params[nparams] = params[nparams];
1876 plpgsql_dstring_free(&ds);
1880 PLpgSQL_stmt_select *select;
1882 select = malloc(sizeof(PLpgSQL_stmt_select));
1883 memset(select, 0, sizeof(PLpgSQL_stmt_select));
1884 select->cmd_type = PLPGSQL_STMT_SELECT;
1887 select->query = expr;
1889 return (PLpgSQL_stmt *)select;
1893 PLpgSQL_stmt_execsql *execsql;
1895 execsql = malloc(sizeof(PLpgSQL_stmt_execsql));
1896 execsql->cmd_type = PLPGSQL_STMT_EXECSQL;
1897 execsql->sqlstmt = expr;
1899 return (PLpgSQL_stmt *)execsql;
1904 static PLpgSQL_stmt *
1905 make_fetch_stmt(void)
1908 PLpgSQL_row *row = NULL;
1909 PLpgSQL_rec *rec = NULL;
1910 PLpgSQL_stmt_fetch *fetch;
1911 int have_nexttok = 0;
1913 /* We have already parsed everything through the INTO keyword */
1929 char *fieldnames[1024];
1932 check_assignable(yylval.variable);
1933 fieldnames[0] = strdup(yytext);
1934 varnos[0] = yylval.variable->dno;
1936 while ((tok = yylex()) == ',')
1942 check_assignable(yylval.variable);
1943 fieldnames[nfields] = strdup(yytext);
1944 varnos[nfields++] = yylval.variable->dno;
1948 plpgsql_error_lineno = yylineno;
1949 elog(ERROR, "plpgsql: %s is not a variable",
1955 row = malloc(sizeof(PLpgSQL_row));
1956 row->dtype = PLPGSQL_DTYPE_ROW;
1957 row->refname = strdup("*internal*");
1958 row->lineno = yylineno;
1959 row->rowtypeclass = InvalidOid;
1960 row->nfields = nfields;
1961 row->fieldnames = malloc(sizeof(char *) * nfields);
1962 row->varnos = malloc(sizeof(int) * nfields);
1963 while (--nfields >= 0)
1965 row->fieldnames[nfields] = fieldnames[nfields];
1966 row->varnos[nfields] = varnos[nfields];
1969 plpgsql_adddatum((PLpgSQL_datum *)row);
1974 yyerror("syntax error");
1981 yyerror("syntax error");
1983 fetch = malloc(sizeof(PLpgSQL_stmt_select));
1984 memset(fetch, 0, sizeof(PLpgSQL_stmt_fetch));
1985 fetch->cmd_type = PLPGSQL_STMT_FETCH;
1989 return (PLpgSQL_stmt *)fetch;
1993 static PLpgSQL_expr *
1994 make_tupret_expr(PLpgSQL_row *row)
2001 expr = malloc(sizeof(PLpgSQL_expr) + sizeof(int) * (row->nfields - 1));
2002 expr->dtype = PLPGSQL_DTYPE_EXPR;
2004 plpgsql_dstring_init(&ds);
2005 plpgsql_dstring_append(&ds, "SELECT ");
2007 for (i = 0; i < row->nfields; i++)
2009 sprintf(buf, "%s$%d", (i > 0) ? "," : "", i + 1);
2010 plpgsql_dstring_append(&ds, buf);
2011 expr->params[i] = row->varnos[i];
2014 expr->query = strdup(plpgsql_dstring_get(&ds));
2016 expr->plan_argtypes = NULL;
2017 expr->nparams = row->nfields;
2019 plpgsql_dstring_free(&ds);
2024 check_assignable(PLpgSQL_datum *datum)
2026 switch (datum->dtype)
2028 case PLPGSQL_DTYPE_VAR:
2029 if (((PLpgSQL_var *) datum)->isconst)
2031 plpgsql_error_lineno = yylineno;
2032 elog(ERROR, "%s is declared CONSTANT",
2033 ((PLpgSQL_var *) datum)->refname);
2036 case PLPGSQL_DTYPE_RECFIELD:
2037 /* always assignable? */
2039 case PLPGSQL_DTYPE_ARRAYELEM:
2040 /* always assignable? */
2042 case PLPGSQL_DTYPE_TRIGARG:
2043 yyerror("cannot assign to tg_argv");
2046 yyerror("check_assignable: unexpected datum type");
2051 #include "pl_scan.c"