1 /**********************************************************************
2 * pl_exec.c - Executor for the PL/pgSQL
6 * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.59 2002/08/29 04:12:03 tgl Exp $
8 * This software is copyrighted by Jan Wieck - Hamburg.
10 * The author hereby grants permission to use, copy, modify,
11 * distribute, and license this software and its documentation
12 * for any purpose, provided that existing copyright notices are
13 * retained in all copies and that this notice is included
14 * verbatim in any distributions. No written agreement, license,
15 * or royalty fee is required for any of the authorized uses.
16 * Modifications to this software may be copyrighted by their
17 * author and need not follow the licensing terms described
18 * here, provided that the new terms are clearly indicated on
19 * the first page of each file where they apply.
21 * IN NO EVENT SHALL THE AUTHOR OR DISTRIBUTORS BE LIABLE TO ANY
22 * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
23 * CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS
24 * SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN
25 * IF THE AUTHOR HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
28 * THE AUTHOR AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY
29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
30 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
31 * PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON
32 * AN "AS IS" BASIS, AND THE AUTHOR AND DISTRIBUTORS HAVE NO
33 * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
34 * ENHANCEMENTS, OR MODIFICATIONS.
36 **********************************************************************/
50 #include "access/heapam.h"
51 #include "catalog/pg_proc.h"
52 #include "catalog/pg_type.h"
53 #include "commands/trigger.h"
54 #include "executor/spi.h"
55 #include "executor/spi_priv.h"
57 #include "optimizer/clauses.h"
58 #include "parser/parse_expr.h"
59 #include "tcop/tcopprot.h"
60 #include "utils/builtins.h"
61 #include "utils/lsyscache.h"
62 #include "utils/syscache.h"
65 static PLpgSQL_function *error_info_func = NULL;
66 static PLpgSQL_stmt *error_info_stmt = NULL;
67 static char *error_info_text = NULL;
70 /************************************************************
71 * Local function forward declarations
72 ************************************************************/
73 static PLpgSQL_var *copy_var(PLpgSQL_var * var);
74 static PLpgSQL_rec *copy_rec(PLpgSQL_rec * rec);
76 static int exec_stmt_block(PLpgSQL_execstate * estate,
77 PLpgSQL_stmt_block * block);
78 static int exec_stmts(PLpgSQL_execstate * estate,
79 PLpgSQL_stmts * stmts);
80 static int exec_stmt(PLpgSQL_execstate * estate,
82 static int exec_stmt_assign(PLpgSQL_execstate * estate,
83 PLpgSQL_stmt_assign * stmt);
84 static int exec_stmt_getdiag(PLpgSQL_execstate * estate,
85 PLpgSQL_stmt_getdiag * stmt);
86 static int exec_stmt_if(PLpgSQL_execstate * estate,
87 PLpgSQL_stmt_if * stmt);
88 static int exec_stmt_loop(PLpgSQL_execstate * estate,
89 PLpgSQL_stmt_loop * stmt);
90 static int exec_stmt_while(PLpgSQL_execstate * estate,
91 PLpgSQL_stmt_while * stmt);
92 static int exec_stmt_fori(PLpgSQL_execstate * estate,
93 PLpgSQL_stmt_fori * stmt);
94 static int exec_stmt_fors(PLpgSQL_execstate * estate,
95 PLpgSQL_stmt_fors * stmt);
96 static int exec_stmt_select(PLpgSQL_execstate * estate,
97 PLpgSQL_stmt_select * stmt);
98 static int exec_stmt_open(PLpgSQL_execstate * estate,
99 PLpgSQL_stmt_open * stmt);
100 static int exec_stmt_fetch(PLpgSQL_execstate * estate,
101 PLpgSQL_stmt_fetch * stmt);
102 static int exec_stmt_close(PLpgSQL_execstate * estate,
103 PLpgSQL_stmt_close * stmt);
104 static int exec_stmt_exit(PLpgSQL_execstate * estate,
105 PLpgSQL_stmt_exit * stmt);
106 static int exec_stmt_return(PLpgSQL_execstate * estate,
107 PLpgSQL_stmt_return * stmt);
108 static int exec_stmt_raise(PLpgSQL_execstate * estate,
109 PLpgSQL_stmt_raise * stmt);
110 static int exec_stmt_execsql(PLpgSQL_execstate * estate,
111 PLpgSQL_stmt_execsql * stmt);
112 static int exec_stmt_dynexecute(PLpgSQL_execstate * estate,
113 PLpgSQL_stmt_dynexecute * stmt);
114 static int exec_stmt_dynfors(PLpgSQL_execstate * estate,
115 PLpgSQL_stmt_dynfors * stmt);
117 static void plpgsql_estate_setup(PLpgSQL_execstate * estate,
118 PLpgSQL_function * func);
119 static void exec_eval_cleanup(PLpgSQL_execstate * estate);
121 static void exec_prepare_plan(PLpgSQL_execstate * estate,
122 PLpgSQL_expr * expr);
123 static bool exec_simple_check_node(Node *node);
124 static void exec_simple_check_plan(PLpgSQL_expr * expr);
125 static Datum exec_eval_simple_expr(PLpgSQL_execstate * estate,
130 static void exec_assign_expr(PLpgSQL_execstate * estate,
131 PLpgSQL_datum * target,
132 PLpgSQL_expr * expr);
133 static void exec_assign_value(PLpgSQL_execstate * estate,
134 PLpgSQL_datum * target,
135 Datum value, Oid valtype, bool *isNull);
136 static Datum exec_eval_expr(PLpgSQL_execstate * estate,
140 static int exec_run_select(PLpgSQL_execstate * estate,
141 PLpgSQL_expr * expr, int maxtuples, Portal *portalP);
142 static void exec_move_row(PLpgSQL_execstate * estate,
145 HeapTuple tup, TupleDesc tupdesc);
146 static Datum exec_cast_value(Datum value, Oid valtype,
152 static void exec_set_found(PLpgSQL_execstate * estate, bool state);
156 * plpgsql_exec_function Called by the call handler for
157 * function execution.
161 plpgsql_exec_function(PLpgSQL_function * func, FunctionCallInfo fcinfo)
163 PLpgSQL_execstate estate;
165 sigjmp_buf save_restart;
166 PLpgSQL_function *save_efunc;
167 PLpgSQL_stmt *save_estmt;
171 * Setup debug error info and catch elog()
173 save_efunc = error_info_func;
174 save_estmt = error_info_stmt;
175 save_etext = error_info_text;
177 error_info_func = func;
178 error_info_stmt = NULL;
179 error_info_text = "while initialization of execution state";
181 memcpy(&save_restart, &Warn_restart, sizeof(save_restart));
182 if (sigsetjmp(Warn_restart, 1) != 0)
184 memcpy(&Warn_restart, &save_restart, sizeof(Warn_restart));
187 * If we are the first of cascaded error catchings, print where
190 if (error_info_func != NULL)
192 elog(WARNING, "Error occurred while executing PL/pgSQL function %s",
193 error_info_func->fn_name);
194 if (error_info_stmt != NULL)
195 elog(WARNING, "line %d at %s", error_info_stmt->lineno,
196 plpgsql_stmt_typename(error_info_stmt));
197 else if (error_info_text != NULL)
198 elog(WARNING, "%s", error_info_text);
200 elog(WARNING, "no more error information available");
202 error_info_func = NULL;
203 error_info_stmt = NULL;
204 error_info_text = NULL;
207 siglongjmp(Warn_restart, 1);
212 * Setup the execution state
214 plpgsql_estate_setup(&estate, func);
217 * Make local execution copies of all the datums
219 for (i = 0; i < func->ndatums; i++)
221 switch (func->datums[i]->dtype)
223 case PLPGSQL_DTYPE_VAR:
224 estate.datums[i] = (PLpgSQL_datum *)
225 copy_var((PLpgSQL_var *) (func->datums[i]));
228 case PLPGSQL_DTYPE_REC:
229 estate.datums[i] = (PLpgSQL_datum *)
230 copy_rec((PLpgSQL_rec *) (func->datums[i]));
233 case PLPGSQL_DTYPE_ROW:
234 case PLPGSQL_DTYPE_RECFIELD:
235 estate.datums[i] = func->datums[i];
239 elog(ERROR, "unknown dtype %d in plpgsql_exec_function()",
240 func->datums[i]->dtype);
245 * Put the actual call argument values into the variables
247 error_info_text = "while putting call arguments to local variables";
248 for (i = 0; i < func->fn_nargs; i++)
250 int n = func->fn_argvarnos[i];
252 switch (estate.datums[n]->dtype)
254 case PLPGSQL_DTYPE_VAR:
256 PLpgSQL_var *var = (PLpgSQL_var *) estate.datums[n];
258 var->value = fcinfo->arg[i];
259 var->isnull = fcinfo->argnull[i];
260 var->freeval = false;
264 case PLPGSQL_DTYPE_ROW:
266 PLpgSQL_row *row = (PLpgSQL_row *) estate.datums[n];
267 TupleTableSlot *slot = (TupleTableSlot *) fcinfo->arg[i];
271 Assert(slot != NULL && !fcinfo->argnull[i]);
273 tupdesc = slot->ttc_tupleDescriptor;
274 exec_move_row(&estate, NULL, row, tup, tupdesc);
279 elog(ERROR, "unknown dtype %d in plpgsql_exec_function()",
280 func->datums[i]->dtype);
285 * Initialize the other variables to NULL values for now. The default
286 * values are set when the blocks are entered.
288 error_info_text = "while initializing local variables to NULL";
289 for (i = estate.found_varno; i < estate.ndatums; i++)
291 switch (estate.datums[i]->dtype)
293 case PLPGSQL_DTYPE_VAR:
295 PLpgSQL_var *var = (PLpgSQL_var *) estate.datums[i];
299 var->freeval = false;
303 case PLPGSQL_DTYPE_ROW:
304 case PLPGSQL_DTYPE_REC:
305 case PLPGSQL_DTYPE_RECFIELD:
309 elog(ERROR, "unknown dtype %d in plpgsql_exec_function()",
310 func->datums[i]->dtype);
315 * Set the magic variable FOUND to false
317 exec_set_found(&estate, false);
320 * Now call the toplevel block of statements
322 error_info_text = NULL;
323 error_info_stmt = (PLpgSQL_stmt *) (func->action);
324 if (exec_stmt_block(&estate, func->action) != PLPGSQL_RC_RETURN)
326 error_info_stmt = NULL;
327 error_info_text = "at END of toplevel PL block";
328 elog(ERROR, "control reaches end of function without RETURN");
332 * We got a return value - process it
334 error_info_stmt = NULL;
335 error_info_text = "while casting return value to functions return type";
337 fcinfo->isnull = estate.retisnull;
339 if (!estate.retisnull)
341 if (estate.retistuple)
343 /* Copy tuple to upper executor memory */
344 /* Here we need to return a TupleTableSlot not just a tuple */
345 estate.retval = (Datum)
346 SPI_copytupleintoslot((HeapTuple) (estate.retval),
351 /* Cast value to proper type */
352 estate.retval = exec_cast_value(estate.retval, estate.rettype,
354 &(func->fn_retinput),
360 * If the functions return type isn't by value, copy the value
361 * into upper executor memory context.
363 if (!fcinfo->isnull && !func->fn_retbyval)
368 len = datumGetSize(estate.retval, false, func->fn_rettyplen);
369 tmp = (void *) SPI_palloc(len);
370 memcpy(tmp, DatumGetPointer(estate.retval), len);
371 estate.retval = PointerGetDatum(tmp);
376 /* Clean up any leftover temporary memory */
377 exec_eval_cleanup(&estate);
380 * Restore the previous error info and elog() jump target
382 error_info_func = save_efunc;
383 error_info_stmt = save_estmt;
384 error_info_text = save_etext;
385 memcpy(&Warn_restart, &save_restart, sizeof(Warn_restart));
388 * Return the functions result
390 return estate.retval;
395 * plpgsql_exec_trigger Called by the call handler for
400 plpgsql_exec_trigger(PLpgSQL_function * func,
401 TriggerData *trigdata)
403 PLpgSQL_execstate estate;
405 sigjmp_buf save_restart;
406 PLpgSQL_function *save_efunc;
407 PLpgSQL_stmt *save_estmt;
409 PLpgSQL_rec *rec_new;
410 PLpgSQL_rec *rec_old;
415 * Setup debug error info and catch elog()
417 save_efunc = error_info_func;
418 save_estmt = error_info_stmt;
419 save_etext = error_info_text;
421 error_info_func = func;
422 error_info_stmt = NULL;
423 error_info_text = "while initialization of execution state";
425 memcpy(&save_restart, &Warn_restart, sizeof(save_restart));
426 if (sigsetjmp(Warn_restart, 1) != 0)
428 memcpy(&Warn_restart, &save_restart, sizeof(Warn_restart));
431 * If we are the first of cascaded error catchings, print where
434 if (error_info_func != NULL)
436 elog(WARNING, "Error occurred while executing PL/pgSQL function %s",
437 error_info_func->fn_name);
438 if (error_info_stmt != NULL)
439 elog(WARNING, "line %d at %s", error_info_stmt->lineno,
440 plpgsql_stmt_typename(error_info_stmt));
441 else if (error_info_text != NULL)
442 elog(WARNING, "%s", error_info_text);
444 elog(WARNING, "no more error information available");
446 error_info_func = NULL;
447 error_info_stmt = NULL;
448 error_info_text = NULL;
451 siglongjmp(Warn_restart, 1);
456 * Setup the execution state
458 plpgsql_estate_setup(&estate, func);
461 * Make local execution copies of all the datums
463 for (i = 0; i < func->ndatums; i++)
465 switch (func->datums[i]->dtype)
467 case PLPGSQL_DTYPE_VAR:
468 estate.datums[i] = (PLpgSQL_datum *)
469 copy_var((PLpgSQL_var *) (func->datums[i]));
472 case PLPGSQL_DTYPE_REC:
473 estate.datums[i] = (PLpgSQL_datum *)
474 copy_rec((PLpgSQL_rec *) (func->datums[i]));
477 case PLPGSQL_DTYPE_ROW:
478 case PLPGSQL_DTYPE_RECFIELD:
479 case PLPGSQL_DTYPE_TRIGARG:
480 estate.datums[i] = func->datums[i];
484 elog(ERROR, "unknown dtype %d in plpgsql_exec_function()",
485 func->datums[i]->dtype);
490 * Put the trig and new tuples into the records and set the tg_op
493 rec_new = (PLpgSQL_rec *) (estate.datums[func->new_varno]);
494 rec_new->freetup = false;
495 rec_new->freetupdesc = false;
496 rec_old = (PLpgSQL_rec *) (estate.datums[func->old_varno]);
497 rec_old->freetup = false;
498 rec_old->freetupdesc = false;
499 var = (PLpgSQL_var *) (estate.datums[func->tg_op_varno]);
501 if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
503 rec_new->tup = trigdata->tg_trigtuple;
504 rec_new->tupdesc = trigdata->tg_relation->rd_att;
506 rec_old->tupdesc = NULL;
507 var->value = DirectFunctionCall1(textin, CStringGetDatum("INSERT"));
509 else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
511 rec_new->tup = trigdata->tg_newtuple;
512 rec_new->tupdesc = trigdata->tg_relation->rd_att;
513 rec_old->tup = trigdata->tg_trigtuple;
514 rec_old->tupdesc = trigdata->tg_relation->rd_att;
515 var->value = DirectFunctionCall1(textin, CStringGetDatum("UPDATE"));
517 else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event))
520 rec_new->tupdesc = NULL;
521 rec_old->tup = trigdata->tg_trigtuple;
522 rec_old->tupdesc = trigdata->tg_relation->rd_att;
523 var->value = DirectFunctionCall1(textin, CStringGetDatum("DELETE"));
528 rec_new->tupdesc = NULL;
530 rec_old->tupdesc = NULL;
531 var->value = DirectFunctionCall1(textin, CStringGetDatum("UNKNOWN"));
537 * Fill all the other special tg_ variables
539 var = (PLpgSQL_var *) (estate.datums[func->tg_name_varno]);
542 var->value = DirectFunctionCall1(namein,
543 CStringGetDatum(trigdata->tg_trigger->tgname));
545 var = (PLpgSQL_var *) (estate.datums[func->tg_when_varno]);
548 if (TRIGGER_FIRED_BEFORE(trigdata->tg_event))
549 var->value = DirectFunctionCall1(textin, CStringGetDatum("BEFORE"));
550 else if (TRIGGER_FIRED_AFTER(trigdata->tg_event))
551 var->value = DirectFunctionCall1(textin, CStringGetDatum("AFTER"));
553 var->value = DirectFunctionCall1(textin, CStringGetDatum("UNKNOWN"));
555 var = (PLpgSQL_var *) (estate.datums[func->tg_level_varno]);
558 if (TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
559 var->value = DirectFunctionCall1(textin, CStringGetDatum("ROW"));
560 else if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
561 var->value = DirectFunctionCall1(textin, CStringGetDatum("STATEMENT"));
563 var->value = DirectFunctionCall1(textin, CStringGetDatum("UNKNOWN"));
565 var = (PLpgSQL_var *) (estate.datums[func->tg_relid_varno]);
567 var->freeval = false;
568 var->value = ObjectIdGetDatum(trigdata->tg_relation->rd_id);
570 var = (PLpgSQL_var *) (estate.datums[func->tg_relname_varno]);
573 var->value = DirectFunctionCall1(namein,
574 CStringGetDatum(RelationGetRelationName(trigdata->tg_relation)));
576 var = (PLpgSQL_var *) (estate.datums[func->tg_nargs_varno]);
578 var->freeval = false;
579 var->value = Int16GetDatum(trigdata->tg_trigger->tgnargs);
582 * Put the actual call argument values into the special execution
585 error_info_text = "while putting call arguments to local variables";
586 estate.trig_nargs = trigdata->tg_trigger->tgnargs;
587 if (estate.trig_nargs == 0)
588 estate.trig_argv = NULL;
591 estate.trig_argv = palloc(sizeof(Datum) * estate.trig_nargs);
592 for (i = 0; i < trigdata->tg_trigger->tgnargs; i++)
593 estate.trig_argv[i] = DirectFunctionCall1(textin,
594 CStringGetDatum(trigdata->tg_trigger->tgargs[i]));
598 * Initialize the other variables to NULL values for now. The default
599 * values are set when the blocks are entered.
601 error_info_text = "while initializing local variables to NULL";
602 for (i = estate.found_varno; i < estate.ndatums; i++)
604 switch (estate.datums[i]->dtype)
606 case PLPGSQL_DTYPE_VAR:
608 PLpgSQL_var *var = (PLpgSQL_var *) estate.datums[i];
612 var->freeval = false;
616 case PLPGSQL_DTYPE_ROW:
617 case PLPGSQL_DTYPE_REC:
618 case PLPGSQL_DTYPE_RECFIELD:
619 case PLPGSQL_DTYPE_TRIGARG:
623 elog(ERROR, "unknown dtype %d in plpgsql_exec_trigger()",
624 func->datums[i]->dtype);
629 * Set the magic variable FOUND to false
631 exec_set_found(&estate, false);
634 * Now call the toplevel block of statements
636 error_info_text = NULL;
637 error_info_stmt = (PLpgSQL_stmt *) (func->action);
638 if (exec_stmt_block(&estate, func->action) != PLPGSQL_RC_RETURN)
640 error_info_stmt = NULL;
641 error_info_text = "at END of toplevel PL block";
642 elog(ERROR, "control reaches end of trigger procedure without RETURN");
646 * Check that the returned tuple structure has the same attributes,
647 * the relation that fired the trigger has.
649 * XXX This way it is possible, that the trigger returns a tuple where
650 * attributes don't have the correct atttypmod's length. It's up to
651 * the trigger's programmer to ensure that this doesn't happen. Jan
653 if (estate.retisnull)
657 TupleDesc td1 = trigdata->tg_relation->rd_att;
658 TupleDesc td2 = estate.rettupdesc;
661 if (td1->natts != td2->natts)
662 elog(ERROR, "returned tuple structure doesn't match table of trigger event");
663 for (i = 1; i <= td1->natts; i++)
665 if (SPI_gettypeid(td1, i) != SPI_gettypeid(td2, i))
666 elog(ERROR, "returned tuple structure doesn't match table of trigger event");
669 /* Copy tuple to upper executor memory */
670 rettup = SPI_copytuple((HeapTuple) (estate.retval));
673 /* Clean up any leftover temporary memory */
674 exec_eval_cleanup(&estate);
677 * Restore the previous error info and elog() jump target
679 error_info_func = save_efunc;
680 error_info_stmt = save_estmt;
681 error_info_text = save_etext;
682 memcpy(&Warn_restart, &save_restart, sizeof(Warn_restart));
685 * Return the triggers result
692 * Support functions for copying local execution variables
696 copy_var(PLpgSQL_var * var)
698 PLpgSQL_var *new = palloc(sizeof(PLpgSQL_var));
700 memcpy(new, var, sizeof(PLpgSQL_var));
701 new->freeval = false;
708 copy_rec(PLpgSQL_rec * rec)
710 PLpgSQL_rec *new = palloc(sizeof(PLpgSQL_rec));
712 memcpy(new, rec, sizeof(PLpgSQL_rec));
715 new->freetup = false;
716 new->freetupdesc = false;
723 * exec_stmt_block Execute a block of statements
727 exec_stmt_block(PLpgSQL_execstate * estate, PLpgSQL_stmt_block * block)
734 * First initialize all variables declared in this block
736 for (i = 0; i < block->n_initvars; i++)
738 n = block->initvarnos[i];
740 switch (estate->datums[n]->dtype)
742 case PLPGSQL_DTYPE_VAR:
744 PLpgSQL_var *var = (PLpgSQL_var *) (estate->datums[n]);
748 pfree((void *) (var->value));
749 var->freeval = false;
752 if (!var->isconst || var->isnull)
754 if (var->default_val == NULL)
756 var->value = (Datum) 0;
759 elog(ERROR, "variable '%s' declared NOT NULL cannot default to NULL", var->refname);
763 exec_assign_expr(estate, (PLpgSQL_datum *) var,
770 case PLPGSQL_DTYPE_REC:
772 PLpgSQL_rec *rec = (PLpgSQL_rec *) (estate->datums[n]);
776 heap_freetuple(rec->tup);
777 FreeTupleDesc(rec->tupdesc);
778 rec->freetup = false;
786 case PLPGSQL_DTYPE_RECFIELD:
790 elog(ERROR, "unknown dtype %d in exec_stmt_block()", estate->datums[n]->dtype);
796 * Execute the statements in the block's body
798 rc = exec_stmts(estate, block->body);
801 * Handle the return code.
806 return PLPGSQL_RC_OK;
808 case PLPGSQL_RC_EXIT:
809 if (estate->exitlabel == NULL)
810 return PLPGSQL_RC_OK;
811 if (block->label == NULL)
812 return PLPGSQL_RC_EXIT;
813 if (strcmp(block->label, estate->exitlabel))
814 return PLPGSQL_RC_EXIT;
815 estate->exitlabel = NULL;
816 return PLPGSQL_RC_OK;
818 case PLPGSQL_RC_RETURN:
819 return PLPGSQL_RC_RETURN;
822 elog(ERROR, "unknown rc %d from exec_stmt()", rc);
825 return PLPGSQL_RC_OK;
830 * exec_stmts Iterate over a list of statements
831 * as long as their return code is OK
835 exec_stmts(PLpgSQL_execstate * estate, PLpgSQL_stmts * stmts)
840 for (i = 0; i < stmts->stmts_used; i++)
842 rc = exec_stmt(estate, (PLpgSQL_stmt *) (stmts->stmts[i]));
843 if (rc != PLPGSQL_RC_OK)
847 return PLPGSQL_RC_OK;
852 * exec_stmt Distribute one statement to the statements
853 * type specific execution function.
857 exec_stmt(PLpgSQL_execstate * estate, PLpgSQL_stmt * stmt)
859 PLpgSQL_stmt *save_estmt;
862 save_estmt = error_info_stmt;
863 error_info_stmt = stmt;
865 switch (stmt->cmd_type)
867 case PLPGSQL_STMT_BLOCK:
868 rc = exec_stmt_block(estate, (PLpgSQL_stmt_block *) stmt);
871 case PLPGSQL_STMT_ASSIGN:
872 rc = exec_stmt_assign(estate, (PLpgSQL_stmt_assign *) stmt);
875 case PLPGSQL_STMT_GETDIAG:
876 rc = exec_stmt_getdiag(estate, (PLpgSQL_stmt_getdiag *) stmt);
879 case PLPGSQL_STMT_IF:
880 rc = exec_stmt_if(estate, (PLpgSQL_stmt_if *) stmt);
883 case PLPGSQL_STMT_LOOP:
884 rc = exec_stmt_loop(estate, (PLpgSQL_stmt_loop *) stmt);
887 case PLPGSQL_STMT_WHILE:
888 rc = exec_stmt_while(estate, (PLpgSQL_stmt_while *) stmt);
891 case PLPGSQL_STMT_FORI:
892 rc = exec_stmt_fori(estate, (PLpgSQL_stmt_fori *) stmt);
895 case PLPGSQL_STMT_FORS:
896 rc = exec_stmt_fors(estate, (PLpgSQL_stmt_fors *) stmt);
899 case PLPGSQL_STMT_SELECT:
900 rc = exec_stmt_select(estate, (PLpgSQL_stmt_select *) stmt);
903 case PLPGSQL_STMT_EXIT:
904 rc = exec_stmt_exit(estate, (PLpgSQL_stmt_exit *) stmt);
907 case PLPGSQL_STMT_RETURN:
908 rc = exec_stmt_return(estate, (PLpgSQL_stmt_return *) stmt);
911 case PLPGSQL_STMT_RAISE:
912 rc = exec_stmt_raise(estate, (PLpgSQL_stmt_raise *) stmt);
915 case PLPGSQL_STMT_EXECSQL:
916 rc = exec_stmt_execsql(estate, (PLpgSQL_stmt_execsql *) stmt);
919 case PLPGSQL_STMT_DYNEXECUTE:
920 rc = exec_stmt_dynexecute(estate, (PLpgSQL_stmt_dynexecute *) stmt);
923 case PLPGSQL_STMT_DYNFORS:
924 rc = exec_stmt_dynfors(estate, (PLpgSQL_stmt_dynfors *) stmt);
927 case PLPGSQL_STMT_OPEN:
928 rc = exec_stmt_open(estate, (PLpgSQL_stmt_open *) stmt);
931 case PLPGSQL_STMT_FETCH:
932 rc = exec_stmt_fetch(estate, (PLpgSQL_stmt_fetch *) stmt);
935 case PLPGSQL_STMT_CLOSE:
936 rc = exec_stmt_close(estate, (PLpgSQL_stmt_close *) stmt);
940 error_info_stmt = save_estmt;
941 elog(ERROR, "unknown cmdtype %d in exec_stmt",
945 error_info_stmt = save_estmt;
952 * exec_stmt_assign Evaluate an expression and
953 * put the result into a variable.
955 * For no very good reason, this is also used for PERFORM statements.
959 exec_stmt_assign(PLpgSQL_execstate * estate, PLpgSQL_stmt_assign * stmt)
961 PLpgSQL_expr *expr = stmt->expr;
963 if (stmt->varno >= 0)
964 exec_assign_expr(estate, estate->datums[stmt->varno], expr);
968 * PERFORM: evaluate query and discard result (but set FOUND
969 * depending on whether at least one row was returned).
971 * This cannot share code with the assignment case since we do not
972 * wish to constrain the discarded result to be only one row/column.
977 * If not already done create a plan for this expression
979 if (expr->plan == NULL)
980 exec_prepare_plan(estate, expr);
982 rc = exec_run_select(estate, expr, 0, NULL);
983 if (rc != SPI_OK_SELECT)
984 elog(ERROR, "query \"%s\" didn't return data", expr->query);
986 exec_set_found(estate, (estate->eval_processed != 0));
988 exec_eval_cleanup(estate);
991 return PLPGSQL_RC_OK;
995 * exec_stmt_getdiag Put internal PG information into
996 * specified variables.
1000 exec_stmt_getdiag(PLpgSQL_execstate * estate, PLpgSQL_stmt_getdiag * stmt)
1004 bool isnull = false;
1006 for (i = 0; i < stmt->ndtitems; i++)
1008 PLpgSQL_diag_item *dtitem = &stmt->dtitems[i];
1010 if (dtitem->target <= 0)
1013 var = (estate->datums[dtitem->target]);
1018 switch (dtitem->item)
1020 case PLPGSQL_GETDIAG_ROW_COUNT:
1022 exec_assign_value(estate, var,
1023 UInt32GetDatum(estate->eval_processed),
1027 case PLPGSQL_GETDIAG_RESULT_OID:
1029 exec_assign_value(estate, var,
1030 ObjectIdGetDatum(estate->eval_lastoid),
1036 elog(ERROR, "unknown attribute request %d in get_diagnostic",
1041 return PLPGSQL_RC_OK;
1045 * exec_stmt_if Evaluate a bool expression and
1046 * execute the true or false body
1051 exec_stmt_if(PLpgSQL_execstate * estate, PLpgSQL_stmt_if * stmt)
1055 bool isnull = false;
1057 value = exec_eval_expr(estate, stmt->cond, &isnull, &valtype);
1058 exec_eval_cleanup(estate);
1060 if (!isnull && DatumGetBool(value))
1062 if (stmt->true_body != NULL)
1063 return exec_stmts(estate, stmt->true_body);
1067 if (stmt->false_body != NULL)
1068 return exec_stmts(estate, stmt->false_body);
1071 return PLPGSQL_RC_OK;
1076 * exec_stmt_loop Loop over statements until
1081 exec_stmt_loop(PLpgSQL_execstate * estate, PLpgSQL_stmt_loop * stmt)
1087 rc = exec_stmts(estate, stmt->body);
1094 case PLPGSQL_RC_EXIT:
1095 if (estate->exitlabel == NULL)
1096 return PLPGSQL_RC_OK;
1097 if (stmt->label == NULL)
1098 return PLPGSQL_RC_EXIT;
1099 if (strcmp(stmt->label, estate->exitlabel))
1100 return PLPGSQL_RC_EXIT;
1101 estate->exitlabel = NULL;
1102 return PLPGSQL_RC_OK;
1104 case PLPGSQL_RC_RETURN:
1105 return PLPGSQL_RC_RETURN;
1108 elog(ERROR, "unknown rc %d from exec_stmts()", rc);
1112 return PLPGSQL_RC_OK;
1117 * exec_stmt_while Loop over statements as long
1118 * as an expression evaluates to
1119 * true or an exit occurs.
1123 exec_stmt_while(PLpgSQL_execstate * estate, PLpgSQL_stmt_while * stmt)
1127 bool isnull = false;
1132 value = exec_eval_expr(estate, stmt->cond, &isnull, &valtype);
1133 exec_eval_cleanup(estate);
1134 if (isnull || !DatumGetBool(value))
1137 rc = exec_stmts(estate, stmt->body);
1144 case PLPGSQL_RC_EXIT:
1145 if (estate->exitlabel == NULL)
1146 return PLPGSQL_RC_OK;
1147 if (stmt->label == NULL)
1148 return PLPGSQL_RC_EXIT;
1149 if (strcmp(stmt->label, estate->exitlabel))
1150 return PLPGSQL_RC_EXIT;
1151 estate->exitlabel = NULL;
1152 return PLPGSQL_RC_OK;
1154 case PLPGSQL_RC_RETURN:
1155 return PLPGSQL_RC_RETURN;
1158 elog(ERROR, "unknown rc %d from exec_stmts()", rc);
1162 return PLPGSQL_RC_OK;
1167 * exec_stmt_fori Iterate an integer variable
1168 * from a lower to an upper value.
1169 * Loop can be left with exit.
1173 exec_stmt_fori(PLpgSQL_execstate * estate, PLpgSQL_stmt_fori * stmt)
1178 bool isnull = false;
1180 int rc = PLPGSQL_RC_OK;
1182 var = (PLpgSQL_var *) (estate->datums[stmt->var->varno]);
1185 * Get the value of the lower bound into the loop var
1187 value = exec_eval_expr(estate, stmt->lower, &isnull, &valtype);
1188 value = exec_cast_value(value, valtype, var->datatype->typoid,
1189 &(var->datatype->typinput),
1190 var->datatype->typelem,
1191 var->datatype->atttypmod, &isnull);
1193 elog(ERROR, "lower bound of FOR loop cannot be NULL");
1195 var->isnull = false;
1196 exec_eval_cleanup(estate);
1199 * Get the value of the upper bound
1201 value = exec_eval_expr(estate, stmt->upper, &isnull, &valtype);
1202 value = exec_cast_value(value, valtype, var->datatype->typoid,
1203 &(var->datatype->typinput),
1204 var->datatype->typelem,
1205 var->datatype->atttypmod, &isnull);
1207 elog(ERROR, "upper bound of FOR loop cannot be NULL");
1208 exec_eval_cleanup(estate);
1220 if ((int4) (var->value) < (int4) value)
1225 if ((int4) (var->value) > (int4) value)
1229 found = true; /* looped at least once */
1232 * Execute the statements
1234 rc = exec_stmts(estate, stmt->body);
1236 if (rc == PLPGSQL_RC_RETURN)
1237 break; /* return from function */
1238 else if (rc == PLPGSQL_RC_EXIT)
1240 if (estate->exitlabel == NULL)
1241 /* unlabelled exit, finish the current loop */
1243 else if (stmt->label != NULL &&
1244 strcmp(stmt->label, estate->exitlabel) == 0)
1246 /* labelled exit, matches the current stmt's label */
1247 estate->exitlabel = NULL;
1252 * otherwise, we processed a labelled exit that does not
1253 * match the current statement's label, if any: return
1254 * RC_EXIT so that the EXIT continues to recurse upward.
1261 * Increase/decrease loop var
1270 * Set the FOUND variable to indicate the result of executing the
1271 * loop (namely, whether we looped one or more times). This must be
1272 * set here so that it does not interfere with the value of the
1273 * FOUND variable inside the loop processing itself.
1275 exec_set_found(estate, found);
1282 * exec_stmt_fors Execute a query, assign each
1283 * tuple to a record or row and
1284 * execute a group of statements
1289 exec_stmt_fors(PLpgSQL_execstate * estate, PLpgSQL_stmt_fors * stmt)
1291 PLpgSQL_rec *rec = NULL;
1292 PLpgSQL_row *row = NULL;
1293 SPITupleTable *tuptab;
1296 int rc = PLPGSQL_RC_OK;
1301 * Determine if we assign to a record or a row
1303 if (stmt->rec != NULL)
1304 rec = (PLpgSQL_rec *) (estate->datums[stmt->rec->recno]);
1307 if (stmt->row != NULL)
1308 row = (PLpgSQL_row *) (estate->datums[stmt->row->rowno]);
1310 elog(ERROR, "unsupported target in exec_stmt_fors()");
1314 * Open the implicit cursor for the statement and fetch the initial 10
1317 exec_run_select(estate, stmt->query, 0, &portal);
1319 SPI_cursor_fetch(portal, true, 10);
1321 tuptab = SPI_tuptable;
1324 * If the query didn't return any rows, set the target to NULL and
1325 * return with FOUND = false.
1328 exec_move_row(estate, rec, row, NULL, NULL);
1330 found = true; /* processed at least one tuple */
1337 for (i = 0; i < n; i++)
1340 * Assign the tuple to the target
1342 exec_move_row(estate, rec, row, tuptab->vals[i], tuptab->tupdesc);
1345 * Execute the statements
1347 rc = exec_stmts(estate, stmt->body);
1349 if (rc != PLPGSQL_RC_OK)
1352 * We're aborting the loop, so cleanup and set FOUND
1354 exec_set_found(estate, found);
1355 SPI_freetuptable(tuptab);
1356 SPI_cursor_close(portal);
1358 if (rc == PLPGSQL_RC_EXIT)
1360 if (estate->exitlabel == NULL)
1361 /* unlabelled exit, finish the current loop */
1363 else if (stmt->label != NULL &&
1364 strcmp(stmt->label, estate->exitlabel) == 0)
1366 /* labelled exit, matches the current stmt's label */
1367 estate->exitlabel = NULL;
1372 * otherwise, we processed a labelled exit that does not
1373 * match the current statement's label, if any: return
1374 * RC_EXIT so that the EXIT continues to recurse upward.
1382 SPI_freetuptable(tuptab);
1385 * Fetch the next 50 tuples
1387 SPI_cursor_fetch(portal, true, 50);
1389 tuptab = SPI_tuptable;
1393 * Close the implicit cursor
1395 SPI_cursor_close(portal);
1398 * Set the FOUND variable to indicate the result of executing the
1399 * loop (namely, whether we looped one or more times). This must be
1400 * set here so that it does not interfere with the value of the
1401 * FOUND variable inside the loop processing itself.
1403 exec_set_found(estate, found);
1410 * exec_stmt_select Run a query and assign the first
1411 * row to a record or rowtype.
1415 exec_stmt_select(PLpgSQL_execstate * estate, PLpgSQL_stmt_select * stmt)
1417 PLpgSQL_rec *rec = NULL;
1418 PLpgSQL_row *row = NULL;
1419 SPITupleTable *tuptab;
1423 * Initialize the global found variable to false
1425 exec_set_found(estate, false);
1428 * Determine if we assign to a record or a row
1430 if (stmt->rec != NULL)
1431 rec = (PLpgSQL_rec *) (estate->datums[stmt->rec->recno]);
1432 else if (stmt->row != NULL)
1433 row = (PLpgSQL_row *) (estate->datums[stmt->row->rowno]);
1435 elog(ERROR, "unsupported target in exec_stmt_select()");
1440 exec_run_select(estate, stmt->query, 1, NULL);
1441 n = estate->eval_processed;
1444 * If the query didn't return any row, set the target to NULL and
1449 exec_move_row(estate, rec, row, NULL, NULL);
1450 exec_eval_cleanup(estate);
1451 return PLPGSQL_RC_OK;
1455 * Put the result into the target and set found to true
1457 tuptab = estate->eval_tuptable;
1458 exec_move_row(estate, rec, row, tuptab->vals[0], tuptab->tupdesc);
1459 exec_set_found(estate, true);
1461 exec_eval_cleanup(estate);
1463 return PLPGSQL_RC_OK;
1468 * exec_stmt_exit Start exiting loop(s) or blocks
1472 exec_stmt_exit(PLpgSQL_execstate * estate, PLpgSQL_stmt_exit * stmt)
1476 bool isnull = false;
1479 * If the exit has a condition, check that it's true
1481 if (stmt->cond != NULL)
1483 value = exec_eval_expr(estate, stmt->cond, &isnull, &valtype);
1484 exec_eval_cleanup(estate);
1485 if (isnull || !DatumGetBool(value))
1486 return PLPGSQL_RC_OK;
1489 estate->exitlabel = stmt->label;
1490 return PLPGSQL_RC_EXIT;
1495 * exec_stmt_return Evaluate an expression and start
1496 * returning from the function.
1500 exec_stmt_return(PLpgSQL_execstate * estate, PLpgSQL_stmt_return * stmt)
1502 if (estate->retistuple)
1504 /* initialize for null result tuple */
1505 estate->retval = (Datum) 0;
1506 estate->rettupdesc = NULL;
1507 estate->retisnull = true;
1509 if (stmt->retrecno >= 0)
1511 PLpgSQL_rec *rec = (PLpgSQL_rec *) (estate->datums[stmt->retrecno]);
1513 if (HeapTupleIsValid(rec->tup))
1515 estate->retval = (Datum) rec->tup;
1516 estate->rettupdesc = rec->tupdesc;
1517 estate->retisnull = false;
1519 return PLPGSQL_RC_RETURN;
1522 if (stmt->expr != NULL)
1524 exec_run_select(estate, stmt->expr, 1, NULL);
1525 if (estate->eval_processed > 0)
1527 estate->retval = (Datum) estate->eval_tuptable->vals[0];
1528 estate->rettupdesc = estate->eval_tuptable->tupdesc;
1529 estate->retisnull = false;
1532 return PLPGSQL_RC_RETURN;
1535 estate->retval = exec_eval_expr(estate, stmt->expr,
1536 &(estate->retisnull),
1537 &(estate->rettype));
1539 return PLPGSQL_RC_RETURN;
1544 * exec_stmt_raise Build a message and throw it with
1549 exec_stmt_raise(PLpgSQL_execstate * estate, PLpgSQL_stmt_raise * stmt)
1552 Form_pg_type typeStruct;
1553 FmgrInfo finfo_output;
1561 PLpgSQL_recfield *recfield;
1564 plpgsql_dstring_init(&ds);
1566 for (cp = stmt->message; *cp; cp++)
1569 * Occurences of a single % are replaced by the next arguments
1570 * external representation. Double %'s are left as is so elog()
1571 * will also don't touch them.
1573 if ((c[0] = *cp) == '%')
1578 plpgsql_dstring_append(&ds, c);
1579 plpgsql_dstring_append(&ds, c);
1583 if (pidx >= stmt->nparams)
1585 plpgsql_dstring_append(&ds, c);
1586 plpgsql_dstring_append(&ds, c);
1589 switch (estate->datums[stmt->params[pidx]]->dtype)
1591 case PLPGSQL_DTYPE_VAR:
1592 var = (PLpgSQL_var *)
1593 (estate->datums[stmt->params[pidx]]);
1598 typetup = SearchSysCache(TYPEOID,
1599 ObjectIdGetDatum(var->datatype->typoid),
1601 if (!HeapTupleIsValid(typetup))
1602 elog(ERROR, "cache lookup for type %u failed",
1603 var->datatype->typoid);
1604 typeStruct = (Form_pg_type) GETSTRUCT(typetup);
1606 fmgr_info(typeStruct->typoutput, &finfo_output);
1607 extval = DatumGetCString(FunctionCall3(&finfo_output,
1609 ObjectIdGetDatum(typeStruct->typelem),
1610 Int32GetDatum(var->datatype->atttypmod)));
1611 ReleaseSysCache(typetup);
1613 plpgsql_dstring_append(&ds, extval);
1616 case PLPGSQL_DTYPE_RECFIELD:
1617 recfield = (PLpgSQL_recfield *)
1618 (estate->datums[stmt->params[pidx]]);
1619 rec = (PLpgSQL_rec *)
1620 (estate->datums[recfield->recno]);
1621 if (!HeapTupleIsValid(rec->tup))
1625 fno = SPI_fnumber(rec->tupdesc, recfield->fieldname);
1626 if (fno == SPI_ERROR_NOATTRIBUTE)
1627 elog(ERROR, "record \"%s\" has no field named \"%s\"", rec->refname, recfield->fieldname);
1628 extval = SPI_getvalue(rec->tup, rec->tupdesc, fno);
1632 plpgsql_dstring_append(&ds, extval);
1635 case PLPGSQL_DTYPE_TRIGARG:
1637 PLpgSQL_trigarg *trigarg;
1640 bool valisnull = false;
1642 trigarg = (PLpgSQL_trigarg *)
1643 (estate->datums[stmt->params[pidx]]);
1644 value = (int) exec_eval_expr(estate, trigarg->argnum,
1645 &valisnull, &valtype);
1646 exec_eval_cleanup(estate);
1648 extval = "<INDEX_IS_NULL>";
1651 if (value < 0 || value >= estate->trig_nargs)
1652 extval = "<OUT_OF_RANGE>";
1654 extval = DatumGetCString(DirectFunctionCall1(textout,
1655 estate->trig_argv[value]));
1657 plpgsql_dstring_append(&ds, extval);
1663 plpgsql_dstring_append(&ds, c);
1671 * Occurrences of single ' are removed. double ' are reduced to
1678 plpgsql_dstring_append(&ds, c);
1683 plpgsql_dstring_append(&ds, c);
1687 * Now suppress debug info and throw the elog()
1689 if (stmt->elog_level == ERROR)
1691 error_info_func = NULL;
1692 error_info_stmt = NULL;
1693 error_info_text = NULL;
1695 elog(stmt->elog_level, "%s", plpgsql_dstring_get(&ds));
1696 plpgsql_dstring_free(&ds);
1698 return PLPGSQL_RC_OK;
1703 * Initialize an empty estate
1707 plpgsql_estate_setup(PLpgSQL_execstate * estate,
1708 PLpgSQL_function * func)
1710 estate->retval = (Datum) 0;
1711 estate->retisnull = true;
1712 estate->rettype = InvalidOid;
1713 estate->retistuple = func->fn_retistuple;
1714 estate->rettupdesc = NULL;
1715 estate->retisset = func->fn_retset;
1716 estate->exitlabel = NULL;
1718 estate->trig_nargs = 0;
1719 estate->trig_argv = NULL;
1721 estate->found_varno = func->found_varno;
1722 estate->ndatums = func->ndatums;
1723 estate->datums = palloc(sizeof(PLpgSQL_datum *) * estate->ndatums);
1724 /* caller is expected to fill the datums array */
1726 estate->eval_tuptable = NULL;
1727 estate->eval_processed = 0;
1728 estate->eval_lastoid = InvalidOid;
1729 estate->eval_econtext = NULL;
1733 * Release temporary memory used by expression/subselect evaluation
1735 * NB: the result of the evaluation is no longer valid after this is done,
1736 * unless it is a pass-by-value datatype.
1740 exec_eval_cleanup(PLpgSQL_execstate * estate)
1742 /* Clear result of a full SPI_exec */
1743 if (estate->eval_tuptable != NULL)
1744 SPI_freetuptable(estate->eval_tuptable);
1745 estate->eval_tuptable = NULL;
1747 /* Clear result of exec_eval_simple_expr */
1748 if (estate->eval_econtext != NULL)
1749 FreeExprContext(estate->eval_econtext);
1750 estate->eval_econtext = NULL;
1755 * Generate a prepared plan
1759 exec_prepare_plan(PLpgSQL_execstate * estate,
1760 PLpgSQL_expr * expr)
1764 PLpgSQL_recfield *recfield;
1771 * We need a temporary argtypes array to load with data. (The finished
1772 * plan structure will contain a copy of it.)
1774 * +1 is just to avoid palloc(0) error.
1776 argtypes = palloc(sizeof(Oid *) * (expr->nparams + 1));
1778 for (i = 0; i < expr->nparams; i++)
1780 switch (estate->datums[expr->params[i]]->dtype)
1782 case PLPGSQL_DTYPE_VAR:
1783 var = (PLpgSQL_var *) (estate->datums[expr->params[i]]);
1784 argtypes[i] = var->datatype->typoid;
1787 case PLPGSQL_DTYPE_RECFIELD:
1788 recfield = (PLpgSQL_recfield *) (estate->datums[expr->params[i]]);
1789 rec = (PLpgSQL_rec *) (estate->datums[recfield->recno]);
1791 if (!HeapTupleIsValid(rec->tup))
1792 elog(ERROR, "record \"%s\" is unassigned yet", rec->refname);
1793 fno = SPI_fnumber(rec->tupdesc, recfield->fieldname);
1794 if (fno == SPI_ERROR_NOATTRIBUTE)
1795 elog(ERROR, "record \"%s\" has no field named \"%s\"", rec->refname, recfield->fieldname);
1796 argtypes[i] = SPI_gettypeid(rec->tupdesc, fno);
1799 case PLPGSQL_DTYPE_TRIGARG:
1800 argtypes[i] = (Oid) TEXTOID;
1804 elog(ERROR, "unknown parameter dtype %d in exec_run_select()",
1805 estate->datums[expr->params[i]]->dtype);
1810 * Generate and save the plan
1812 plan = SPI_prepare(expr->query, expr->nparams, argtypes);
1814 elog(ERROR, "SPI_prepare() failed on \"%s\"", expr->query);
1815 expr->plan = SPI_saveplan(plan);
1816 expr->plan_argtypes = ((_SPI_plan *) expr->plan)->argtypes;
1817 expr->plan_simple_expr = NULL;
1818 exec_simple_check_plan(expr);
1825 * exec_stmt_execsql Execute an SQL statement not
1826 * returning any data.
1830 exec_stmt_execsql(PLpgSQL_execstate * estate,
1831 PLpgSQL_stmt_execsql * stmt)
1835 PLpgSQL_recfield *recfield;
1836 PLpgSQL_trigarg *trigarg;
1844 PLpgSQL_expr *expr = stmt->sqlstmt;
1848 * On the first call for this expression generate the plan
1850 if (expr->plan == NULL)
1851 exec_prepare_plan(estate, expr);
1854 * Now build up the values and nulls arguments for SPI_execp()
1856 values = palloc(sizeof(Datum) * (expr->nparams + 1));
1857 nulls = palloc(expr->nparams + 1);
1859 for (i = 0; i < expr->nparams; i++)
1861 switch (estate->datums[expr->params[i]]->dtype)
1863 case PLPGSQL_DTYPE_VAR:
1864 var = (PLpgSQL_var *) (estate->datums[expr->params[i]]);
1865 values[i] = var->value;
1872 case PLPGSQL_DTYPE_RECFIELD:
1873 recfield = (PLpgSQL_recfield *) (estate->datums[expr->params[i]]);
1874 rec = (PLpgSQL_rec *) (estate->datums[recfield->recno]);
1876 if (!HeapTupleIsValid(rec->tup))
1877 elog(ERROR, "record \"%s\" is unassigned yet", rec->refname);
1878 fno = SPI_fnumber(rec->tupdesc, recfield->fieldname);
1879 if (fno == SPI_ERROR_NOATTRIBUTE)
1880 elog(ERROR, "record \"%s\" has no field named \"%s\"", rec->refname, recfield->fieldname);
1882 if (expr->plan_argtypes[i] != SPI_gettypeid(rec->tupdesc, fno))
1883 elog(ERROR, "type of %s.%s doesn't match that when preparing the plan", rec->refname, recfield->fieldname);
1885 values[i] = SPI_getbinval(rec->tup, rec->tupdesc, fno, &isnull);
1892 case PLPGSQL_DTYPE_TRIGARG:
1893 trigarg = (PLpgSQL_trigarg *) (estate->datums[expr->params[i]]);
1894 tgargno = (int) exec_eval_expr(estate, trigarg->argnum,
1895 &isnull, &tgargoid);
1896 exec_eval_cleanup(estate);
1897 if (isnull || tgargno < 0 || tgargno >= estate->trig_nargs)
1904 values[i] = estate->trig_argv[tgargno];
1910 elog(ERROR, "unknown parameter dtype %d in exec_stmt_execsql()", estate->datums[expr->params[i]]->dtype);
1918 rc = SPI_execp(expr->plan, values, nulls, 0);
1921 case SPI_OK_UTILITY:
1922 case SPI_OK_SELINTO:
1929 * If the INSERT, DELETE, or UPDATE query affected at least
1930 * one tuple, set the magic 'FOUND' variable to true. This
1931 * conforms with the behavior of PL/SQL.
1933 exec_set_found(estate, (SPI_processed != 0));
1937 elog(ERROR, "SELECT query has no destination for result data."
1938 "\n\tIf you want to discard the results, use PERFORM instead.");
1941 elog(ERROR, "error executing query \"%s\"", expr->query);
1945 * Release any result tuples from SPI_execp (probably shouldn't be
1948 SPI_freetuptable(SPI_tuptable);
1950 /* Save result info for GET DIAGNOSTICS */
1951 estate->eval_processed = SPI_processed;
1952 estate->eval_lastoid = SPI_lastoid;
1957 return PLPGSQL_RC_OK;
1962 * exec_stmt_dynexecute Execute a dynamic SQL query not
1963 * returning any data.
1967 exec_stmt_dynexecute(PLpgSQL_execstate * estate,
1968 PLpgSQL_stmt_dynexecute * stmt)
1971 bool isnull = false;
1975 Form_pg_type typeStruct;
1976 FmgrInfo finfo_output;
1980 * First we evaluate the string expression after the EXECUTE keyword.
1981 * It's result is the querystring we have to execute.
1983 query = exec_eval_expr(estate, stmt->query, &isnull, &restype);
1985 elog(ERROR, "cannot EXECUTE NULL query");
1988 * Get the C-String representation.
1990 typetup = SearchSysCache(TYPEOID,
1991 ObjectIdGetDatum(restype),
1993 if (!HeapTupleIsValid(typetup))
1994 elog(ERROR, "cache lookup for type %u failed", restype);
1995 typeStruct = (Form_pg_type) GETSTRUCT(typetup);
1997 fmgr_info(typeStruct->typoutput, &finfo_output);
1998 querystr = DatumGetCString(FunctionCall3(&finfo_output,
2000 ObjectIdGetDatum(typeStruct->typelem),
2001 Int32GetDatum(-1)));
2003 ReleaseSysCache(typetup);
2004 exec_eval_cleanup(estate);
2007 * Call SPI_exec() without preparing a saved plan. The returncode can
2008 * be any standard OK. Note that while a SELECT is allowed, its
2009 * results will be discarded.
2011 exec_res = SPI_exec(querystr, 0);
2018 case SPI_OK_UTILITY:
2024 * Also allow a zero return, which implies the querystring
2025 * contained no commands.
2029 case SPI_OK_SELINTO:
2032 * We want to disallow SELECT INTO for now, because its behavior
2033 * is not consistent with SELECT INTO in a normal plpgsql
2034 * context. (We need to reimplement EXECUTE to parse the string
2035 * as a plpgsql command, not just feed it to SPI_exec.)
2036 * However, CREATE AS should be allowed ... and since it produces
2037 * the same parsetree as SELECT INTO, there's no way to tell
2038 * the difference except to look at the source text. Wotta
2044 for (ptr = querystr; *ptr; ptr++)
2045 if (!isspace((unsigned char) *ptr))
2047 if (*ptr == 'S' || *ptr == 's')
2048 elog(ERROR, "EXECUTE of SELECT ... INTO is not implemented yet");
2053 elog(ERROR, "unexpected error %d in EXECUTE of query '%s'",
2054 exec_res, querystr);
2058 /* Release any result from SPI_exec, as well as the querystring */
2059 SPI_freetuptable(SPI_tuptable);
2062 /* Save result info for GET DIAGNOSTICS */
2063 estate->eval_processed = SPI_processed;
2064 estate->eval_lastoid = SPI_lastoid;
2066 return PLPGSQL_RC_OK;
2071 * exec_stmt_dynfors Execute a dynamic query, assign each
2072 * tuple to a record or row and
2073 * execute a group of statements
2078 exec_stmt_dynfors(PLpgSQL_execstate * estate, PLpgSQL_stmt_dynfors * stmt)
2081 bool isnull = false;
2084 PLpgSQL_rec *rec = NULL;
2085 PLpgSQL_row *row = NULL;
2086 SPITupleTable *tuptab;
2087 int rc = PLPGSQL_RC_OK;
2091 Form_pg_type typeStruct;
2092 FmgrInfo finfo_output;
2098 * Determine if we assign to a record or a row
2100 if (stmt->rec != NULL)
2101 rec = (PLpgSQL_rec *) (estate->datums[stmt->rec->recno]);
2104 if (stmt->row != NULL)
2105 row = (PLpgSQL_row *) (estate->datums[stmt->row->rowno]);
2107 elog(ERROR, "unsupported target in exec_stmt_fors()");
2111 * Evaluate the string expression after the EXECUTE keyword. It's
2112 * result is the querystring we have to execute.
2114 query = exec_eval_expr(estate, stmt->query, &isnull, &restype);
2116 elog(ERROR, "cannot EXECUTE NULL-query");
2119 * Get the C-String representation.
2121 typetup = SearchSysCache(TYPEOID,
2122 ObjectIdGetDatum(restype),
2124 if (!HeapTupleIsValid(typetup))
2125 elog(ERROR, "cache lookup for type %u failed", restype);
2126 typeStruct = (Form_pg_type) GETSTRUCT(typetup);
2128 fmgr_info(typeStruct->typoutput, &finfo_output);
2129 querystr = DatumGetCString(FunctionCall3(&finfo_output,
2131 ObjectIdGetDatum(typeStruct->typelem),
2132 Int32GetDatum(-1)));
2134 ReleaseSysCache(typetup);
2135 exec_eval_cleanup(estate);
2138 * Prepare a plan and open an implicit cursor for the query
2140 plan = SPI_prepare(querystr, 0, NULL);
2142 elog(ERROR, "SPI_prepare() failed for dynamic query \"%s\"", querystr);
2143 portal = SPI_cursor_open(NULL, plan, NULL, NULL);
2145 elog(ERROR, "failed to open implicit cursor for dynamic query \"%s\"",
2151 * Fetch the initial 10 tuples
2153 SPI_cursor_fetch(portal, true, 10);
2155 tuptab = SPI_tuptable;
2158 * If the query didn't return any rows, set the target to NULL and
2159 * return with FOUND = false.
2162 exec_move_row(estate, rec, row, NULL, NULL);
2171 for (i = 0; i < n; i++)
2174 * Assign the tuple to the target
2176 exec_move_row(estate, rec, row, tuptab->vals[i], tuptab->tupdesc);
2179 * Execute the statements
2181 rc = exec_stmts(estate, stmt->body);
2184 * We're aborting the loop, so cleanup and set FOUND
2186 if (rc != PLPGSQL_RC_OK)
2188 exec_set_found(estate, found);
2189 SPI_freetuptable(tuptab);
2190 SPI_cursor_close(portal);
2192 if (rc == PLPGSQL_RC_EXIT)
2194 if (estate->exitlabel == NULL)
2195 /* unlabelled exit, finish the current loop */
2197 else if (stmt->label != NULL &&
2198 strcmp(stmt->label, estate->exitlabel) == 0)
2200 /* labelled exit, matches the current stmt's label */
2201 estate->exitlabel = NULL;
2206 * otherwise, we processed a labelled exit that does not
2207 * match the current statement's label, if any: return
2208 * RC_EXIT so that the EXIT continues to recurse upward.
2216 SPI_freetuptable(tuptab);
2219 * Fetch the next 50 tuples
2221 SPI_cursor_fetch(portal, true, 50);
2223 tuptab = SPI_tuptable;
2229 SPI_cursor_close(portal);
2232 * Set the FOUND variable to indicate the result of executing the
2233 * loop (namely, whether we looped one or more times). This must be
2234 * set here so that it does not interfere with the value of the
2235 * FOUND variable inside the loop processing itself.
2237 exec_set_found(estate, found);
2239 return PLPGSQL_RC_OK;
2244 * exec_stmt_open Execute an OPEN cursor statement
2248 exec_stmt_open(PLpgSQL_execstate * estate, PLpgSQL_stmt_open * stmt)
2250 PLpgSQL_var *curvar = NULL;
2251 char *curname = NULL;
2252 PLpgSQL_expr *query = NULL;
2257 PLpgSQL_recfield *recfield;
2258 PLpgSQL_trigarg *trigarg;
2269 * Get the cursor variable and if it has an assigned name, check
2270 * that it's not in use currently.
2273 curvar = (PLpgSQL_var *) (estate->datums[stmt->curvar]);
2274 if (!curvar->isnull)
2276 curname = DatumGetCString(DirectFunctionCall1(textout, curvar->value));
2277 if (SPI_cursor_find(curname) != NULL)
2278 elog(ERROR, "cursor \"%s\" already in use", curname);
2282 * Process the OPEN according to it's type.
2285 if (stmt->query != NULL)
2288 * This is an OPEN refcursor FOR SELECT ...
2290 * We just make sure the query is planned. The real work is
2294 query = stmt->query;
2295 if (query->plan == NULL)
2296 exec_prepare_plan(estate, query);
2298 else if (stmt->dynquery != NULL)
2301 * This is an OPEN refcursor FOR EXECUTE ...
2308 Form_pg_type typeStruct;
2309 FmgrInfo finfo_output;
2313 * We evaluate the string expression after the
2314 * EXECUTE keyword. It's result is the querystring we have
2318 queryD = exec_eval_expr(estate, stmt->dynquery, &isnull, &restype);
2320 elog(ERROR, "cannot EXECUTE NULL query");
2323 * Get the C-String representation.
2326 typetup = SearchSysCache(TYPEOID,
2327 ObjectIdGetDatum(restype),
2329 if (!HeapTupleIsValid(typetup))
2330 elog(ERROR, "cache lookup for type %u failed", restype);
2331 typeStruct = (Form_pg_type) GETSTRUCT(typetup);
2333 fmgr_info(typeStruct->typoutput, &finfo_output);
2334 querystr = DatumGetCString(FunctionCall3(&finfo_output,
2336 ObjectIdGetDatum(typeStruct->typelem),
2337 Int32GetDatum(-1)));
2339 ReleaseSysCache(typetup);
2340 exec_eval_cleanup(estate);
2343 * Now we prepare a query plan for it and open a cursor
2346 curplan = SPI_prepare(querystr, 0, NULL);
2347 portal = SPI_cursor_open(curname, curplan, NULL, NULL);
2349 elog(ERROR, "Failed to open cursor");
2353 * Store the eventually assigned cursor name in the cursor variable
2356 if (curvar->freeval)
2357 pfree((void *) (curvar->value));
2359 curvar->value = DirectFunctionCall1(textin, CStringGetDatum(portal->name));
2360 curvar->isnull = false;
2361 curvar->freeval = true;
2363 return PLPGSQL_RC_OK;
2368 * This is an OPEN cursor
2370 * Note: parser should already have checked that statement supplies
2371 * args iff cursor needs them, but we check again to be safe.
2374 if (stmt->argquery != NULL)
2377 * Er - OPEN CURSOR (args). We fake a SELECT ... INTO ...
2378 * statement to evaluate the args and put 'em into the
2382 PLpgSQL_stmt_select set_args;
2384 if (curvar->cursor_explicit_argrow < 0)
2385 elog(ERROR, "arguments given for cursor without arguments");
2387 memset(&set_args, 0, sizeof(set_args));
2388 set_args.cmd_type = PLPGSQL_STMT_SELECT;
2389 set_args.lineno = stmt->lineno;
2390 set_args.row = (PLpgSQL_row *)
2391 (estate->datums[curvar->cursor_explicit_argrow]);
2392 set_args.query = stmt->argquery;
2394 if (exec_stmt_select(estate, &set_args) != PLPGSQL_RC_OK)
2395 elog(ERROR, "open cursor failed during argument processing");
2399 if (curvar->cursor_explicit_argrow >= 0)
2400 elog(ERROR, "arguments required for cursor");
2403 query = curvar->cursor_explicit_expr;
2404 if (query->plan == NULL)
2405 exec_prepare_plan(estate, query);
2409 * Here we go if we have a saved plan where we have to put
2410 * values into, either from an explicit cursor or from a
2411 * refcursor opened with OPEN ... FOR SELECT ...;
2414 values = palloc(sizeof(Datum) * (query->nparams + 1));
2415 nulls = palloc(query->nparams + 1);
2417 for (i = 0; i < query->nparams; i++)
2419 switch (estate->datums[query->params[i]]->dtype)
2421 case PLPGSQL_DTYPE_VAR:
2422 var = (PLpgSQL_var *) (estate->datums[query->params[i]]);
2423 values[i] = var->value;
2430 case PLPGSQL_DTYPE_RECFIELD:
2431 recfield = (PLpgSQL_recfield *) (estate->datums[query->params[i]]);
2432 rec = (PLpgSQL_rec *) (estate->datums[recfield->recno]);
2434 if (!HeapTupleIsValid(rec->tup))
2435 elog(ERROR, "record \"%s\" is unassigned yet", rec->refname);
2436 fno = SPI_fnumber(rec->tupdesc, recfield->fieldname);
2437 if (fno == SPI_ERROR_NOATTRIBUTE)
2438 elog(ERROR, "record \"%s\" has no field named \"%s\"", rec->refname, recfield->fieldname);
2440 if (query->plan_argtypes[i] != SPI_gettypeid(rec->tupdesc, fno))
2441 elog(ERROR, "type of %s.%s doesn't match that when preparing the plan", rec->refname, recfield->fieldname);
2443 values[i] = SPI_getbinval(rec->tup, rec->tupdesc, fno, &isnull);
2450 case PLPGSQL_DTYPE_TRIGARG:
2451 trigarg = (PLpgSQL_trigarg *) (estate->datums[query->params[i]]);
2452 tgargno = (int) exec_eval_expr(estate, trigarg->argnum,
2453 &isnull, &tgargoid);
2454 exec_eval_cleanup(estate);
2455 if (isnull || tgargno < 0 || tgargno >= estate->trig_nargs)
2462 values[i] = estate->trig_argv[tgargno];
2468 elog(ERROR, "unknown parameter dtype %d in exec_stmt_open()",
2469 estate->datums[query->params[i]]->dtype);
2478 portal = SPI_cursor_open(curname, query->plan, values, nulls);
2480 elog(ERROR, "Failed to open cursor");
2488 * Store the eventually assigned portal name in the cursor variable
2491 if (curvar->freeval)
2492 pfree((void *) (curvar->value));
2494 curvar->value = DirectFunctionCall1(textin, CStringGetDatum(portal->name));
2495 curvar->isnull = false;
2496 curvar->freeval = true;
2498 return PLPGSQL_RC_OK;
2503 * exec_stmt_fetch Fetch from a cursor into a target
2507 exec_stmt_fetch(PLpgSQL_execstate * estate, PLpgSQL_stmt_fetch * stmt)
2509 PLpgSQL_var *curvar = NULL;
2510 PLpgSQL_rec *rec = NULL;
2511 PLpgSQL_row *row = NULL;
2512 SPITupleTable *tuptab;
2518 * Get the portal of the cursor by name
2521 curvar = (PLpgSQL_var *) (estate->datums[stmt->curvar]);
2523 elog(ERROR, "cursor variable \"%s\" is NULL", curvar->refname);
2524 curname = DatumGetCString(DirectFunctionCall1(textout, curvar->value));
2526 portal = SPI_cursor_find(curname);
2528 elog(ERROR, "cursor \"%s\" is invalid", curname);
2532 * Initialize the global found variable to false
2535 exec_set_found(estate, false);
2538 * Determine if we fetch into a record or a row
2541 if (stmt->rec != NULL)
2542 rec = (PLpgSQL_rec *) (estate->datums[stmt->rec->recno]);
2545 if (stmt->row != NULL)
2546 row = (PLpgSQL_row *) (estate->datums[stmt->row->rowno]);
2548 elog(ERROR, "unsupported target in exec_stmt_select()");
2552 * Fetch 1 tuple from the cursor
2555 SPI_cursor_fetch(portal, true, 1);
2557 tuptab = SPI_tuptable;
2560 * If the FETCH didn't return a row, set the target
2561 * to NULL and return with FOUND = false.
2566 exec_move_row(estate, rec, row, NULL, NULL);
2567 return PLPGSQL_RC_OK;
2571 * Put the result into the target and set found to true
2574 exec_move_row(estate, rec, row, tuptab->vals[0], tuptab->tupdesc);
2575 exec_set_found(estate, true);
2577 SPI_freetuptable(tuptab);
2579 return PLPGSQL_RC_OK;
2584 * exec_stmt_close Close a cursor
2588 exec_stmt_close(PLpgSQL_execstate * estate, PLpgSQL_stmt_close * stmt)
2590 PLpgSQL_var *curvar = NULL;
2595 * Get the portal of the cursor by name
2598 curvar = (PLpgSQL_var *) (estate->datums[stmt->curvar]);
2600 elog(ERROR, "cursor variable \"%s\" is NULL", curvar->refname);
2601 curname = DatumGetCString(DirectFunctionCall1(textout, curvar->value));
2603 portal = SPI_cursor_find(curname);
2605 elog(ERROR, "cursor \"%s\" is invalid", curname);
2612 SPI_cursor_close(portal);
2614 return PLPGSQL_RC_OK;
2619 * exec_assign_expr Put an expression's result into
2624 exec_assign_expr(PLpgSQL_execstate * estate, PLpgSQL_datum * target,
2625 PLpgSQL_expr * expr)
2629 bool isnull = false;
2631 value = exec_eval_expr(estate, expr, &isnull, &valtype);
2632 exec_assign_value(estate, target, value, valtype, &isnull);
2633 exec_eval_cleanup(estate);
2638 * exec_assign_value Put a value into a target field
2642 exec_assign_value(PLpgSQL_execstate * estate,
2643 PLpgSQL_datum * target,
2644 Datum value, Oid valtype, bool *isNull)
2648 PLpgSQL_recfield *recfield;
2661 Form_pg_type typeStruct;
2662 FmgrInfo finfo_input;
2664 switch (target->dtype)
2666 case PLPGSQL_DTYPE_VAR:
2669 * Target field is a variable
2671 var = (PLpgSQL_var *) target;
2675 pfree(DatumGetPointer(var->value));
2676 var->freeval = false;
2679 newvalue = exec_cast_value(value, valtype, var->datatype->typoid,
2680 &(var->datatype->typinput),
2681 var->datatype->typelem,
2682 var->datatype->atttypmod,
2685 if (*isNull && var->notnull)
2686 elog(ERROR, "NULL assignment to variable '%s' declared NOT NULL", var->refname);
2689 * If type is by-reference, make sure we have a freshly
2690 * palloc'd copy; the originally passed value may not live as
2691 * long as the variable! But we don't need to re-copy if
2692 * exec_cast_value performed a conversion; its output must
2693 * already be palloc'd.
2695 if (!var->datatype->typbyval && !*isNull)
2697 if (newvalue == value)
2698 var->value = datumCopy(newvalue,
2700 var->datatype->typlen);
2702 var->value = newvalue;
2703 var->freeval = true;
2706 var->value = newvalue;
2707 var->isnull = *isNull;
2710 case PLPGSQL_DTYPE_RECFIELD:
2713 * Target field is a record
2715 recfield = (PLpgSQL_recfield *) target;
2716 rec = (PLpgSQL_rec *) (estate->datums[recfield->recno]);
2719 * Check that there is already a tuple in the record. We need
2720 * that because records don't have any predefined field
2723 if (!HeapTupleIsValid(rec->tup))
2724 elog(ERROR, "record \"%s\" is unassigned yet - don't know its tuple structure", rec->refname);
2727 * Get the number of the records field to change and the
2728 * number of attributes in the tuple.
2730 fno = SPI_fnumber(rec->tupdesc, recfield->fieldname);
2731 if (fno == SPI_ERROR_NOATTRIBUTE)
2732 elog(ERROR, "record \"%s\" has no field named \"%s\"", rec->refname, recfield->fieldname);
2734 natts = rec->tupdesc->natts;
2737 * Set up values/datums arrays for heap_formtuple. For all
2738 * the attributes except the one we want to replace, use the
2739 * value that's in the old tuple.
2741 values = palloc(sizeof(Datum) * natts);
2742 nulls = palloc(natts);
2744 for (i = 0; i < natts; i++)
2748 values[i] = SPI_getbinval(rec->tup, rec->tupdesc,
2757 * Now insert the new value, being careful to cast it to the
2760 atttype = SPI_gettypeid(rec->tupdesc, fno + 1);
2761 atttypmod = rec->tupdesc->attrs[fno]->atttypmod;
2762 typetup = SearchSysCache(TYPEOID,
2763 ObjectIdGetDatum(atttype),
2765 if (!HeapTupleIsValid(typetup))
2766 elog(ERROR, "cache lookup for type %u failed", atttype);
2767 typeStruct = (Form_pg_type) GETSTRUCT(typetup);
2768 fmgr_info(typeStruct->typinput, &finfo_input);
2770 attisnull = *isNull;
2771 values[fno] = exec_cast_value(value, valtype,
2772 atttype, &finfo_input,
2773 typeStruct->typelem,
2774 atttypmod, &attisnull);
2781 * Avoid leaking the result of exec_cast_value, if it
2782 * performed a conversion to a pass-by-ref type.
2784 if (!typeStruct->typbyval && !attisnull && values[fno] != value)
2785 mustfree = DatumGetPointer(values[fno]);
2789 ReleaseSysCache(typetup);
2792 * Now call heap_formtuple() to create a new tuple that
2793 * replaces the old one in the record.
2795 newtup = heap_formtuple(rec->tupdesc, values, nulls);
2798 heap_freetuple(rec->tup);
2801 rec->freetup = true;
2811 elog(ERROR, "unknown dtype %d in exec_assign_value()",
2818 * exec_eval_expr Evaluate an expression and return
2821 * NOTE: caller must do exec_eval_cleanup when done with the Datum.
2825 exec_eval_expr(PLpgSQL_execstate * estate,
2826 PLpgSQL_expr * expr,
2833 * If not already done create a plan for this expression
2835 if (expr->plan == NULL)
2836 exec_prepare_plan(estate, expr);
2839 * If this is a simple expression, bypass SPI and use the executor
2842 if (expr->plan_simple_expr != NULL)
2843 return exec_eval_simple_expr(estate, expr, isNull, rettype);
2845 rc = exec_run_select(estate, expr, 2, NULL);
2846 if (rc != SPI_OK_SELECT)
2847 elog(ERROR, "query \"%s\" didn't return data", expr->query);
2850 * If there are no rows selected, the result is NULL.
2852 if (estate->eval_processed == 0)
2859 * Check that the expression returned one single Datum
2861 if (estate->eval_processed > 1)
2862 elog(ERROR, "query \"%s\" returned more than one row", expr->query);
2863 if (estate->eval_tuptable->tupdesc->natts != 1)
2864 elog(ERROR, "query \"%s\" returned %d columns", expr->query,
2865 estate->eval_tuptable->tupdesc->natts);
2868 * Return the result and its type
2870 *rettype = SPI_gettypeid(estate->eval_tuptable->tupdesc, 1);
2871 return SPI_getbinval(estate->eval_tuptable->vals[0],
2872 estate->eval_tuptable->tupdesc, 1, isNull);
2877 * exec_run_select Execute a select query
2881 exec_run_select(PLpgSQL_execstate * estate,
2882 PLpgSQL_expr * expr, int maxtuples, Portal *portalP)
2886 PLpgSQL_recfield *recfield;
2887 PLpgSQL_trigarg *trigarg;
2898 * On the first call for this expression generate the plan
2900 if (expr->plan == NULL)
2901 exec_prepare_plan(estate, expr);
2904 * Now build up the values and nulls arguments for SPI_execp()
2906 values = palloc(sizeof(Datum) * (expr->nparams + 1));
2907 nulls = palloc(expr->nparams + 1);
2909 for (i = 0; i < expr->nparams; i++)
2911 switch (estate->datums[expr->params[i]]->dtype)
2913 case PLPGSQL_DTYPE_VAR:
2914 var = (PLpgSQL_var *) (estate->datums[expr->params[i]]);
2915 values[i] = var->value;
2922 case PLPGSQL_DTYPE_RECFIELD:
2923 recfield = (PLpgSQL_recfield *) (estate->datums[expr->params[i]]);
2924 rec = (PLpgSQL_rec *) (estate->datums[recfield->recno]);
2926 if (!HeapTupleIsValid(rec->tup))
2927 elog(ERROR, "record \"%s\" is unassigned yet", rec->refname);
2928 fno = SPI_fnumber(rec->tupdesc, recfield->fieldname);
2929 if (fno == SPI_ERROR_NOATTRIBUTE)
2930 elog(ERROR, "record \"%s\" has no field named \"%s\"", rec->refname, recfield->fieldname);
2932 if (expr->plan_argtypes[i] != SPI_gettypeid(rec->tupdesc, fno))
2933 elog(ERROR, "type of %s.%s doesn't match that when preparing the plan", rec->refname, recfield->fieldname);
2935 values[i] = SPI_getbinval(rec->tup, rec->tupdesc, fno, &isnull);
2942 case PLPGSQL_DTYPE_TRIGARG:
2943 trigarg = (PLpgSQL_trigarg *) (estate->datums[expr->params[i]]);
2944 tgargno = (int) exec_eval_expr(estate, trigarg->argnum,
2945 &isnull, &tgargoid);
2946 exec_eval_cleanup(estate);
2947 if (isnull || tgargno < 0 || tgargno >= estate->trig_nargs)
2954 values[i] = estate->trig_argv[tgargno];
2960 elog(ERROR, "unknown parameter dtype %d in exec_eval_expr()",
2961 estate->datums[expr->params[i]]->dtype);
2967 * If a portal was requested, put the query into the portal
2969 if (portalP != NULL)
2971 *portalP = SPI_cursor_open(NULL, expr->plan, values, nulls);
2972 if (*portalP == NULL)
2973 elog(ERROR, "failed to open implicit cursor for \"%s\"",
2977 return SPI_OK_CURSOR;
2983 rc = SPI_execp(expr->plan, values, nulls, maxtuples);
2984 if (rc != SPI_OK_SELECT)
2985 elog(ERROR, "query \"%s\" isn't a SELECT", expr->query);
2987 /* Save query results for eventual cleanup */
2988 Assert(estate->eval_tuptable == NULL);
2989 estate->eval_tuptable = SPI_tuptable;
2990 estate->eval_processed = SPI_processed;
2991 estate->eval_lastoid = SPI_lastoid;
3001 * exec_eval_simple_expr - Evaluate a simple expression returning
3002 * a Datum by directly calling ExecEvalExpr().
3006 exec_eval_simple_expr(PLpgSQL_execstate * estate,
3007 PLpgSQL_expr * expr,
3011 _SPI_plan *spi_plan = (_SPI_plan *) expr->plan;
3015 PLpgSQL_recfield *recfield;
3016 PLpgSQL_trigarg *trigarg;
3022 ExprContext *econtext;
3023 ParamListInfo paramLI;
3026 * Create a simple expression context to hold the arguments.
3028 * NOTE: we pass the SPI plan's context as the query-lifetime context for
3029 * function cache nodes and suchlike allocations. This is appropriate
3030 * because that's where the expression tree itself is, and the
3031 * function cache nodes must live as long as it does.
3033 econtext = MakeExprContext(NULL, spi_plan->plancxt);
3036 * Param list can live in econtext's temporary memory context.
3038 paramLI = (ParamListInfo)
3039 MemoryContextAlloc(econtext->ecxt_per_tuple_memory,
3040 (expr->nparams + 1) * sizeof(ParamListInfoData));
3041 econtext->ecxt_param_list_info = paramLI;
3044 * Put the parameter values into the parameter list info of the
3045 * expression context.
3047 for (i = 0; i < expr->nparams; i++, paramLI++)
3049 paramLI->kind = PARAM_NUM;
3050 paramLI->id = i + 1;
3052 switch (estate->datums[expr->params[i]]->dtype)
3054 case PLPGSQL_DTYPE_VAR:
3055 var = (PLpgSQL_var *) (estate->datums[expr->params[i]]);
3056 paramLI->isnull = var->isnull;
3057 paramLI->value = var->value;
3060 case PLPGSQL_DTYPE_RECFIELD:
3061 recfield = (PLpgSQL_recfield *) (estate->datums[expr->params[i]]);
3062 rec = (PLpgSQL_rec *) (estate->datums[recfield->recno]);
3064 if (!HeapTupleIsValid(rec->tup))
3065 elog(ERROR, "record \"%s\" is unassigned yet", rec->refname);
3066 fno = SPI_fnumber(rec->tupdesc, recfield->fieldname);
3067 if (fno == SPI_ERROR_NOATTRIBUTE)
3068 elog(ERROR, "record \"%s\" has no field named \"%s\"", rec->refname, recfield->fieldname);
3070 if (expr->plan_argtypes[i] != SPI_gettypeid(rec->tupdesc, fno))
3071 elog(ERROR, "type of %s.%s doesn't match that when preparing the plan", rec->refname, recfield->fieldname);
3073 paramLI->value = SPI_getbinval(rec->tup, rec->tupdesc, fno, &isnull);
3074 paramLI->isnull = isnull;
3077 case PLPGSQL_DTYPE_TRIGARG:
3078 trigarg = (PLpgSQL_trigarg *) (estate->datums[expr->params[i]]);
3079 tgargno = (int) exec_eval_expr(estate, trigarg->argnum,
3080 &isnull, &tgargoid);
3081 exec_eval_cleanup(estate);
3082 if (isnull || tgargno < 0 || tgargno >= estate->trig_nargs)
3085 paramLI->isnull = TRUE;
3089 paramLI->value = estate->trig_argv[tgargno];
3090 paramLI->isnull = FALSE;
3095 elog(ERROR, "unknown parameter dtype %d in exec_eval_simple_expr()", estate->datums[expr->params[i]]->dtype);
3098 paramLI->kind = PARAM_INVALID;
3103 *rettype = expr->plan_simple_type;
3106 * Now call the executor to evaluate the expression
3109 retval = ExecEvalExprSwitchContext(expr->plan_simple_expr,
3116 * Note: if pass-by-reference, the result is in the econtext's
3117 * temporary memory context. It will be freed when exec_eval_cleanup
3120 Assert(estate->eval_econtext == NULL);
3121 estate->eval_econtext = econtext;
3131 * exec_move_row Move one tuple's values into a record or row
3135 exec_move_row(PLpgSQL_execstate * estate,
3138 HeapTuple tup, TupleDesc tupdesc)
3141 * Record is simple - just put the tuple and its descriptor into the
3148 heap_freetuple(rec->tup);
3149 rec->freetup = false;
3151 if (rec->freetupdesc)
3153 FreeTupleDesc(rec->tupdesc);
3154 rec->freetupdesc = false;
3157 if (HeapTupleIsValid(tup))
3159 rec->tup = heap_copytuple(tup);
3160 rec->tupdesc = CreateTupleDescCopy(tupdesc);
3161 rec->freetup = true;
3162 rec->freetupdesc = true;
3167 rec->tupdesc = NULL;
3174 * Row is a bit more complicated in that we assign the individual
3175 * attributes of the tuple to the variables the row points to.
3177 * NOTE: this code used to demand row->nfields == tup->t_data->t_natts,
3178 * but that's wrong. The tuple might have more fields than we
3179 * expected if it's from an inheritance-child table of the current
3180 * table, or it might have fewer if the table has had columns added by
3181 * ALTER TABLE. Ignore extra columns and assume NULL for missing
3182 * columns, the same as heap_getattr would do.
3189 if (HeapTupleIsValid(tup))
3190 t_natts = tup->t_data->t_natts;
3194 for (i = 0; i < row->nfields; i++)
3201 var = (PLpgSQL_var *) (estate->datums[row->varnos[i]]);
3204 value = SPI_getbinval(tup, tupdesc, i + 1, &isnull);
3205 valtype = SPI_gettypeid(tupdesc, i + 1);
3211 valtype = InvalidOid;
3214 exec_assign_value(estate, estate->datums[row->varnos[i]],
3215 value, valtype, &isnull);
3221 elog(ERROR, "unsupported target in exec_move_row()");
3226 * exec_cast_value Cast a value if required
3230 exec_cast_value(Datum value, Oid valtype,
3240 * If the type of the queries return value isn't that of the
3241 * variable, convert it.
3243 if (valtype != reqtype || reqtypmod != -1)
3246 Form_pg_type typeStruct;
3247 FmgrInfo finfo_output;
3250 typetup = SearchSysCache(TYPEOID,
3251 ObjectIdGetDatum(valtype),
3253 if (!HeapTupleIsValid(typetup))
3254 elog(ERROR, "cache lookup for type %u failed", valtype);
3255 typeStruct = (Form_pg_type) GETSTRUCT(typetup);
3257 fmgr_info(typeStruct->typoutput, &finfo_output);
3258 extval = DatumGetCString(FunctionCall3(&finfo_output,
3260 ObjectIdGetDatum(typeStruct->typelem),
3261 Int32GetDatum(-1)));
3262 value = FunctionCall3(reqinput,
3263 CStringGetDatum(extval),
3264 ObjectIdGetDatum(reqtypelem),
3265 Int32GetDatum(reqtypmod));
3267 ReleaseSysCache(typetup);
3276 * exec_simple_check_node - Recursively check if an expression
3277 * is made only of simple things we can
3278 * hand out directly to ExecEvalExpr()
3279 * instead of calling SPI.
3283 exec_simple_check_node(Node *node)
3285 switch (nodeTag(node))
3289 Expr *expr = (Expr *) node;
3292 switch (expr->opType)
3305 foreach(l, expr->args)
3307 if (!exec_simple_check_node(lfirst(l)))
3321 return exec_simple_check_node(((RelabelType *) node)->arg);
3330 * exec_simple_check_plan - Check if a plan is simple enough to
3331 * be evaluated by ExecEvalExpr() instead
3336 exec_simple_check_plan(PLpgSQL_expr * expr)
3338 _SPI_plan *spi_plan = (_SPI_plan *) expr->plan;
3342 expr->plan_simple_expr = NULL;
3345 * 1. We can only evaluate queries that resulted in one single
3348 if (length(spi_plan->ptlist) != 1)
3351 plan = (Plan *) lfirst(spi_plan->ptlist);
3354 * 2. It must be a RESULT plan --> no scan's required
3356 if (plan == NULL) /* utility statement produces this */
3359 if (!IsA(plan, Result))
3363 * 3. Can't have any subplan or qual clause, either
3365 if (plan->lefttree != NULL ||
3366 plan->righttree != NULL ||
3367 plan->initPlan != NULL ||
3368 plan->subPlan != NULL ||
3369 plan->qual != NULL ||
3370 ((Result *) plan)->resconstantqual != NULL)
3374 * 4. The plan must have a single attribute as result
3376 if (length(plan->targetlist) != 1)
3379 tle = (TargetEntry *) lfirst(plan->targetlist);
3382 * 5. Check that all the nodes in the expression are one of Expr,
3385 if (!exec_simple_check_node(tle->expr))
3389 * Yes - this is a simple expression. Remember the expression and the
3392 expr->plan_simple_expr = tle->expr;
3393 expr->plan_simple_type = exprType(tle->expr);
3397 * exec_set_found Set the global found variable
3402 exec_set_found(PLpgSQL_execstate * estate, bool state)
3406 var = (PLpgSQL_var *) (estate->datums[estate->found_varno]);
3407 var->value = (Datum) state;
3408 var->isnull = false;