2 /**********************************************************************
3 * gram.y - Parser for the PL/pgSQL
7 * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.3 1999/03/21 01:07:07 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 **********************************************************************/
43 extern int yylineno; /* not always declared by lexer... */
47 static PLpgSQL_expr *read_sqlstmt(int until, char *s, char *sqlstart);
48 static PLpgSQL_stmt *make_select_stmt(void);
49 static PLpgSQL_expr *make_tupret_expr(PLpgSQL_row *row);
78 PLpgSQL_recfield *recfield;
79 PLpgSQL_trigarg *trigarg;
83 PLpgSQL_stmt_block *program;
84 PLpgSQL_nsitem *nsitem;
87 %type <declhdr> decl_sect
88 %type <varname> decl_varname
89 %type <str> decl_renname
90 %type <ival> decl_const, decl_notnull, decl_atttypmod, decl_atttypmodval
91 %type <expr> decl_defval
92 %type <dtype> decl_datatype, decl_dtypename
93 %type <row> decl_rowtype
94 %type <nsitem> decl_aliasitem
95 %type <str> decl_stmts, decl_stmt
97 %type <expr> expr_until_semi, expr_until_then, expr_until_loop
98 %type <expr> opt_exitcond
100 %type <ival> assign_var
102 %type <varname> fori_varname
103 %type <forilow> fori_lower
104 %type <rec> fors_target
106 %type <str> opt_lblname, opt_label
107 %type <str> opt_exitlabel
108 %type <str> execsql_start
110 %type <stmts> proc_sect, proc_stmts, stmt_else, loop_body
111 %type <stmt> proc_stmt, pl_block
112 %type <stmt> stmt_assign, stmt_if, stmt_loop, stmt_while, stmt_exit
113 %type <stmt> stmt_return, stmt_raise, stmt_execsql, stmt_fori
114 %type <stmt> stmt_fors, stmt_select, stmt_perform
116 %type <dtlist> raise_params
117 %type <ival> raise_level, raise_param
118 %type <str> raise_msg
185 pl_function : T_FUNCTION comp_optsect pl_block
187 yylval.program = (PLpgSQL_stmt_block *)$3;
189 | T_TRIGGER comp_optsect pl_block
191 yylval.program = (PLpgSQL_stmt_block *)$3;
199 comp_options : comp_options comp_option
203 comp_option : O_OPTION O_DUMP
205 plpgsql_DumpExecTree = 1;
209 pl_block : decl_sect K_BEGIN lno proc_sect K_END ';'
211 PLpgSQL_stmt_block *new;
213 new = malloc(sizeof(PLpgSQL_stmt_block));
214 memset(new, 0, sizeof(PLpgSQL_stmt_block));
216 new->cmd_type = PLPGSQL_STMT_BLOCK;
218 new->label = $1.label;
219 new->n_initvars = $1.n_initvars;
220 new->initvarnos = $1.initvarnos;
225 $$ = (PLpgSQL_stmt *)new;
230 decl_sect : opt_label
232 plpgsql_ns_setlocal(false);
235 $$.initvarnos = NULL;
236 plpgsql_add_initdatums(NULL);
238 | opt_label decl_start
240 plpgsql_ns_setlocal(false);
243 $$.initvarnos = NULL;
244 plpgsql_add_initdatums(NULL);
246 | opt_label decl_start decl_stmts
248 plpgsql_ns_setlocal(false);
254 $$.n_initvars = plpgsql_add_initdatums(&($$.initvarnos));
258 decl_start : K_DECLARE
260 plpgsql_ns_setlocal(true);
264 decl_stmts : decl_stmts decl_stmt
274 decl_stmt : '<' '<' opt_lblname '>' '>'
288 decl_statement : decl_varname decl_const decl_datatype decl_notnull decl_defval
292 new = malloc(sizeof(PLpgSQL_var));
294 new->dtype = PLPGSQL_DTYPE_VAR;
295 new->refname = $1.name;
296 new->lineno = $1.lineno;
301 new->default_val = $5;
303 plpgsql_adddatum((PLpgSQL_datum *)new);
304 plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, new->varno,
307 | decl_varname K_RECORD ';'
311 new = malloc(sizeof(PLpgSQL_var));
313 new->dtype = PLPGSQL_DTYPE_REC;
314 new->refname = $1.name;
315 new->lineno = $1.lineno;
317 plpgsql_adddatum((PLpgSQL_datum *)new);
318 plpgsql_ns_additem(PLPGSQL_NSTYPE_REC, new->recno,
321 | decl_varname decl_rowtype ';'
323 $2->dtype = PLPGSQL_DTYPE_ROW;
324 $2->refname = $1.name;
325 $2->lineno = $1.lineno;
327 plpgsql_adddatum((PLpgSQL_datum *)$2);
328 plpgsql_ns_additem(PLPGSQL_NSTYPE_ROW, $2->rowno,
331 | decl_varname K_ALIAS K_FOR decl_aliasitem ';'
333 plpgsql_ns_additem($4->itemtype,
334 $4->itemno, $1.name);
336 | K_RENAME decl_renname K_TO decl_renname ';'
338 plpgsql_ns_rename($2, $4);
342 decl_aliasitem : T_WORD
347 plpgsql_ns_setlocal(false);
348 name = plpgsql_tolower(yytext);
349 if (name[0] != '$') {
350 elog(ERROR, "can only alias positional parameters");
352 nsi = plpgsql_ns_lookup(name, NULL);
354 elog(ERROR, "function has no parameter %s", name);
357 plpgsql_ns_setlocal(true);
369 decl_varname : T_WORD
371 $$.name = strdup(yytext);
372 $$.lineno = yylineno;
376 decl_renname : T_WORD
378 $$ = plpgsql_tolower(yytext);
388 decl_datatype : decl_dtypename
394 decl_dtypename : T_DTYPE
398 | T_CHAR decl_atttypmod
401 plpgsql_parse_word("char");
404 plpgsql_parse_word("bpchar");
409 | T_VARCHAR decl_atttypmod
411 plpgsql_parse_word("varchar");
415 | T_BPCHAR '(' decl_atttypmodval ')'
417 plpgsql_parse_word("bpchar");
427 | '(' decl_atttypmodval ')'
433 decl_atttypmodval : T_NUMBER
435 $$ = int2in(yytext) + VARHDRSZ;
455 expr = malloc(sizeof(PLpgSQL_expr));
456 plpgsql_dstring_init(&ds);
457 plpgsql_dstring_append(&ds, "SELECT ");
459 expr->dtype = PLPGSQL_DTYPE_EXPR;
466 plpgsql_error_lineno = lno;
467 plpgsql_comperrinfo();
468 elog(ERROR, "unexpected end of file");
470 if (yylex() != ';') {
471 plpgsql_error_lineno = lno;
472 plpgsql_comperrinfo();
473 elog(ERROR, "expectec ; after NULL");
476 plpgsql_dstring_free(&ds);
482 plpgsql_dstring_append(&ds, yytext);
483 while ((tok = yylex()) != ';') {
485 plpgsql_error_lineno = lno;
486 plpgsql_comperrinfo();
487 elog(ERROR, "unterminated default value");
489 if (plpgsql_SpaceScanned) {
490 plpgsql_dstring_append(&ds, " ");
492 plpgsql_dstring_append(&ds, yytext);
494 expr->query = strdup(plpgsql_dstring_get(&ds));
495 plpgsql_dstring_free(&ds);
503 decl_defkey : K_ASSIGN
510 new = malloc(sizeof(PLpgSQL_stmts));
511 memset(new, 0, sizeof(PLpgSQL_stmts));
520 proc_stmts : proc_stmts proc_stmt
522 if ($1->stmts_used == $1->stmts_alloc) {
523 $1->stmts_alloc *= 2;
524 $1->stmts = realloc($1->stmts, sizeof(PLpgSQL_stmt *) * $1->stmts_alloc);
526 $1->stmts[$1->stmts_used++] = (struct PLpgSQL_stmt *)$2;
534 new = malloc(sizeof(PLpgSQL_stmts));
535 memset(new, 0, sizeof(PLpgSQL_stmts));
537 new->stmts_alloc = 64;
539 new->stmts = malloc(sizeof(PLpgSQL_stmt *) * new->stmts_alloc);
540 new->stmts[0] = (struct PLpgSQL_stmt *)$1;
574 stmt_perform : K_PERFORM lno expr_until_semi
576 PLpgSQL_stmt_assign *new;
578 new = malloc(sizeof(PLpgSQL_stmt_assign));
579 memset(new, 0, sizeof(PLpgSQL_stmt_assign));
581 new->cmd_type = PLPGSQL_STMT_ASSIGN;
586 $$ = (PLpgSQL_stmt *)new;
590 stmt_assign : assign_var lno K_ASSIGN expr_until_semi
592 PLpgSQL_stmt_assign *new;
594 new = malloc(sizeof(PLpgSQL_stmt_assign));
595 memset(new, 0, sizeof(PLpgSQL_stmt_assign));
597 new->cmd_type = PLPGSQL_STMT_ASSIGN;
602 $$ = (PLpgSQL_stmt *)new;
606 assign_var : T_VARIABLE
608 if (yylval.var->isconst) {
609 plpgsql_comperrinfo();
610 elog(ERROR, "%s is declared CONSTANT", yylval.var->refname);
612 $$ = yylval.var->varno;
616 $$ = yylval.recfield->rfno;
620 stmt_if : K_IF lno expr_until_then proc_sect stmt_else K_END K_IF ';'
622 PLpgSQL_stmt_if *new;
624 new = malloc(sizeof(PLpgSQL_stmt_if));
625 memset(new, 0, sizeof(PLpgSQL_stmt_if));
627 new->cmd_type = PLPGSQL_STMT_IF;
631 new->false_body = $5;
633 $$ = (PLpgSQL_stmt *)new;
641 new = malloc(sizeof(PLpgSQL_stmts));
642 memset(new, 0, sizeof(PLpgSQL_stmts));
649 stmt_loop : opt_label K_LOOP lno loop_body
651 PLpgSQL_stmt_loop *new;
653 new = malloc(sizeof(PLpgSQL_stmt_loop));
654 memset(new, 0, sizeof(PLpgSQL_stmt_loop));
656 new->cmd_type = PLPGSQL_STMT_LOOP;
663 $$ = (PLpgSQL_stmt *)new;
667 stmt_while : opt_label K_WHILE lno expr_until_loop loop_body
669 PLpgSQL_stmt_while *new;
671 new = malloc(sizeof(PLpgSQL_stmt_while));
672 memset(new, 0, sizeof(PLpgSQL_stmt_while));
674 new->cmd_type = PLPGSQL_STMT_WHILE;
682 $$ = (PLpgSQL_stmt *)new;
686 stmt_fori : opt_label K_FOR lno fori_var K_IN fori_lower expr_until_loop loop_body
688 PLpgSQL_stmt_fori *new;
690 new = malloc(sizeof(PLpgSQL_stmt_fori));
691 memset(new, 0, sizeof(PLpgSQL_stmt_fori));
693 new->cmd_type = PLPGSQL_STMT_FORI;
697 new->reverse = $6.reverse;
698 new->lower = $6.expr;
704 $$ = (PLpgSQL_stmt *)new;
708 fori_var : fori_varname
712 new = malloc(sizeof(PLpgSQL_var));
714 new->dtype = PLPGSQL_DTYPE_VAR;
715 new->refname = $1.name;
716 new->lineno = $1.lineno;
718 plpgsql_parse_word("integer");
720 new->datatype = yylval.dtype;
721 new->isconst = false;
722 new->notnull = false;
723 new->default_val = NULL;
725 plpgsql_adddatum((PLpgSQL_datum *)new);
726 plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, new->varno,
729 plpgsql_add_initdatums(NULL);
735 fori_varname : T_VARIABLE
737 $$.name = strdup(yytext);
738 $$.lineno = yylineno;
742 $$.name = strdup(yytext);
743 $$.lineno = yylineno;
759 plpgsql_dstring_init(&ds);
760 plpgsql_dstring_append(&ds, "SELECT ");
763 while((tok = yylex()) != K_DOTDOT) {
766 if (tok == K_REVERSE) {
771 if (tok == ';') break;
772 if (plpgsql_SpaceScanned) {
773 plpgsql_dstring_append(&ds, " ");
777 params[nparams] = yylval.var->varno;
778 sprintf(buf, "$%d", ++nparams);
779 plpgsql_dstring_append(&ds, buf);
783 params[nparams] = yylval.recfield->rfno;
784 sprintf(buf, "$%d", ++nparams);
785 plpgsql_dstring_append(&ds, buf);
789 params[nparams] = yylval.trigarg->dno;
790 sprintf(buf, "$%d", ++nparams);
791 plpgsql_dstring_append(&ds, buf);
796 plpgsql_error_lineno = lno;
797 plpgsql_comperrinfo();
798 elog(ERROR, "missing .. to terminate lower bound of for loop");
800 plpgsql_dstring_append(&ds, yytext);
805 expr = malloc(sizeof(PLpgSQL_expr) + sizeof(int) * nparams - 1);
806 expr->dtype = PLPGSQL_DTYPE_EXPR;
807 expr->query = strdup(plpgsql_dstring_get(&ds));
809 expr->nparams = nparams;
810 while(nparams-- > 0) {
811 expr->params[nparams] = params[nparams];
813 plpgsql_dstring_free(&ds);
817 stmt_fors : opt_label K_FOR lno fors_target K_IN K_SELECT expr_until_loop loop_body
819 PLpgSQL_stmt_fors *new;
821 new = malloc(sizeof(PLpgSQL_stmt_fors));
822 memset(new, 0, sizeof(PLpgSQL_stmt_fors));
824 new->cmd_type = PLPGSQL_STMT_FORS;
828 case PLPGSQL_DTYPE_REC:
831 case PLPGSQL_DTYPE_ROW:
832 new->row = (PLpgSQL_row *)$4;
835 plpgsql_comperrinfo();
836 elog(ERROR, "unknown dtype %d in stmt_fors", $4->dtype);
843 $$ = (PLpgSQL_stmt *)new;
846 fors_target : T_RECORD
852 $$ = (PLpgSQL_rec *)(yylval.row);
856 stmt_select : K_SELECT lno
858 $$ = make_select_stmt();
863 stmt_exit : K_EXIT lno opt_exitlabel opt_exitcond
865 PLpgSQL_stmt_exit *new;
867 new = malloc(sizeof(PLpgSQL_stmt_exit));
868 memset(new, 0, sizeof(PLpgSQL_stmt_exit));
870 new->cmd_type = PLPGSQL_STMT_EXIT;
875 $$ = (PLpgSQL_stmt *)new;
879 stmt_return : K_RETURN lno
881 PLpgSQL_stmt_return *new;
882 PLpgSQL_expr *expr = NULL;
885 new = malloc(sizeof(PLpgSQL_stmt_return));
886 memset(new, 0, sizeof(PLpgSQL_stmt_return));
888 if (plpgsql_curr_compile->fn_retistuple) {
889 new->retistuple = true;
891 switch (tok = yylex()) {
897 expr = make_tupret_expr(yylval.row);
901 new->retrecno = yylval.rec->recno;
906 yyerror("return type mismatch in function returning table row");
909 if (yylex() != ';') {
910 yyerror("expected ';'");
913 new->retistuple = false;
914 expr = plpgsql_read_expression(';', ";");
917 new->cmd_type = PLPGSQL_STMT_RETURN;
921 $$ = (PLpgSQL_stmt *)new;
925 stmt_raise : K_RAISE lno raise_level raise_msg raise_params ';'
927 PLpgSQL_stmt_raise *new;
929 new = malloc(sizeof(PLpgSQL_stmt_raise));
931 new->cmd_type = PLPGSQL_STMT_RAISE;
933 new->elog_level = $3;
935 new->nparams = $5.nused;
936 new->params = malloc(sizeof(int) * $5.nused);
937 memcpy(new->params, $5.dtnums, sizeof(int) * $5.nused);
939 $$ = (PLpgSQL_stmt *)new;
941 | K_RAISE lno raise_level raise_msg ';'
943 PLpgSQL_stmt_raise *new;
945 new = malloc(sizeof(PLpgSQL_stmt_raise));
947 new->cmd_type = PLPGSQL_STMT_RAISE;
949 new->elog_level = $3;
954 $$ = (PLpgSQL_stmt *)new;
964 raise_level : K_EXCEPTION
978 raise_params : raise_params raise_param
980 if ($1.nused == $1.nalloc) {
982 $1.dtnums = repalloc($1.dtnums, sizeof(int) * $1.nalloc);
984 $1.dtnums[$1.nused++] = $2;
986 $$.nalloc = $1.nalloc;
988 $$.dtnums = $1.dtnums;
994 $$.dtnums = palloc(sizeof(int) * $$.nalloc);
999 raise_param : ',' T_VARIABLE
1001 $$ = yylval.var->varno;
1005 $$ = yylval.recfield->rfno;
1009 $$ = yylval.trigarg->dno;
1013 loop_body : proc_sect K_END K_LOOP ';'
1017 stmt_execsql : execsql_start lno
1019 PLpgSQL_stmt_execsql *new;
1021 new = malloc(sizeof(PLpgSQL_stmt_execsql));
1022 new->cmd_type = PLPGSQL_STMT_EXECSQL;
1024 new->sqlstmt = read_sqlstmt(';', ";", $1);
1026 $$ = (PLpgSQL_stmt *)new;
1030 execsql_start : T_WORD
1031 { $$ = strdup(yytext); }
1033 { $$ = strdup(yytext); }
1037 { $$ = plpgsql_read_expression(';', ";"); }
1041 { $$ = plpgsql_read_expression(K_THEN, "THEN"); }
1045 { $$ = plpgsql_read_expression(K_LOOP, "LOOP"); }
1050 plpgsql_ns_push(NULL);
1053 | '<' '<' opt_lblname '>' '>'
1055 plpgsql_ns_push($3);
1063 { $$ = strdup(yytext); }
1068 | K_WHEN expr_until_semi
1072 opt_lblname : T_WORD
1073 { $$ = strdup(yytext); }
1078 plpgsql_error_lineno = yylineno;
1086 plpgsql_read_expression (int until, char *s)
1088 return read_sqlstmt(until, s, "SELECT ");
1092 static PLpgSQL_expr *
1093 read_sqlstmt (int until, char *s, char *sqlstart)
1104 plpgsql_dstring_init(&ds);
1105 plpgsql_dstring_append(&ds, sqlstart);
1107 while((tok = yylex()) != until) {
1108 if (tok == ';') break;
1109 if (plpgsql_SpaceScanned) {
1110 plpgsql_dstring_append(&ds, " ");
1114 params[nparams] = yylval.var->varno;
1115 sprintf(buf, "$%d", ++nparams);
1116 plpgsql_dstring_append(&ds, buf);
1120 params[nparams] = yylval.recfield->rfno;
1121 sprintf(buf, "$%d", ++nparams);
1122 plpgsql_dstring_append(&ds, buf);
1126 params[nparams] = yylval.trigarg->dno;
1127 sprintf(buf, "$%d", ++nparams);
1128 plpgsql_dstring_append(&ds, buf);
1133 plpgsql_error_lineno = lno;
1134 plpgsql_comperrinfo();
1135 elog(ERROR, "missing %s at end of SQL statement", s);
1137 plpgsql_dstring_append(&ds, yytext);
1142 expr = malloc(sizeof(PLpgSQL_expr) + sizeof(int) * nparams - 1);
1143 expr->dtype = PLPGSQL_DTYPE_EXPR;
1144 expr->query = strdup(plpgsql_dstring_get(&ds));
1146 expr->nparams = nparams;
1147 while(nparams-- > 0) {
1148 expr->params[nparams] = params[nparams];
1150 plpgsql_dstring_free(&ds);
1156 static PLpgSQL_stmt *
1166 PLpgSQL_row *row = NULL;
1167 PLpgSQL_rec *rec = NULL;
1168 PLpgSQL_stmt_select *select;
1169 int have_nexttok = 0;
1172 plpgsql_dstring_init(&ds);
1173 plpgsql_dstring_append(&ds, "SELECT ");
1175 while((tok = yylex()) != K_INTO) {
1177 PLpgSQL_stmt_execsql *execsql;
1179 expr = malloc(sizeof(PLpgSQL_expr) + sizeof(int) * nparams - 1);
1180 expr->dtype = PLPGSQL_DTYPE_EXPR;
1181 expr->query = strdup(plpgsql_dstring_get(&ds));
1183 expr->nparams = nparams;
1184 while(nparams-- > 0) {
1185 expr->params[nparams] = params[nparams];
1187 plpgsql_dstring_free(&ds);
1189 execsql = malloc(sizeof(PLpgSQL_stmt_execsql));
1190 execsql->cmd_type = PLPGSQL_STMT_EXECSQL;
1191 execsql->sqlstmt = expr;
1193 return (PLpgSQL_stmt *)execsql;
1196 if (plpgsql_SpaceScanned) {
1197 plpgsql_dstring_append(&ds, " ");
1201 params[nparams] = yylval.var->varno;
1202 sprintf(buf, "$%d", ++nparams);
1203 plpgsql_dstring_append(&ds, buf);
1207 params[nparams] = yylval.recfield->rfno;
1208 sprintf(buf, "$%d", ++nparams);
1209 plpgsql_dstring_append(&ds, buf);
1213 params[nparams] = yylval.trigarg->dno;
1214 sprintf(buf, "$%d", ++nparams);
1215 plpgsql_dstring_append(&ds, buf);
1220 plpgsql_error_lineno = yylineno;
1221 plpgsql_comperrinfo();
1222 elog(ERROR, "unexpected end of file");
1224 plpgsql_dstring_append(&ds, yytext);
1243 PLpgSQL_recfield *recfield;
1245 char *fieldnames[1024];
1251 fieldnames[0] = strdup(yytext);
1252 varnos[0] = var->varno;
1256 recfield = yylval.recfield;
1257 fieldnames[0] = strdup(yytext);
1258 varnos[0] = recfield->rfno;
1262 while ((tok = yylex()) == ',') {
1267 fieldnames[nfields] = strdup(yytext);
1268 varnos[nfields++] = var->varno;
1272 recfield = yylval.recfield;
1273 fieldnames[0] = strdup(yytext);
1274 varnos[0] = recfield->rfno;
1278 elog(ERROR, "plpgsql: %s is not a variable or record field", yytext);
1281 row = malloc(sizeof(PLpgSQL_row));
1282 row->dtype = PLPGSQL_DTYPE_ROW;
1283 row->refname = strdup("*internal*");
1284 row->lineno = yylineno;
1285 row->rowtypeclass = InvalidOid;
1286 row->nfields = nfields;
1287 row->fieldnames = malloc(sizeof(char *) * nfields);
1288 row->varnos = malloc(sizeof(int) * nfields);
1289 while (--nfields >= 0) {
1290 row->fieldnames[nfields] = fieldnames[nfields];
1291 row->varnos[nfields] = varnos[nfields];
1294 plpgsql_adddatum((PLpgSQL_datum *)row);
1302 if (plpgsql_SpaceScanned) {
1303 plpgsql_dstring_append(&ds, " ");
1305 plpgsql_dstring_append(&ds, yytext);
1310 PLpgSQL_stmt_execsql *execsql;
1312 expr = malloc(sizeof(PLpgSQL_expr) + sizeof(int) * nparams - 1);
1313 expr->dtype = PLPGSQL_DTYPE_EXPR;
1314 expr->query = strdup(plpgsql_dstring_get(&ds));
1316 expr->nparams = nparams;
1317 while(nparams-- > 0) {
1318 expr->params[nparams] = params[nparams];
1320 plpgsql_dstring_free(&ds);
1322 execsql = malloc(sizeof(PLpgSQL_stmt_execsql));
1323 execsql->cmd_type = PLPGSQL_STMT_EXECSQL;
1324 execsql->sqlstmt = expr;
1326 return (PLpgSQL_stmt *)execsql;
1329 if (plpgsql_SpaceScanned) {
1330 plpgsql_dstring_append(&ds, " ");
1334 params[nparams] = yylval.var->varno;
1335 sprintf(buf, "$%d", ++nparams);
1336 plpgsql_dstring_append(&ds, buf);
1340 params[nparams] = yylval.recfield->rfno;
1341 sprintf(buf, "$%d", ++nparams);
1342 plpgsql_dstring_append(&ds, buf);
1346 params[nparams] = yylval.trigarg->dno;
1347 sprintf(buf, "$%d", ++nparams);
1348 plpgsql_dstring_append(&ds, buf);
1353 plpgsql_error_lineno = yylineno;
1354 plpgsql_comperrinfo();
1355 elog(ERROR, "unexpected end of file");
1357 plpgsql_dstring_append(&ds, yytext);
1364 /************************************************************
1365 * Eat up the rest of the statement after the target fields
1366 ************************************************************/
1368 if (!have_nexttok) {
1376 if (plpgsql_SpaceScanned) {
1377 plpgsql_dstring_append(&ds, " ");
1381 params[nparams] = yylval.var->varno;
1382 sprintf(buf, "$%d", ++nparams);
1383 plpgsql_dstring_append(&ds, buf);
1387 params[nparams] = yylval.recfield->rfno;
1388 sprintf(buf, "$%d", ++nparams);
1389 plpgsql_dstring_append(&ds, buf);
1393 params[nparams] = yylval.trigarg->dno;
1394 sprintf(buf, "$%d", ++nparams);
1395 plpgsql_dstring_append(&ds, buf);
1400 plpgsql_error_lineno = yylineno;
1401 plpgsql_comperrinfo();
1402 elog(ERROR, "unexpected end of file");
1404 plpgsql_dstring_append(&ds, yytext);
1409 expr = malloc(sizeof(PLpgSQL_expr) + sizeof(int) * (nparams - 1));
1410 expr->dtype = PLPGSQL_DTYPE_EXPR;
1411 expr->query = strdup(plpgsql_dstring_get(&ds));
1413 expr->nparams = nparams;
1414 while(nparams-- > 0) {
1415 expr->params[nparams] = params[nparams];
1417 plpgsql_dstring_free(&ds);
1419 select = malloc(sizeof(PLpgSQL_stmt_select));
1420 memset(select, 0, sizeof(PLpgSQL_stmt_select));
1421 select->cmd_type = PLPGSQL_STMT_SELECT;
1424 select->query = expr;
1426 return (PLpgSQL_stmt *)select;
1430 static PLpgSQL_expr *
1431 make_tupret_expr(PLpgSQL_row *row)
1438 expr = malloc(sizeof(PLpgSQL_expr) + sizeof(int) * (row->nfields - 1));
1439 expr->dtype = PLPGSQL_DTYPE_EXPR;
1441 plpgsql_dstring_init(&ds);
1442 plpgsql_dstring_append(&ds, "SELECT ");
1444 for (i = 0; i < row->nfields; i++) {
1445 sprintf(buf, "%s$%d", (i > 0) ? "," : "", i + 1);
1446 plpgsql_dstring_append(&ds, buf);
1447 expr->params[i] = row->varnos[i];
1450 expr->query = strdup(plpgsql_dstring_get(&ds));
1452 expr->plan_argtypes = NULL;
1453 expr->nparams = row->nfields;
1455 plpgsql_dstring_free(&ds);