Header And Logo

PostgreSQL
| The world's most advanced open source database.

pl_exec.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * pl_exec.c        - Executor for the PL/pgSQL
00004  *            procedural language
00005  *
00006  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00007  * Portions Copyright (c) 1994, Regents of the University of California
00008  *
00009  *
00010  * IDENTIFICATION
00011  *    src/pl/plpgsql/src/pl_exec.c
00012  *
00013  *-------------------------------------------------------------------------
00014  */
00015 
00016 #include "plpgsql.h"
00017 
00018 #include <ctype.h>
00019 
00020 #include "access/htup_details.h"
00021 #include "access/transam.h"
00022 #include "access/tupconvert.h"
00023 #include "catalog/pg_proc.h"
00024 #include "catalog/pg_type.h"
00025 #include "executor/spi.h"
00026 #include "funcapi.h"
00027 #include "miscadmin.h"
00028 #include "nodes/nodeFuncs.h"
00029 #include "parser/scansup.h"
00030 #include "storage/proc.h"
00031 #include "tcop/tcopprot.h"
00032 #include "utils/array.h"
00033 #include "utils/builtins.h"
00034 #include "utils/datum.h"
00035 #include "utils/lsyscache.h"
00036 #include "utils/memutils.h"
00037 #include "utils/rel.h"
00038 #include "utils/snapmgr.h"
00039 #include "utils/typcache.h"
00040 
00041 
00042 static const char *const raise_skip_msg = "RAISE";
00043 
00044 typedef struct
00045 {
00046     int         nargs;          /* number of arguments */
00047     Oid        *types;          /* types of arguments */
00048     Datum      *values;         /* evaluated argument values */
00049     char       *nulls;          /* null markers (' '/'n' style) */
00050     bool       *freevals;       /* which arguments are pfree-able */
00051 } PreparedParamsData;
00052 
00053 /*
00054  * All plpgsql function executions within a single transaction share the same
00055  * executor EState for evaluating "simple" expressions.  Each function call
00056  * creates its own "eval_econtext" ExprContext within this estate for
00057  * per-evaluation workspace.  eval_econtext is freed at normal function exit,
00058  * and the EState is freed at transaction end (in case of error, we assume
00059  * that the abort mechanisms clean it all up).  Furthermore, any exception
00060  * block within a function has to have its own eval_econtext separate from
00061  * the containing function's, so that we can clean up ExprContext callbacks
00062  * properly at subtransaction exit.  We maintain a stack that tracks the
00063  * individual econtexts so that we can clean up correctly at subxact exit.
00064  *
00065  * This arrangement is a bit tedious to maintain, but it's worth the trouble
00066  * so that we don't have to re-prepare simple expressions on each trip through
00067  * a function.  (We assume the case to optimize is many repetitions of a
00068  * function within a transaction.)
00069  */
00070 typedef struct SimpleEcontextStackEntry
00071 {
00072     ExprContext *stack_econtext;    /* a stacked econtext */
00073     SubTransactionId xact_subxid;       /* ID for current subxact */
00074     struct SimpleEcontextStackEntry *next;      /* next stack entry up */
00075 } SimpleEcontextStackEntry;
00076 
00077 static EState *simple_eval_estate = NULL;
00078 static SimpleEcontextStackEntry *simple_econtext_stack = NULL;
00079 
00080 /************************************************************
00081  * Local function forward declarations
00082  ************************************************************/
00083 static void plpgsql_exec_error_callback(void *arg);
00084 static PLpgSQL_datum *copy_plpgsql_datum(PLpgSQL_datum *datum);
00085 
00086 static int exec_stmt_block(PLpgSQL_execstate *estate,
00087                 PLpgSQL_stmt_block *block);
00088 static int exec_stmts(PLpgSQL_execstate *estate,
00089            List *stmts);
00090 static int exec_stmt(PLpgSQL_execstate *estate,
00091           PLpgSQL_stmt *stmt);
00092 static int exec_stmt_assign(PLpgSQL_execstate *estate,
00093                  PLpgSQL_stmt_assign *stmt);
00094 static int exec_stmt_perform(PLpgSQL_execstate *estate,
00095                   PLpgSQL_stmt_perform *stmt);
00096 static int exec_stmt_getdiag(PLpgSQL_execstate *estate,
00097                   PLpgSQL_stmt_getdiag *stmt);
00098 static int exec_stmt_if(PLpgSQL_execstate *estate,
00099              PLpgSQL_stmt_if *stmt);
00100 static int exec_stmt_case(PLpgSQL_execstate *estate,
00101                PLpgSQL_stmt_case *stmt);
00102 static int exec_stmt_loop(PLpgSQL_execstate *estate,
00103                PLpgSQL_stmt_loop *stmt);
00104 static int exec_stmt_while(PLpgSQL_execstate *estate,
00105                 PLpgSQL_stmt_while *stmt);
00106 static int exec_stmt_fori(PLpgSQL_execstate *estate,
00107                PLpgSQL_stmt_fori *stmt);
00108 static int exec_stmt_fors(PLpgSQL_execstate *estate,
00109                PLpgSQL_stmt_fors *stmt);
00110 static int exec_stmt_forc(PLpgSQL_execstate *estate,
00111                PLpgSQL_stmt_forc *stmt);
00112 static int exec_stmt_foreach_a(PLpgSQL_execstate *estate,
00113                     PLpgSQL_stmt_foreach_a *stmt);
00114 static int exec_stmt_open(PLpgSQL_execstate *estate,
00115                PLpgSQL_stmt_open *stmt);
00116 static int exec_stmt_fetch(PLpgSQL_execstate *estate,
00117                 PLpgSQL_stmt_fetch *stmt);
00118 static int exec_stmt_close(PLpgSQL_execstate *estate,
00119                 PLpgSQL_stmt_close *stmt);
00120 static int exec_stmt_exit(PLpgSQL_execstate *estate,
00121                PLpgSQL_stmt_exit *stmt);
00122 static int exec_stmt_return(PLpgSQL_execstate *estate,
00123                  PLpgSQL_stmt_return *stmt);
00124 static int exec_stmt_return_next(PLpgSQL_execstate *estate,
00125                       PLpgSQL_stmt_return_next *stmt);
00126 static int exec_stmt_return_query(PLpgSQL_execstate *estate,
00127                        PLpgSQL_stmt_return_query *stmt);
00128 static int exec_stmt_raise(PLpgSQL_execstate *estate,
00129                 PLpgSQL_stmt_raise *stmt);
00130 static int exec_stmt_execsql(PLpgSQL_execstate *estate,
00131                   PLpgSQL_stmt_execsql *stmt);
00132 static int exec_stmt_dynexecute(PLpgSQL_execstate *estate,
00133                      PLpgSQL_stmt_dynexecute *stmt);
00134 static int exec_stmt_dynfors(PLpgSQL_execstate *estate,
00135                   PLpgSQL_stmt_dynfors *stmt);
00136 
00137 static void plpgsql_estate_setup(PLpgSQL_execstate *estate,
00138                      PLpgSQL_function *func,
00139                      ReturnSetInfo *rsi);
00140 static void exec_eval_cleanup(PLpgSQL_execstate *estate);
00141 
00142 static void exec_prepare_plan(PLpgSQL_execstate *estate,
00143                   PLpgSQL_expr *expr, int cursorOptions);
00144 static bool exec_simple_check_node(Node *node);
00145 static void exec_simple_check_plan(PLpgSQL_expr *expr);
00146 static void exec_simple_recheck_plan(PLpgSQL_expr *expr, CachedPlan *cplan);
00147 static bool exec_eval_simple_expr(PLpgSQL_execstate *estate,
00148                       PLpgSQL_expr *expr,
00149                       Datum *result,
00150                       bool *isNull,
00151                       Oid *rettype);
00152 
00153 static void exec_assign_expr(PLpgSQL_execstate *estate,
00154                  PLpgSQL_datum *target,
00155                  PLpgSQL_expr *expr);
00156 static void exec_assign_c_string(PLpgSQL_execstate *estate,
00157                      PLpgSQL_datum *target,
00158                      const char *str);
00159 static void exec_assign_value(PLpgSQL_execstate *estate,
00160                   PLpgSQL_datum *target,
00161                   Datum value, Oid valtype, bool *isNull);
00162 static void exec_eval_datum(PLpgSQL_execstate *estate,
00163                 PLpgSQL_datum *datum,
00164                 Oid *typeid,
00165                 int32 *typetypmod,
00166                 Datum *value,
00167                 bool *isnull);
00168 static int exec_eval_integer(PLpgSQL_execstate *estate,
00169                   PLpgSQL_expr *expr,
00170                   bool *isNull);
00171 static bool exec_eval_boolean(PLpgSQL_execstate *estate,
00172                   PLpgSQL_expr *expr,
00173                   bool *isNull);
00174 static Datum exec_eval_expr(PLpgSQL_execstate *estate,
00175                PLpgSQL_expr *expr,
00176                bool *isNull,
00177                Oid *rettype);
00178 static int exec_run_select(PLpgSQL_execstate *estate,
00179                 PLpgSQL_expr *expr, long maxtuples, Portal *portalP);
00180 static int exec_for_query(PLpgSQL_execstate *estate, PLpgSQL_stmt_forq *stmt,
00181                Portal portal, bool prefetch_ok);
00182 static ParamListInfo setup_param_list(PLpgSQL_execstate *estate,
00183                  PLpgSQL_expr *expr);
00184 static void plpgsql_param_fetch(ParamListInfo params, int paramid);
00185 static void exec_move_row(PLpgSQL_execstate *estate,
00186               PLpgSQL_rec *rec,
00187               PLpgSQL_row *row,
00188               HeapTuple tup, TupleDesc tupdesc);
00189 static HeapTuple make_tuple_from_row(PLpgSQL_execstate *estate,
00190                     PLpgSQL_row *row,
00191                     TupleDesc tupdesc);
00192 static HeapTuple get_tuple_from_datum(Datum value);
00193 static TupleDesc get_tupdesc_from_datum(Datum value);
00194 static void exec_move_row_from_datum(PLpgSQL_execstate *estate,
00195                          PLpgSQL_rec *rec,
00196                          PLpgSQL_row *row,
00197                          Datum value);
00198 static char *convert_value_to_string(PLpgSQL_execstate *estate,
00199                         Datum value, Oid valtype);
00200 static Datum exec_cast_value(PLpgSQL_execstate *estate,
00201                 Datum value, Oid valtype,
00202                 Oid reqtype,
00203                 FmgrInfo *reqinput,
00204                 Oid reqtypioparam,
00205                 int32 reqtypmod,
00206                 bool isnull);
00207 static Datum exec_simple_cast_value(PLpgSQL_execstate *estate,
00208                        Datum value, Oid valtype,
00209                        Oid reqtype, int32 reqtypmod,
00210                        bool isnull);
00211 static void exec_init_tuple_store(PLpgSQL_execstate *estate);
00212 static void exec_set_found(PLpgSQL_execstate *estate, bool state);
00213 static void plpgsql_create_econtext(PLpgSQL_execstate *estate);
00214 static void plpgsql_destroy_econtext(PLpgSQL_execstate *estate);
00215 static void free_var(PLpgSQL_var *var);
00216 static void assign_text_var(PLpgSQL_var *var, const char *str);
00217 static PreparedParamsData *exec_eval_using_params(PLpgSQL_execstate *estate,
00218                        List *params);
00219 static void free_params_data(PreparedParamsData *ppd);
00220 static Portal exec_dynquery_with_params(PLpgSQL_execstate *estate,
00221                           PLpgSQL_expr *dynquery, List *params,
00222                           const char *portalname, int cursorOptions);
00223 
00224 
00225 /* ----------
00226  * plpgsql_exec_function    Called by the call handler for
00227  *              function execution.
00228  * ----------
00229  */
00230 Datum
00231 plpgsql_exec_function(PLpgSQL_function *func, FunctionCallInfo fcinfo)
00232 {
00233     PLpgSQL_execstate estate;
00234     ErrorContextCallback plerrcontext;
00235     int         i;
00236     int         rc;
00237 
00238     /*
00239      * Setup the execution state
00240      */
00241     plpgsql_estate_setup(&estate, func, (ReturnSetInfo *) fcinfo->resultinfo);
00242 
00243     /*
00244      * Setup error traceback support for ereport()
00245      */
00246     plerrcontext.callback = plpgsql_exec_error_callback;
00247     plerrcontext.arg = &estate;
00248     plerrcontext.previous = error_context_stack;
00249     error_context_stack = &plerrcontext;
00250 
00251     /*
00252      * Make local execution copies of all the datums
00253      */
00254     estate.err_text = gettext_noop("during initialization of execution state");
00255     for (i = 0; i < estate.ndatums; i++)
00256         estate.datums[i] = copy_plpgsql_datum(func->datums[i]);
00257 
00258     /*
00259      * Store the actual call argument values into the appropriate variables
00260      */
00261     estate.err_text = gettext_noop("while storing call arguments into local variables");
00262     for (i = 0; i < func->fn_nargs; i++)
00263     {
00264         int         n = func->fn_argvarnos[i];
00265 
00266         switch (estate.datums[n]->dtype)
00267         {
00268             case PLPGSQL_DTYPE_VAR:
00269                 {
00270                     PLpgSQL_var *var = (PLpgSQL_var *) estate.datums[n];
00271 
00272                     var->value = fcinfo->arg[i];
00273                     var->isnull = fcinfo->argnull[i];
00274                     var->freeval = false;
00275                 }
00276                 break;
00277 
00278             case PLPGSQL_DTYPE_ROW:
00279                 {
00280                     PLpgSQL_row *row = (PLpgSQL_row *) estate.datums[n];
00281 
00282                     if (!fcinfo->argnull[i])
00283                     {
00284                         /* Assign row value from composite datum */
00285                         exec_move_row_from_datum(&estate, NULL, row,
00286                                                  fcinfo->arg[i]);
00287                     }
00288                     else
00289                     {
00290                         /* If arg is null, treat it as an empty row */
00291                         exec_move_row(&estate, NULL, row, NULL, NULL);
00292                     }
00293                     /* clean up after exec_move_row() */
00294                     exec_eval_cleanup(&estate);
00295                 }
00296                 break;
00297 
00298             default:
00299                 elog(ERROR, "unrecognized dtype: %d", func->datums[i]->dtype);
00300         }
00301     }
00302 
00303     estate.err_text = gettext_noop("during function entry");
00304 
00305     /*
00306      * Set the magic variable FOUND to false
00307      */
00308     exec_set_found(&estate, false);
00309 
00310     /*
00311      * Let the instrumentation plugin peek at this function
00312      */
00313     if (*plugin_ptr && (*plugin_ptr)->func_beg)
00314         ((*plugin_ptr)->func_beg) (&estate, func);
00315 
00316     /*
00317      * Now call the toplevel block of statements
00318      */
00319     estate.err_text = NULL;
00320     estate.err_stmt = (PLpgSQL_stmt *) (func->action);
00321     rc = exec_stmt_block(&estate, func->action);
00322     if (rc != PLPGSQL_RC_RETURN)
00323     {
00324         estate.err_stmt = NULL;
00325         estate.err_text = NULL;
00326 
00327         /*
00328          * Provide a more helpful message if a CONTINUE or RAISE has been used
00329          * outside the context it can work in.
00330          */
00331         if (rc == PLPGSQL_RC_CONTINUE)
00332             ereport(ERROR,
00333                     (errcode(ERRCODE_SYNTAX_ERROR),
00334                      errmsg("CONTINUE cannot be used outside a loop")));
00335         else
00336             ereport(ERROR,
00337                (errcode(ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT),
00338                 errmsg("control reached end of function without RETURN")));
00339     }
00340 
00341     /*
00342      * We got a return value - process it
00343      */
00344     estate.err_stmt = NULL;
00345     estate.err_text = gettext_noop("while casting return value to function's return type");
00346 
00347     fcinfo->isnull = estate.retisnull;
00348 
00349     if (estate.retisset)
00350     {
00351         ReturnSetInfo *rsi = estate.rsi;
00352 
00353         /* Check caller can handle a set result */
00354         if (!rsi || !IsA(rsi, ReturnSetInfo) ||
00355             (rsi->allowedModes & SFRM_Materialize) == 0)
00356             ereport(ERROR,
00357                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
00358                      errmsg("set-valued function called in context that cannot accept a set")));
00359         rsi->returnMode = SFRM_Materialize;
00360 
00361         /* If we produced any tuples, send back the result */
00362         if (estate.tuple_store)
00363         {
00364             rsi->setResult = estate.tuple_store;
00365             if (estate.rettupdesc)
00366             {
00367                 MemoryContext oldcxt;
00368 
00369                 oldcxt = MemoryContextSwitchTo(estate.tuple_store_cxt);
00370                 rsi->setDesc = CreateTupleDescCopy(estate.rettupdesc);
00371                 MemoryContextSwitchTo(oldcxt);
00372             }
00373         }
00374         estate.retval = (Datum) 0;
00375         fcinfo->isnull = true;
00376     }
00377     else if (!estate.retisnull)
00378     {
00379         if (estate.retistuple)
00380         {
00381             /*
00382              * We have to check that the returned tuple actually matches the
00383              * expected result type.  XXX would be better to cache the tupdesc
00384              * instead of repeating get_call_result_type()
00385              */
00386             HeapTuple   rettup = (HeapTuple) DatumGetPointer(estate.retval);
00387             TupleDesc   tupdesc;
00388             TupleConversionMap *tupmap;
00389 
00390             switch (get_call_result_type(fcinfo, NULL, &tupdesc))
00391             {
00392                 case TYPEFUNC_COMPOSITE:
00393                     /* got the expected result rowtype, now check it */
00394                     tupmap = convert_tuples_by_position(estate.rettupdesc,
00395                                                         tupdesc,
00396                                                         gettext_noop("returned record type does not match expected record type"));
00397                     /* it might need conversion */
00398                     if (tupmap)
00399                         rettup = do_convert_tuple(rettup, tupmap);
00400                     /* no need to free map, we're about to return anyway */
00401                     break;
00402                 case TYPEFUNC_RECORD:
00403 
00404                     /*
00405                      * Failed to determine actual type of RECORD.  We could
00406                      * raise an error here, but what this means in practice is
00407                      * that the caller is expecting any old generic rowtype,
00408                      * so we don't really need to be restrictive. Pass back
00409                      * the generated result type, instead.
00410                      */
00411                     tupdesc = estate.rettupdesc;
00412                     if (tupdesc == NULL)        /* shouldn't happen */
00413                         elog(ERROR, "return type must be a row type");
00414                     break;
00415                 default:
00416                     /* shouldn't get here if retistuple is true ... */
00417                     elog(ERROR, "return type must be a row type");
00418                     break;
00419             }
00420 
00421             /*
00422              * Copy tuple to upper executor memory, as a tuple Datum. Make
00423              * sure it is labeled with the caller-supplied tuple type.
00424              */
00425             estate.retval = PointerGetDatum(SPI_returntuple(rettup, tupdesc));
00426         }
00427         else
00428         {
00429             /* Cast value to proper type */
00430             estate.retval = exec_cast_value(&estate,
00431                                             estate.retval,
00432                                             estate.rettype,
00433                                             func->fn_rettype,
00434                                             &(func->fn_retinput),
00435                                             func->fn_rettypioparam,
00436                                             -1,
00437                                             fcinfo->isnull);
00438 
00439             /*
00440              * If the function's return type isn't by value, copy the value
00441              * into upper executor memory context.
00442              */
00443             if (!fcinfo->isnull && !func->fn_retbyval)
00444             {
00445                 Size        len;
00446                 void       *tmp;
00447 
00448                 len = datumGetSize(estate.retval, false, func->fn_rettyplen);
00449                 tmp = SPI_palloc(len);
00450                 memcpy(tmp, DatumGetPointer(estate.retval), len);
00451                 estate.retval = PointerGetDatum(tmp);
00452             }
00453         }
00454     }
00455 
00456     estate.err_text = gettext_noop("during function exit");
00457 
00458     /*
00459      * Let the instrumentation plugin peek at this function
00460      */
00461     if (*plugin_ptr && (*plugin_ptr)->func_end)
00462         ((*plugin_ptr)->func_end) (&estate, func);
00463 
00464     /* Clean up any leftover temporary memory */
00465     plpgsql_destroy_econtext(&estate);
00466     exec_eval_cleanup(&estate);
00467 
00468     /*
00469      * Pop the error context stack
00470      */
00471     error_context_stack = plerrcontext.previous;
00472 
00473     /*
00474      * Return the function's result
00475      */
00476     return estate.retval;
00477 }
00478 
00479 
00480 /* ----------
00481  * plpgsql_exec_trigger     Called by the call handler for
00482  *              trigger execution.
00483  * ----------
00484  */
00485 HeapTuple
00486 plpgsql_exec_trigger(PLpgSQL_function *func,
00487                      TriggerData *trigdata)
00488 {
00489     PLpgSQL_execstate estate;
00490     ErrorContextCallback plerrcontext;
00491     int         i;
00492     int         rc;
00493     PLpgSQL_var *var;
00494     PLpgSQL_rec *rec_new,
00495                *rec_old;
00496     HeapTuple   rettup;
00497 
00498     /*
00499      * Setup the execution state
00500      */
00501     plpgsql_estate_setup(&estate, func, NULL);
00502 
00503     /*
00504      * Setup error traceback support for ereport()
00505      */
00506     plerrcontext.callback = plpgsql_exec_error_callback;
00507     plerrcontext.arg = &estate;
00508     plerrcontext.previous = error_context_stack;
00509     error_context_stack = &plerrcontext;
00510 
00511     /*
00512      * Make local execution copies of all the datums
00513      */
00514     estate.err_text = gettext_noop("during initialization of execution state");
00515     for (i = 0; i < estate.ndatums; i++)
00516         estate.datums[i] = copy_plpgsql_datum(func->datums[i]);
00517 
00518     /*
00519      * Put the OLD and NEW tuples into record variables
00520      *
00521      * We make the tupdescs available in both records even though only one may
00522      * have a value.  This allows parsing of record references to succeed in
00523      * functions that are used for multiple trigger types.  For example, we
00524      * might have a test like "if (TG_OP = 'INSERT' and NEW.foo = 'xyz')",
00525      * which should parse regardless of the current trigger type.
00526      */
00527     rec_new = (PLpgSQL_rec *) (estate.datums[func->new_varno]);
00528     rec_new->freetup = false;
00529     rec_new->tupdesc = trigdata->tg_relation->rd_att;
00530     rec_new->freetupdesc = false;
00531     rec_old = (PLpgSQL_rec *) (estate.datums[func->old_varno]);
00532     rec_old->freetup = false;
00533     rec_old->tupdesc = trigdata->tg_relation->rd_att;
00534     rec_old->freetupdesc = false;
00535 
00536     if (!TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
00537     {
00538         /*
00539          * Per-statement triggers don't use OLD/NEW variables
00540          */
00541         rec_new->tup = NULL;
00542         rec_old->tup = NULL;
00543     }
00544     else if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
00545     {
00546         rec_new->tup = trigdata->tg_trigtuple;
00547         rec_old->tup = NULL;
00548     }
00549     else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
00550     {
00551         rec_new->tup = trigdata->tg_newtuple;
00552         rec_old->tup = trigdata->tg_trigtuple;
00553     }
00554     else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event))
00555     {
00556         rec_new->tup = NULL;
00557         rec_old->tup = trigdata->tg_trigtuple;
00558     }
00559     else
00560         elog(ERROR, "unrecognized trigger action: not INSERT, DELETE, or UPDATE");
00561 
00562     /*
00563      * Assign the special tg_ variables
00564      */
00565 
00566     var = (PLpgSQL_var *) (estate.datums[func->tg_op_varno]);
00567     if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
00568         var->value = CStringGetTextDatum("INSERT");
00569     else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
00570         var->value = CStringGetTextDatum("UPDATE");
00571     else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event))
00572         var->value = CStringGetTextDatum("DELETE");
00573     else if (TRIGGER_FIRED_BY_TRUNCATE(trigdata->tg_event))
00574         var->value = CStringGetTextDatum("TRUNCATE");
00575     else
00576         elog(ERROR, "unrecognized trigger action: not INSERT, DELETE, UPDATE, or TRUNCATE");
00577     var->isnull = false;
00578     var->freeval = true;
00579 
00580     var = (PLpgSQL_var *) (estate.datums[func->tg_name_varno]);
00581     var->value = DirectFunctionCall1(namein,
00582                               CStringGetDatum(trigdata->tg_trigger->tgname));
00583     var->isnull = false;
00584     var->freeval = true;
00585 
00586     var = (PLpgSQL_var *) (estate.datums[func->tg_when_varno]);
00587     if (TRIGGER_FIRED_BEFORE(trigdata->tg_event))
00588         var->value = CStringGetTextDatum("BEFORE");
00589     else if (TRIGGER_FIRED_AFTER(trigdata->tg_event))
00590         var->value = CStringGetTextDatum("AFTER");
00591     else if (TRIGGER_FIRED_INSTEAD(trigdata->tg_event))
00592         var->value = CStringGetTextDatum("INSTEAD OF");
00593     else
00594         elog(ERROR, "unrecognized trigger execution time: not BEFORE, AFTER, or INSTEAD OF");
00595     var->isnull = false;
00596     var->freeval = true;
00597 
00598     var = (PLpgSQL_var *) (estate.datums[func->tg_level_varno]);
00599     if (TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
00600         var->value = CStringGetTextDatum("ROW");
00601     else if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
00602         var->value = CStringGetTextDatum("STATEMENT");
00603     else
00604         elog(ERROR, "unrecognized trigger event type: not ROW or STATEMENT");
00605     var->isnull = false;
00606     var->freeval = true;
00607 
00608     var = (PLpgSQL_var *) (estate.datums[func->tg_relid_varno]);
00609     var->value = ObjectIdGetDatum(trigdata->tg_relation->rd_id);
00610     var->isnull = false;
00611     var->freeval = false;
00612 
00613     var = (PLpgSQL_var *) (estate.datums[func->tg_relname_varno]);
00614     var->value = DirectFunctionCall1(namein,
00615             CStringGetDatum(RelationGetRelationName(trigdata->tg_relation)));
00616     var->isnull = false;
00617     var->freeval = true;
00618 
00619     var = (PLpgSQL_var *) (estate.datums[func->tg_table_name_varno]);
00620     var->value = DirectFunctionCall1(namein,
00621             CStringGetDatum(RelationGetRelationName(trigdata->tg_relation)));
00622     var->isnull = false;
00623     var->freeval = true;
00624 
00625     var = (PLpgSQL_var *) (estate.datums[func->tg_table_schema_varno]);
00626     var->value = DirectFunctionCall1(namein,
00627                                      CStringGetDatum(
00628                                                      get_namespace_name(
00629                                                         RelationGetNamespace(
00630                                                    trigdata->tg_relation))));
00631     var->isnull = false;
00632     var->freeval = true;
00633 
00634     var = (PLpgSQL_var *) (estate.datums[func->tg_nargs_varno]);
00635     var->value = Int16GetDatum(trigdata->tg_trigger->tgnargs);
00636     var->isnull = false;
00637     var->freeval = false;
00638 
00639     var = (PLpgSQL_var *) (estate.datums[func->tg_argv_varno]);
00640     if (trigdata->tg_trigger->tgnargs > 0)
00641     {
00642         /*
00643          * For historical reasons, tg_argv[] subscripts start at zero not one.
00644          * So we can't use construct_array().
00645          */
00646         int         nelems = trigdata->tg_trigger->tgnargs;
00647         Datum      *elems;
00648         int         dims[1];
00649         int         lbs[1];
00650 
00651         elems = palloc(sizeof(Datum) * nelems);
00652         for (i = 0; i < nelems; i++)
00653             elems[i] = CStringGetTextDatum(trigdata->tg_trigger->tgargs[i]);
00654         dims[0] = nelems;
00655         lbs[0] = 0;
00656 
00657         var->value = PointerGetDatum(construct_md_array(elems, NULL,
00658                                                         1, dims, lbs,
00659                                                         TEXTOID,
00660                                                         -1, false, 'i'));
00661         var->isnull = false;
00662         var->freeval = true;
00663     }
00664     else
00665     {
00666         var->value = (Datum) 0;
00667         var->isnull = true;
00668         var->freeval = false;
00669     }
00670 
00671     estate.err_text = gettext_noop("during function entry");
00672 
00673     /*
00674      * Set the magic variable FOUND to false
00675      */
00676     exec_set_found(&estate, false);
00677 
00678     /*
00679      * Let the instrumentation plugin peek at this function
00680      */
00681     if (*plugin_ptr && (*plugin_ptr)->func_beg)
00682         ((*plugin_ptr)->func_beg) (&estate, func);
00683 
00684     /*
00685      * Now call the toplevel block of statements
00686      */
00687     estate.err_text = NULL;
00688     estate.err_stmt = (PLpgSQL_stmt *) (func->action);
00689     rc = exec_stmt_block(&estate, func->action);
00690     if (rc != PLPGSQL_RC_RETURN)
00691     {
00692         estate.err_stmt = NULL;
00693         estate.err_text = NULL;
00694 
00695         /*
00696          * Provide a more helpful message if a CONTINUE or RAISE has been used
00697          * outside the context it can work in.
00698          */
00699         if (rc == PLPGSQL_RC_CONTINUE)
00700             ereport(ERROR,
00701                     (errcode(ERRCODE_SYNTAX_ERROR),
00702                      errmsg("CONTINUE cannot be used outside a loop")));
00703         else
00704             ereport(ERROR,
00705                (errcode(ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT),
00706                 errmsg("control reached end of trigger procedure without RETURN")));
00707     }
00708 
00709     estate.err_stmt = NULL;
00710     estate.err_text = gettext_noop("during function exit");
00711 
00712     if (estate.retisset)
00713         ereport(ERROR,
00714                 (errcode(ERRCODE_DATATYPE_MISMATCH),
00715                  errmsg("trigger procedure cannot return a set")));
00716 
00717     /*
00718      * Check that the returned tuple structure has the same attributes, the
00719      * relation that fired the trigger has. A per-statement trigger always
00720      * needs to return NULL, so we ignore any return value the function itself
00721      * produces (XXX: is this a good idea?)
00722      *
00723      * XXX This way it is possible, that the trigger returns a tuple where
00724      * attributes don't have the correct atttypmod's length. It's up to the
00725      * trigger's programmer to ensure that this doesn't happen. Jan
00726      */
00727     if (estate.retisnull || !TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
00728         rettup = NULL;
00729     else
00730     {
00731         TupleConversionMap *tupmap;
00732 
00733         rettup = (HeapTuple) DatumGetPointer(estate.retval);
00734         /* check rowtype compatibility */
00735         tupmap = convert_tuples_by_position(estate.rettupdesc,
00736                                             trigdata->tg_relation->rd_att,
00737                                             gettext_noop("returned row structure does not match the structure of the triggering table"));
00738         /* it might need conversion */
00739         if (tupmap)
00740             rettup = do_convert_tuple(rettup, tupmap);
00741         /* no need to free map, we're about to return anyway */
00742 
00743         /* Copy tuple to upper executor memory */
00744         rettup = SPI_copytuple(rettup);
00745     }
00746 
00747     /*
00748      * Let the instrumentation plugin peek at this function
00749      */
00750     if (*plugin_ptr && (*plugin_ptr)->func_end)
00751         ((*plugin_ptr)->func_end) (&estate, func);
00752 
00753     /* Clean up any leftover temporary memory */
00754     plpgsql_destroy_econtext(&estate);
00755     exec_eval_cleanup(&estate);
00756 
00757     /*
00758      * Pop the error context stack
00759      */
00760     error_context_stack = plerrcontext.previous;
00761 
00762     /*
00763      * Return the trigger's result
00764      */
00765     return rettup;
00766 }
00767 
00768 void
00769 plpgsql_exec_event_trigger(PLpgSQL_function *func, EventTriggerData *trigdata)
00770 {
00771     PLpgSQL_execstate estate;
00772     ErrorContextCallback plerrcontext;
00773     int         i;
00774     int         rc;
00775     PLpgSQL_var *var;
00776 
00777     /*
00778      * Setup the execution state
00779      */
00780     plpgsql_estate_setup(&estate, func, NULL);
00781 
00782     /*
00783      * Setup error traceback support for ereport()
00784      */
00785     plerrcontext.callback = plpgsql_exec_error_callback;
00786     plerrcontext.arg = &estate;
00787     plerrcontext.previous = error_context_stack;
00788     error_context_stack = &plerrcontext;
00789 
00790     /*
00791      * Make local execution copies of all the datums
00792      */
00793     estate.err_text = gettext_noop("during initialization of execution state");
00794     for (i = 0; i < estate.ndatums; i++)
00795         estate.datums[i] = copy_plpgsql_datum(func->datums[i]);
00796 
00797     /*
00798      * Assign the special tg_ variables
00799      */
00800     var = (PLpgSQL_var *) (estate.datums[func->tg_event_varno]);
00801     var->value = CStringGetTextDatum(trigdata->event);
00802     var->isnull = false;
00803     var->freeval = true;
00804 
00805     var = (PLpgSQL_var *) (estate.datums[func->tg_tag_varno]);
00806     var->value = CStringGetTextDatum(trigdata->tag);
00807     var->isnull = false;
00808     var->freeval = true;
00809 
00810     /*
00811      * Let the instrumentation plugin peek at this function
00812      */
00813     if (*plugin_ptr && (*plugin_ptr)->func_beg)
00814         ((*plugin_ptr)->func_beg) (&estate, func);
00815 
00816     /*
00817      * Now call the toplevel block of statements
00818      */
00819     estate.err_text = NULL;
00820     estate.err_stmt = (PLpgSQL_stmt *) (func->action);
00821     rc = exec_stmt_block(&estate, func->action);
00822     if (rc != PLPGSQL_RC_RETURN)
00823     {
00824         estate.err_stmt = NULL;
00825         estate.err_text = NULL;
00826 
00827         /*
00828          * Provide a more helpful message if a CONTINUE or RAISE has been used
00829          * outside the context it can work in.
00830          */
00831         if (rc == PLPGSQL_RC_CONTINUE)
00832             ereport(ERROR,
00833                     (errcode(ERRCODE_SYNTAX_ERROR),
00834                      errmsg("CONTINUE cannot be used outside a loop")));
00835         else
00836             ereport(ERROR,
00837                (errcode(ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT),
00838                 errmsg("control reached end of trigger procedure without RETURN")));
00839     }
00840 
00841     estate.err_stmt = NULL;
00842     estate.err_text = gettext_noop("during function exit");
00843 
00844     /*
00845      * Let the instrumentation plugin peek at this function
00846      */
00847     if (*plugin_ptr && (*plugin_ptr)->func_end)
00848         ((*plugin_ptr)->func_end) (&estate, func);
00849 
00850     /* Clean up any leftover temporary memory */
00851     plpgsql_destroy_econtext(&estate);
00852     exec_eval_cleanup(&estate);
00853 
00854     /*
00855      * Pop the error context stack
00856      */
00857     error_context_stack = plerrcontext.previous;
00858 
00859     return;
00860 }
00861 
00862 /*
00863  * error context callback to let us supply a call-stack traceback
00864  */
00865 static void
00866 plpgsql_exec_error_callback(void *arg)
00867 {
00868     PLpgSQL_execstate *estate = (PLpgSQL_execstate *) arg;
00869 
00870     /* if we are doing RAISE, don't report its location */
00871     if (estate->err_text == raise_skip_msg)
00872         return;
00873 
00874     if (estate->err_text != NULL)
00875     {
00876         /*
00877          * We don't expend the cycles to run gettext() on err_text unless we
00878          * actually need it.  Therefore, places that set up err_text should
00879          * use gettext_noop() to ensure the strings get recorded in the
00880          * message dictionary.
00881          *
00882          * If both err_text and err_stmt are set, use the err_text as
00883          * description, but report the err_stmt's line number.  When err_stmt
00884          * is not set, we're in function entry/exit, or some such place not
00885          * attached to a specific line number.
00886          */
00887         if (estate->err_stmt != NULL)
00888         {
00889             /*
00890              * translator: last %s is a phrase such as "during statement block
00891              * local variable initialization"
00892              */
00893             errcontext("PL/pgSQL function %s line %d %s",
00894                        estate->func->fn_signature,
00895                        estate->err_stmt->lineno,
00896                        _(estate->err_text));
00897         }
00898         else
00899         {
00900             /*
00901              * translator: last %s is a phrase such as "while storing call
00902              * arguments into local variables"
00903              */
00904             errcontext("PL/pgSQL function %s %s",
00905                        estate->func->fn_signature,
00906                        _(estate->err_text));
00907         }
00908     }
00909     else if (estate->err_stmt != NULL)
00910     {
00911         /* translator: last %s is a plpgsql statement type name */
00912         errcontext("PL/pgSQL function %s line %d at %s",
00913                    estate->func->fn_signature,
00914                    estate->err_stmt->lineno,
00915                    plpgsql_stmt_typename(estate->err_stmt));
00916     }
00917     else
00918         errcontext("PL/pgSQL function %s",
00919                    estate->func->fn_signature);
00920 }
00921 
00922 
00923 /* ----------
00924  * Support function for initializing local execution variables
00925  * ----------
00926  */
00927 static PLpgSQL_datum *
00928 copy_plpgsql_datum(PLpgSQL_datum *datum)
00929 {
00930     PLpgSQL_datum *result;
00931 
00932     switch (datum->dtype)
00933     {
00934         case PLPGSQL_DTYPE_VAR:
00935             {
00936                 PLpgSQL_var *new = palloc(sizeof(PLpgSQL_var));
00937 
00938                 memcpy(new, datum, sizeof(PLpgSQL_var));
00939                 /* Ensure the value is null (possibly not needed?) */
00940                 new->value = 0;
00941                 new->isnull = true;
00942                 new->freeval = false;
00943 
00944                 result = (PLpgSQL_datum *) new;
00945             }
00946             break;
00947 
00948         case PLPGSQL_DTYPE_REC:
00949             {
00950                 PLpgSQL_rec *new = palloc(sizeof(PLpgSQL_rec));
00951 
00952                 memcpy(new, datum, sizeof(PLpgSQL_rec));
00953                 /* Ensure the value is null (possibly not needed?) */
00954                 new->tup = NULL;
00955                 new->tupdesc = NULL;
00956                 new->freetup = false;
00957                 new->freetupdesc = false;
00958 
00959                 result = (PLpgSQL_datum *) new;
00960             }
00961             break;
00962 
00963         case PLPGSQL_DTYPE_ROW:
00964         case PLPGSQL_DTYPE_RECFIELD:
00965         case PLPGSQL_DTYPE_ARRAYELEM:
00966 
00967             /*
00968              * These datum records are read-only at runtime, so no need to
00969              * copy them (well, ARRAYELEM contains some cached type data, but
00970              * we'd just as soon centralize the caching anyway)
00971              */
00972             result = datum;
00973             break;
00974 
00975         default:
00976             elog(ERROR, "unrecognized dtype: %d", datum->dtype);
00977             result = NULL;      /* keep compiler quiet */
00978             break;
00979     }
00980 
00981     return result;
00982 }
00983 
00984 
00985 static bool
00986 exception_matches_conditions(ErrorData *edata, PLpgSQL_condition *cond)
00987 {
00988     for (; cond != NULL; cond = cond->next)
00989     {
00990         int         sqlerrstate = cond->sqlerrstate;
00991 
00992         /*
00993          * OTHERS matches everything *except* query-canceled; if you're
00994          * foolish enough, you can match that explicitly.
00995          */
00996         if (sqlerrstate == 0)
00997         {
00998             if (edata->sqlerrcode != ERRCODE_QUERY_CANCELED)
00999                 return true;
01000         }
01001         /* Exact match? */
01002         else if (edata->sqlerrcode == sqlerrstate)
01003             return true;
01004         /* Category match? */
01005         else if (ERRCODE_IS_CATEGORY(sqlerrstate) &&
01006                  ERRCODE_TO_CATEGORY(edata->sqlerrcode) == sqlerrstate)
01007             return true;
01008     }
01009     return false;
01010 }
01011 
01012 
01013 /* ----------
01014  * exec_stmt_block          Execute a block of statements
01015  * ----------
01016  */
01017 static int
01018 exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
01019 {
01020     volatile int rc = -1;
01021     int         i;
01022     int         n;
01023 
01024     /*
01025      * First initialize all variables declared in this block
01026      */
01027     estate->err_text = gettext_noop("during statement block local variable initialization");
01028 
01029     for (i = 0; i < block->n_initvars; i++)
01030     {
01031         n = block->initvarnos[i];
01032 
01033         switch (estate->datums[n]->dtype)
01034         {
01035             case PLPGSQL_DTYPE_VAR:
01036                 {
01037                     PLpgSQL_var *var = (PLpgSQL_var *) (estate->datums[n]);
01038 
01039                     /* free any old value, in case re-entering block */
01040                     free_var(var);
01041 
01042                     /* Initially it contains a NULL */
01043                     var->value = (Datum) 0;
01044                     var->isnull = true;
01045 
01046                     if (var->default_val == NULL)
01047                     {
01048                         /*
01049                          * If needed, give the datatype a chance to reject
01050                          * NULLs, by assigning a NULL to the variable. We
01051                          * claim the value is of type UNKNOWN, not the var's
01052                          * datatype, else coercion will be skipped. (Do this
01053                          * before the notnull check to be consistent with
01054                          * exec_assign_value.)
01055                          */
01056                         if (!var->datatype->typinput.fn_strict)
01057                         {
01058                             bool        valIsNull = true;
01059 
01060                             exec_assign_value(estate,
01061                                               (PLpgSQL_datum *) var,
01062                                               (Datum) 0,
01063                                               UNKNOWNOID,
01064                                               &valIsNull);
01065                         }
01066                         if (var->notnull)
01067                             ereport(ERROR,
01068                                     (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
01069                                      errmsg("variable \"%s\" declared NOT NULL cannot default to NULL",
01070                                             var->refname)));
01071                     }
01072                     else
01073                     {
01074                         exec_assign_expr(estate, (PLpgSQL_datum *) var,
01075                                          var->default_val);
01076                     }
01077                 }
01078                 break;
01079 
01080             case PLPGSQL_DTYPE_REC:
01081                 {
01082                     PLpgSQL_rec *rec = (PLpgSQL_rec *) (estate->datums[n]);
01083 
01084                     if (rec->freetup)
01085                     {
01086                         heap_freetuple(rec->tup);
01087                         rec->freetup = false;
01088                     }
01089                     if (rec->freetupdesc)
01090                     {
01091                         FreeTupleDesc(rec->tupdesc);
01092                         rec->freetupdesc = false;
01093                     }
01094                     rec->tup = NULL;
01095                     rec->tupdesc = NULL;
01096                 }
01097                 break;
01098 
01099             case PLPGSQL_DTYPE_RECFIELD:
01100             case PLPGSQL_DTYPE_ARRAYELEM:
01101                 break;
01102 
01103             default:
01104                 elog(ERROR, "unrecognized dtype: %d",
01105                      estate->datums[n]->dtype);
01106         }
01107     }
01108 
01109     if (block->exceptions)
01110     {
01111         /*
01112          * Execute the statements in the block's body inside a sub-transaction
01113          */
01114         MemoryContext oldcontext = CurrentMemoryContext;
01115         ResourceOwner oldowner = CurrentResourceOwner;
01116         ExprContext *old_eval_econtext = estate->eval_econtext;
01117         ErrorData  *save_cur_error = estate->cur_error;
01118 
01119         estate->err_text = gettext_noop("during statement block entry");
01120 
01121         BeginInternalSubTransaction(NULL);
01122         /* Want to run statements inside function's memory context */
01123         MemoryContextSwitchTo(oldcontext);
01124 
01125         PG_TRY();
01126         {
01127             /*
01128              * We need to run the block's statements with a new eval_econtext
01129              * that belongs to the current subtransaction; if we try to use
01130              * the outer econtext then ExprContext shutdown callbacks will be
01131              * called at the wrong times.
01132              */
01133             plpgsql_create_econtext(estate);
01134 
01135             estate->err_text = NULL;
01136 
01137             /* Run the block's statements */
01138             rc = exec_stmts(estate, block->body);
01139 
01140             estate->err_text = gettext_noop("during statement block exit");
01141 
01142             /*
01143              * If the block ended with RETURN, we may need to copy the return
01144              * value out of the subtransaction eval_context.  This is
01145              * currently only needed for scalar result types --- rowtype
01146              * values will always exist in the function's own memory context.
01147              */
01148             if (rc == PLPGSQL_RC_RETURN &&
01149                 !estate->retisset &&
01150                 !estate->retisnull &&
01151                 estate->rettupdesc == NULL)
01152             {
01153                 int16       resTypLen;
01154                 bool        resTypByVal;
01155 
01156                 get_typlenbyval(estate->rettype, &resTypLen, &resTypByVal);
01157                 estate->retval = datumCopy(estate->retval,
01158                                            resTypByVal, resTypLen);
01159             }
01160 
01161             /* Commit the inner transaction, return to outer xact context */
01162             ReleaseCurrentSubTransaction();
01163             MemoryContextSwitchTo(oldcontext);
01164             CurrentResourceOwner = oldowner;
01165 
01166             /*
01167              * Revert to outer eval_econtext.  (The inner one was
01168              * automatically cleaned up during subxact exit.)
01169              */
01170             estate->eval_econtext = old_eval_econtext;
01171 
01172             /*
01173              * AtEOSubXact_SPI() should not have popped any SPI context, but
01174              * just in case it did, make sure we remain connected.
01175              */
01176             SPI_restore_connection();
01177         }
01178         PG_CATCH();
01179         {
01180             ErrorData  *edata;
01181             ListCell   *e;
01182 
01183             estate->err_text = gettext_noop("during exception cleanup");
01184 
01185             /* Save error info */
01186             MemoryContextSwitchTo(oldcontext);
01187             edata = CopyErrorData();
01188             FlushErrorState();
01189 
01190             /* Abort the inner transaction */
01191             RollbackAndReleaseCurrentSubTransaction();
01192             MemoryContextSwitchTo(oldcontext);
01193             CurrentResourceOwner = oldowner;
01194 
01195             /* Revert to outer eval_econtext */
01196             estate->eval_econtext = old_eval_econtext;
01197 
01198             /*
01199              * If AtEOSubXact_SPI() popped any SPI context of the subxact, it
01200              * will have left us in a disconnected state.  We need this hack
01201              * to return to connected state.
01202              */
01203             SPI_restore_connection();
01204 
01205             /* Must clean up the econtext too */
01206             exec_eval_cleanup(estate);
01207 
01208             /* Look for a matching exception handler */
01209             foreach(e, block->exceptions->exc_list)
01210             {
01211                 PLpgSQL_exception *exception = (PLpgSQL_exception *) lfirst(e);
01212 
01213                 if (exception_matches_conditions(edata, exception->conditions))
01214                 {
01215                     /*
01216                      * Initialize the magic SQLSTATE and SQLERRM variables for
01217                      * the exception block. We needn't do this until we have
01218                      * found a matching exception.
01219                      */
01220                     PLpgSQL_var *state_var;
01221                     PLpgSQL_var *errm_var;
01222 
01223                     state_var = (PLpgSQL_var *)
01224                         estate->datums[block->exceptions->sqlstate_varno];
01225                     errm_var = (PLpgSQL_var *)
01226                         estate->datums[block->exceptions->sqlerrm_varno];
01227 
01228                     assign_text_var(state_var,
01229                                     unpack_sql_state(edata->sqlerrcode));
01230                     assign_text_var(errm_var, edata->message);
01231 
01232                     /*
01233                      * Also set up cur_error so the error data is accessible
01234                      * inside the handler.
01235                      */
01236                     estate->cur_error = edata;
01237 
01238                     estate->err_text = NULL;
01239 
01240                     rc = exec_stmts(estate, exception->action);
01241 
01242                     free_var(state_var);
01243                     state_var->value = (Datum) 0;
01244                     state_var->isnull = true;
01245                     free_var(errm_var);
01246                     errm_var->value = (Datum) 0;
01247                     errm_var->isnull = true;
01248 
01249                     break;
01250                 }
01251             }
01252 
01253             /*
01254              * Restore previous state of cur_error, whether or not we executed
01255              * a handler.  This is needed in case an error got thrown from
01256              * some inner block's exception handler.
01257              */
01258             estate->cur_error = save_cur_error;
01259 
01260             /* If no match found, re-throw the error */
01261             if (e == NULL)
01262                 ReThrowError(edata);
01263             else
01264                 FreeErrorData(edata);
01265         }
01266         PG_END_TRY();
01267 
01268         Assert(save_cur_error == estate->cur_error);
01269     }
01270     else
01271     {
01272         /*
01273          * Just execute the statements in the block's body
01274          */
01275         estate->err_text = NULL;
01276 
01277         rc = exec_stmts(estate, block->body);
01278     }
01279 
01280     estate->err_text = NULL;
01281 
01282     /*
01283      * Handle the return code.
01284      */
01285     switch (rc)
01286     {
01287         case PLPGSQL_RC_OK:
01288         case PLPGSQL_RC_RETURN:
01289         case PLPGSQL_RC_CONTINUE:
01290             return rc;
01291 
01292         case PLPGSQL_RC_EXIT:
01293 
01294             /*
01295              * This is intentionally different from the handling of RC_EXIT
01296              * for loops: to match a block, we require a match by label.
01297              */
01298             if (estate->exitlabel == NULL)
01299                 return PLPGSQL_RC_EXIT;
01300             if (block->label == NULL)
01301                 return PLPGSQL_RC_EXIT;
01302             if (strcmp(block->label, estate->exitlabel) != 0)
01303                 return PLPGSQL_RC_EXIT;
01304             estate->exitlabel = NULL;
01305             return PLPGSQL_RC_OK;
01306 
01307         default:
01308             elog(ERROR, "unrecognized rc: %d", rc);
01309     }
01310 
01311     return PLPGSQL_RC_OK;
01312 }
01313 
01314 
01315 /* ----------
01316  * exec_stmts           Iterate over a list of statements
01317  *              as long as their return code is OK
01318  * ----------
01319  */
01320 static int
01321 exec_stmts(PLpgSQL_execstate *estate, List *stmts)
01322 {
01323     ListCell   *s;
01324 
01325     if (stmts == NIL)
01326     {
01327         /*
01328          * Ensure we do a CHECK_FOR_INTERRUPTS() even though there is no
01329          * statement.  This prevents hangup in a tight loop if, for instance,
01330          * there is a LOOP construct with an empty body.
01331          */
01332         CHECK_FOR_INTERRUPTS();
01333         return PLPGSQL_RC_OK;
01334     }
01335 
01336     foreach(s, stmts)
01337     {
01338         PLpgSQL_stmt *stmt = (PLpgSQL_stmt *) lfirst(s);
01339         int         rc = exec_stmt(estate, stmt);
01340 
01341         if (rc != PLPGSQL_RC_OK)
01342             return rc;
01343     }
01344 
01345     return PLPGSQL_RC_OK;
01346 }
01347 
01348 
01349 /* ----------
01350  * exec_stmt            Distribute one statement to the statements
01351  *              type specific execution function.
01352  * ----------
01353  */
01354 static int
01355 exec_stmt(PLpgSQL_execstate *estate, PLpgSQL_stmt *stmt)
01356 {
01357     PLpgSQL_stmt *save_estmt;
01358     int         rc = -1;
01359 
01360     save_estmt = estate->err_stmt;
01361     estate->err_stmt = stmt;
01362 
01363     /* Let the plugin know that we are about to execute this statement */
01364     if (*plugin_ptr && (*plugin_ptr)->stmt_beg)
01365         ((*plugin_ptr)->stmt_beg) (estate, stmt);
01366 
01367     CHECK_FOR_INTERRUPTS();
01368 
01369     switch ((enum PLpgSQL_stmt_types) stmt->cmd_type)
01370     {
01371         case PLPGSQL_STMT_BLOCK:
01372             rc = exec_stmt_block(estate, (PLpgSQL_stmt_block *) stmt);
01373             break;
01374 
01375         case PLPGSQL_STMT_ASSIGN:
01376             rc = exec_stmt_assign(estate, (PLpgSQL_stmt_assign *) stmt);
01377             break;
01378 
01379         case PLPGSQL_STMT_PERFORM:
01380             rc = exec_stmt_perform(estate, (PLpgSQL_stmt_perform *) stmt);
01381             break;
01382 
01383         case PLPGSQL_STMT_GETDIAG:
01384             rc = exec_stmt_getdiag(estate, (PLpgSQL_stmt_getdiag *) stmt);
01385             break;
01386 
01387         case PLPGSQL_STMT_IF:
01388             rc = exec_stmt_if(estate, (PLpgSQL_stmt_if *) stmt);
01389             break;
01390 
01391         case PLPGSQL_STMT_CASE:
01392             rc = exec_stmt_case(estate, (PLpgSQL_stmt_case *) stmt);
01393             break;
01394 
01395         case PLPGSQL_STMT_LOOP:
01396             rc = exec_stmt_loop(estate, (PLpgSQL_stmt_loop *) stmt);
01397             break;
01398 
01399         case PLPGSQL_STMT_WHILE:
01400             rc = exec_stmt_while(estate, (PLpgSQL_stmt_while *) stmt);
01401             break;
01402 
01403         case PLPGSQL_STMT_FORI:
01404             rc = exec_stmt_fori(estate, (PLpgSQL_stmt_fori *) stmt);
01405             break;
01406 
01407         case PLPGSQL_STMT_FORS:
01408             rc = exec_stmt_fors(estate, (PLpgSQL_stmt_fors *) stmt);
01409             break;
01410 
01411         case PLPGSQL_STMT_FORC:
01412             rc = exec_stmt_forc(estate, (PLpgSQL_stmt_forc *) stmt);
01413             break;
01414 
01415         case PLPGSQL_STMT_FOREACH_A:
01416             rc = exec_stmt_foreach_a(estate, (PLpgSQL_stmt_foreach_a *) stmt);
01417             break;
01418 
01419         case PLPGSQL_STMT_EXIT:
01420             rc = exec_stmt_exit(estate, (PLpgSQL_stmt_exit *) stmt);
01421             break;
01422 
01423         case PLPGSQL_STMT_RETURN:
01424             rc = exec_stmt_return(estate, (PLpgSQL_stmt_return *) stmt);
01425             break;
01426 
01427         case PLPGSQL_STMT_RETURN_NEXT:
01428             rc = exec_stmt_return_next(estate, (PLpgSQL_stmt_return_next *) stmt);
01429             break;
01430 
01431         case PLPGSQL_STMT_RETURN_QUERY:
01432             rc = exec_stmt_return_query(estate, (PLpgSQL_stmt_return_query *) stmt);
01433             break;
01434 
01435         case PLPGSQL_STMT_RAISE:
01436             rc = exec_stmt_raise(estate, (PLpgSQL_stmt_raise *) stmt);
01437             break;
01438 
01439         case PLPGSQL_STMT_EXECSQL:
01440             rc = exec_stmt_execsql(estate, (PLpgSQL_stmt_execsql *) stmt);
01441             break;
01442 
01443         case PLPGSQL_STMT_DYNEXECUTE:
01444             rc = exec_stmt_dynexecute(estate, (PLpgSQL_stmt_dynexecute *) stmt);
01445             break;
01446 
01447         case PLPGSQL_STMT_DYNFORS:
01448             rc = exec_stmt_dynfors(estate, (PLpgSQL_stmt_dynfors *) stmt);
01449             break;
01450 
01451         case PLPGSQL_STMT_OPEN:
01452             rc = exec_stmt_open(estate, (PLpgSQL_stmt_open *) stmt);
01453             break;
01454 
01455         case PLPGSQL_STMT_FETCH:
01456             rc = exec_stmt_fetch(estate, (PLpgSQL_stmt_fetch *) stmt);
01457             break;
01458 
01459         case PLPGSQL_STMT_CLOSE:
01460             rc = exec_stmt_close(estate, (PLpgSQL_stmt_close *) stmt);
01461             break;
01462 
01463         default:
01464             estate->err_stmt = save_estmt;
01465             elog(ERROR, "unrecognized cmdtype: %d", stmt->cmd_type);
01466     }
01467 
01468     /* Let the plugin know that we have finished executing this statement */
01469     if (*plugin_ptr && (*plugin_ptr)->stmt_end)
01470         ((*plugin_ptr)->stmt_end) (estate, stmt);
01471 
01472     estate->err_stmt = save_estmt;
01473 
01474     return rc;
01475 }
01476 
01477 
01478 /* ----------
01479  * exec_stmt_assign         Evaluate an expression and
01480  *                  put the result into a variable.
01481  * ----------
01482  */
01483 static int
01484 exec_stmt_assign(PLpgSQL_execstate *estate, PLpgSQL_stmt_assign *stmt)
01485 {
01486     Assert(stmt->varno >= 0);
01487 
01488     exec_assign_expr(estate, estate->datums[stmt->varno], stmt->expr);
01489 
01490     return PLPGSQL_RC_OK;
01491 }
01492 
01493 /* ----------
01494  * exec_stmt_perform        Evaluate query and discard result (but set
01495  *                          FOUND depending on whether at least one row
01496  *                          was returned).
01497  * ----------
01498  */
01499 static int
01500 exec_stmt_perform(PLpgSQL_execstate *estate, PLpgSQL_stmt_perform *stmt)
01501 {
01502     PLpgSQL_expr *expr = stmt->expr;
01503 
01504     (void) exec_run_select(estate, expr, 0, NULL);
01505     exec_set_found(estate, (estate->eval_processed != 0));
01506     exec_eval_cleanup(estate);
01507 
01508     return PLPGSQL_RC_OK;
01509 }
01510 
01511 /* ----------
01512  * exec_stmt_getdiag                    Put internal PG information into
01513  *                                      specified variables.
01514  * ----------
01515  */
01516 static int
01517 exec_stmt_getdiag(PLpgSQL_execstate *estate, PLpgSQL_stmt_getdiag *stmt)
01518 {
01519     ListCell   *lc;
01520 
01521     /*
01522      * GET STACKED DIAGNOSTICS is only valid inside an exception handler.
01523      *
01524      * Note: we trust the grammar to have disallowed the relevant item kinds
01525      * if not is_stacked, otherwise we'd dump core below.
01526      */
01527     if (stmt->is_stacked && estate->cur_error == NULL)
01528         ereport(ERROR,
01529         (errcode(ERRCODE_STACKED_DIAGNOSTICS_ACCESSED_WITHOUT_ACTIVE_HANDLER),
01530          errmsg("GET STACKED DIAGNOSTICS cannot be used outside an exception handler")));
01531 
01532     foreach(lc, stmt->diag_items)
01533     {
01534         PLpgSQL_diag_item *diag_item = (PLpgSQL_diag_item *) lfirst(lc);
01535         PLpgSQL_datum *var = estate->datums[diag_item->target];
01536         bool        isnull = false;
01537 
01538         switch (diag_item->kind)
01539         {
01540             case PLPGSQL_GETDIAG_ROW_COUNT:
01541                 exec_assign_value(estate, var,
01542                                   UInt32GetDatum(estate->eval_processed),
01543                                   INT4OID, &isnull);
01544                 break;
01545 
01546             case PLPGSQL_GETDIAG_RESULT_OID:
01547                 exec_assign_value(estate, var,
01548                                   ObjectIdGetDatum(estate->eval_lastoid),
01549                                   OIDOID, &isnull);
01550                 break;
01551 
01552             case PLPGSQL_GETDIAG_ERROR_CONTEXT:
01553                 exec_assign_c_string(estate, var,
01554                                      estate->cur_error->context);
01555                 break;
01556 
01557             case PLPGSQL_GETDIAG_ERROR_DETAIL:
01558                 exec_assign_c_string(estate, var,
01559                                      estate->cur_error->detail);
01560                 break;
01561 
01562             case PLPGSQL_GETDIAG_ERROR_HINT:
01563                 exec_assign_c_string(estate, var,
01564                                      estate->cur_error->hint);
01565                 break;
01566 
01567             case PLPGSQL_GETDIAG_RETURNED_SQLSTATE:
01568                 exec_assign_c_string(estate, var,
01569                             unpack_sql_state(estate->cur_error->sqlerrcode));
01570                 break;
01571 
01572             case PLPGSQL_GETDIAG_MESSAGE_TEXT:
01573                 exec_assign_c_string(estate, var,
01574                                      estate->cur_error->message);
01575                 break;
01576 
01577             default:
01578                 elog(ERROR, "unrecognized diagnostic item kind: %d",
01579                      diag_item->kind);
01580         }
01581     }
01582 
01583     return PLPGSQL_RC_OK;
01584 }
01585 
01586 /* ----------
01587  * exec_stmt_if             Evaluate a bool expression and
01588  *                  execute the true or false body
01589  *                  conditionally.
01590  * ----------
01591  */
01592 static int
01593 exec_stmt_if(PLpgSQL_execstate *estate, PLpgSQL_stmt_if *stmt)
01594 {
01595     bool        value;
01596     bool        isnull;
01597     ListCell   *lc;
01598 
01599     value = exec_eval_boolean(estate, stmt->cond, &isnull);
01600     exec_eval_cleanup(estate);
01601     if (!isnull && value)
01602         return exec_stmts(estate, stmt->then_body);
01603 
01604     foreach(lc, stmt->elsif_list)
01605     {
01606         PLpgSQL_if_elsif *elif = (PLpgSQL_if_elsif *) lfirst(lc);
01607 
01608         value = exec_eval_boolean(estate, elif->cond, &isnull);
01609         exec_eval_cleanup(estate);
01610         if (!isnull && value)
01611             return exec_stmts(estate, elif->stmts);
01612     }
01613 
01614     return exec_stmts(estate, stmt->else_body);
01615 }
01616 
01617 
01618 /*-----------
01619  * exec_stmt_case
01620  *-----------
01621  */
01622 static int
01623 exec_stmt_case(PLpgSQL_execstate *estate, PLpgSQL_stmt_case *stmt)
01624 {
01625     PLpgSQL_var *t_var = NULL;
01626     bool        isnull;
01627     ListCell   *l;
01628 
01629     if (stmt->t_expr != NULL)
01630     {
01631         /* simple case */
01632         Datum       t_val;
01633         Oid         t_oid;
01634 
01635         t_val = exec_eval_expr(estate, stmt->t_expr, &isnull, &t_oid);
01636 
01637         t_var = (PLpgSQL_var *) estate->datums[stmt->t_varno];
01638 
01639         /*
01640          * When expected datatype is different from real, change it. Note that
01641          * what we're modifying here is an execution copy of the datum, so
01642          * this doesn't affect the originally stored function parse tree.
01643          */
01644         if (t_var->datatype->typoid != t_oid)
01645             t_var->datatype = plpgsql_build_datatype(t_oid,
01646                                                      -1,
01647                                            estate->func->fn_input_collation);
01648 
01649         /* now we can assign to the variable */
01650         exec_assign_value(estate,
01651                           (PLpgSQL_datum *) t_var,
01652                           t_val,
01653                           t_oid,
01654                           &isnull);
01655 
01656         exec_eval_cleanup(estate);
01657     }
01658 
01659     /* Now search for a successful WHEN clause */
01660     foreach(l, stmt->case_when_list)
01661     {
01662         PLpgSQL_case_when *cwt = (PLpgSQL_case_when *) lfirst(l);
01663         bool        value;
01664 
01665         value = exec_eval_boolean(estate, cwt->expr, &isnull);
01666         exec_eval_cleanup(estate);
01667         if (!isnull && value)
01668         {
01669             /* Found it */
01670 
01671             /* We can now discard any value we had for the temp variable */
01672             if (t_var != NULL)
01673             {
01674                 free_var(t_var);
01675                 t_var->value = (Datum) 0;
01676                 t_var->isnull = true;
01677             }
01678 
01679             /* Evaluate the statement(s), and we're done */
01680             return exec_stmts(estate, cwt->stmts);
01681         }
01682     }
01683 
01684     /* We can now discard any value we had for the temp variable */
01685     if (t_var != NULL)
01686     {
01687         free_var(t_var);
01688         t_var->value = (Datum) 0;
01689         t_var->isnull = true;
01690     }
01691 
01692     /* SQL2003 mandates this error if there was no ELSE clause */
01693     if (!stmt->have_else)
01694         ereport(ERROR,
01695                 (errcode(ERRCODE_CASE_NOT_FOUND),
01696                  errmsg("case not found"),
01697                  errhint("CASE statement is missing ELSE part.")));
01698 
01699     /* Evaluate the ELSE statements, and we're done */
01700     return exec_stmts(estate, stmt->else_stmts);
01701 }
01702 
01703 
01704 /* ----------
01705  * exec_stmt_loop           Loop over statements until
01706  *                  an exit occurs.
01707  * ----------
01708  */
01709 static int
01710 exec_stmt_loop(PLpgSQL_execstate *estate, PLpgSQL_stmt_loop *stmt)
01711 {
01712     for (;;)
01713     {
01714         int         rc = exec_stmts(estate, stmt->body);
01715 
01716         switch (rc)
01717         {
01718             case PLPGSQL_RC_OK:
01719                 break;
01720 
01721             case PLPGSQL_RC_EXIT:
01722                 if (estate->exitlabel == NULL)
01723                     return PLPGSQL_RC_OK;
01724                 if (stmt->label == NULL)
01725                     return PLPGSQL_RC_EXIT;
01726                 if (strcmp(stmt->label, estate->exitlabel) != 0)
01727                     return PLPGSQL_RC_EXIT;
01728                 estate->exitlabel = NULL;
01729                 return PLPGSQL_RC_OK;
01730 
01731             case PLPGSQL_RC_CONTINUE:
01732                 if (estate->exitlabel == NULL)
01733                     /* anonymous continue, so re-run the loop */
01734                     break;
01735                 else if (stmt->label != NULL &&
01736                          strcmp(stmt->label, estate->exitlabel) == 0)
01737                     /* label matches named continue, so re-run loop */
01738                     estate->exitlabel = NULL;
01739                 else
01740                     /* label doesn't match named continue, so propagate upward */
01741                     return PLPGSQL_RC_CONTINUE;
01742                 break;
01743 
01744             case PLPGSQL_RC_RETURN:
01745                 return rc;
01746 
01747             default:
01748                 elog(ERROR, "unrecognized rc: %d", rc);
01749         }
01750     }
01751 }
01752 
01753 
01754 /* ----------
01755  * exec_stmt_while          Loop over statements as long
01756  *                  as an expression evaluates to
01757  *                  true or an exit occurs.
01758  * ----------
01759  */
01760 static int
01761 exec_stmt_while(PLpgSQL_execstate *estate, PLpgSQL_stmt_while *stmt)
01762 {
01763     for (;;)
01764     {
01765         int         rc;
01766         bool        value;
01767         bool        isnull;
01768 
01769         value = exec_eval_boolean(estate, stmt->cond, &isnull);
01770         exec_eval_cleanup(estate);
01771 
01772         if (isnull || !value)
01773             break;
01774 
01775         rc = exec_stmts(estate, stmt->body);
01776 
01777         switch (rc)
01778         {
01779             case PLPGSQL_RC_OK:
01780                 break;
01781 
01782             case PLPGSQL_RC_EXIT:
01783                 if (estate->exitlabel == NULL)
01784                     return PLPGSQL_RC_OK;
01785                 if (stmt->label == NULL)
01786                     return PLPGSQL_RC_EXIT;
01787                 if (strcmp(stmt->label, estate->exitlabel) != 0)
01788                     return PLPGSQL_RC_EXIT;
01789                 estate->exitlabel = NULL;
01790                 return PLPGSQL_RC_OK;
01791 
01792             case PLPGSQL_RC_CONTINUE:
01793                 if (estate->exitlabel == NULL)
01794                     /* anonymous continue, so re-run loop */
01795                     break;
01796                 else if (stmt->label != NULL &&
01797                          strcmp(stmt->label, estate->exitlabel) == 0)
01798                     /* label matches named continue, so re-run loop */
01799                     estate->exitlabel = NULL;
01800                 else
01801                     /* label doesn't match named continue, propagate upward */
01802                     return PLPGSQL_RC_CONTINUE;
01803                 break;
01804 
01805             case PLPGSQL_RC_RETURN:
01806                 return rc;
01807 
01808             default:
01809                 elog(ERROR, "unrecognized rc: %d", rc);
01810         }
01811     }
01812 
01813     return PLPGSQL_RC_OK;
01814 }
01815 
01816 
01817 /* ----------
01818  * exec_stmt_fori           Iterate an integer variable
01819  *                  from a lower to an upper value
01820  *                  incrementing or decrementing by the BY value
01821  * ----------
01822  */
01823 static int
01824 exec_stmt_fori(PLpgSQL_execstate *estate, PLpgSQL_stmt_fori *stmt)
01825 {
01826     PLpgSQL_var *var;
01827     Datum       value;
01828     bool        isnull;
01829     Oid         valtype;
01830     int32       loop_value;
01831     int32       end_value;
01832     int32       step_value;
01833     bool        found = false;
01834     int         rc = PLPGSQL_RC_OK;
01835 
01836     var = (PLpgSQL_var *) (estate->datums[stmt->var->dno]);
01837 
01838     /*
01839      * Get the value of the lower bound
01840      */
01841     value = exec_eval_expr(estate, stmt->lower, &isnull, &valtype);
01842     value = exec_cast_value(estate, value, valtype, var->datatype->typoid,
01843                             &(var->datatype->typinput),
01844                             var->datatype->typioparam,
01845                             var->datatype->atttypmod, isnull);
01846     if (isnull)
01847         ereport(ERROR,
01848                 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
01849                  errmsg("lower bound of FOR loop cannot be null")));
01850     loop_value = DatumGetInt32(value);
01851     exec_eval_cleanup(estate);
01852 
01853     /*
01854      * Get the value of the upper bound
01855      */
01856     value = exec_eval_expr(estate, stmt->upper, &isnull, &valtype);
01857     value = exec_cast_value(estate, value, valtype, var->datatype->typoid,
01858                             &(var->datatype->typinput),
01859                             var->datatype->typioparam,
01860                             var->datatype->atttypmod, isnull);
01861     if (isnull)
01862         ereport(ERROR,
01863                 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
01864                  errmsg("upper bound of FOR loop cannot be null")));
01865     end_value = DatumGetInt32(value);
01866     exec_eval_cleanup(estate);
01867 
01868     /*
01869      * Get the step value
01870      */
01871     if (stmt->step)
01872     {
01873         value = exec_eval_expr(estate, stmt->step, &isnull, &valtype);
01874         value = exec_cast_value(estate, value, valtype, var->datatype->typoid,
01875                                 &(var->datatype->typinput),
01876                                 var->datatype->typioparam,
01877                                 var->datatype->atttypmod, isnull);
01878         if (isnull)
01879             ereport(ERROR,
01880                     (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
01881                      errmsg("BY value of FOR loop cannot be null")));
01882         step_value = DatumGetInt32(value);
01883         exec_eval_cleanup(estate);
01884         if (step_value <= 0)
01885             ereport(ERROR,
01886                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
01887                   errmsg("BY value of FOR loop must be greater than zero")));
01888     }
01889     else
01890         step_value = 1;
01891 
01892     /*
01893      * Now do the loop
01894      */
01895     for (;;)
01896     {
01897         /*
01898          * Check against upper bound
01899          */
01900         if (stmt->reverse)
01901         {
01902             if (loop_value < end_value)
01903                 break;
01904         }
01905         else
01906         {
01907             if (loop_value > end_value)
01908                 break;
01909         }
01910 
01911         found = true;           /* looped at least once */
01912 
01913         /*
01914          * Assign current value to loop var
01915          */
01916         var->value = Int32GetDatum(loop_value);
01917         var->isnull = false;
01918 
01919         /*
01920          * Execute the statements
01921          */
01922         rc = exec_stmts(estate, stmt->body);
01923 
01924         if (rc == PLPGSQL_RC_RETURN)
01925             break;              /* break out of the loop */
01926         else if (rc == PLPGSQL_RC_EXIT)
01927         {
01928             if (estate->exitlabel == NULL)
01929                 /* unlabelled exit, finish the current loop */
01930                 rc = PLPGSQL_RC_OK;
01931             else if (stmt->label != NULL &&
01932                      strcmp(stmt->label, estate->exitlabel) == 0)
01933             {
01934                 /* labelled exit, matches the current stmt's label */
01935                 estate->exitlabel = NULL;
01936                 rc = PLPGSQL_RC_OK;
01937             }
01938 
01939             /*
01940              * otherwise, this is a labelled exit that does not match the
01941              * current statement's label, if any: return RC_EXIT so that the
01942              * EXIT continues to propagate up the stack.
01943              */
01944             break;
01945         }
01946         else if (rc == PLPGSQL_RC_CONTINUE)
01947         {
01948             if (estate->exitlabel == NULL)
01949                 /* unlabelled continue, so re-run the current loop */
01950                 rc = PLPGSQL_RC_OK;
01951             else if (stmt->label != NULL &&
01952                      strcmp(stmt->label, estate->exitlabel) == 0)
01953             {
01954                 /* label matches named continue, so re-run loop */
01955                 estate->exitlabel = NULL;
01956                 rc = PLPGSQL_RC_OK;
01957             }
01958             else
01959             {
01960                 /*
01961                  * otherwise, this is a named continue that does not match the
01962                  * current statement's label, if any: return RC_CONTINUE so
01963                  * that the CONTINUE will propagate up the stack.
01964                  */
01965                 break;
01966             }
01967         }
01968 
01969         /*
01970          * Increase/decrease loop value, unless it would overflow, in which
01971          * case exit the loop.
01972          */
01973         if (stmt->reverse)
01974         {
01975             if ((int32) (loop_value - step_value) > loop_value)
01976                 break;
01977             loop_value -= step_value;
01978         }
01979         else
01980         {
01981             if ((int32) (loop_value + step_value) < loop_value)
01982                 break;
01983             loop_value += step_value;
01984         }
01985     }
01986 
01987     /*
01988      * Set the FOUND variable to indicate the result of executing the loop
01989      * (namely, whether we looped one or more times). This must be set here so
01990      * that it does not interfere with the value of the FOUND variable inside
01991      * the loop processing itself.
01992      */
01993     exec_set_found(estate, found);
01994 
01995     return rc;
01996 }
01997 
01998 
01999 /* ----------
02000  * exec_stmt_fors           Execute a query, assign each
02001  *                  tuple to a record or row and
02002  *                  execute a group of statements
02003  *                  for it.
02004  * ----------
02005  */
02006 static int
02007 exec_stmt_fors(PLpgSQL_execstate *estate, PLpgSQL_stmt_fors *stmt)
02008 {
02009     Portal      portal;
02010     int         rc;
02011 
02012     /*
02013      * Open the implicit cursor for the statement using exec_run_select
02014      */
02015     exec_run_select(estate, stmt->query, 0, &portal);
02016 
02017     /*
02018      * Execute the loop
02019      */
02020     rc = exec_for_query(estate, (PLpgSQL_stmt_forq *) stmt, portal, true);
02021 
02022     /*
02023      * Close the implicit cursor
02024      */
02025     SPI_cursor_close(portal);
02026 
02027     return rc;
02028 }
02029 
02030 
02031 /* ----------
02032  * exec_stmt_forc           Execute a loop for each row from a cursor.
02033  * ----------
02034  */
02035 static int
02036 exec_stmt_forc(PLpgSQL_execstate *estate, PLpgSQL_stmt_forc *stmt)
02037 {
02038     PLpgSQL_var *curvar;
02039     char       *curname = NULL;
02040     PLpgSQL_expr *query;
02041     ParamListInfo paramLI;
02042     Portal      portal;
02043     int         rc;
02044 
02045     /* ----------
02046      * Get the cursor variable and if it has an assigned name, check
02047      * that it's not in use currently.
02048      * ----------
02049      */
02050     curvar = (PLpgSQL_var *) (estate->datums[stmt->curvar]);
02051     if (!curvar->isnull)
02052     {
02053         curname = TextDatumGetCString(curvar->value);
02054         if (SPI_cursor_find(curname) != NULL)
02055             ereport(ERROR,
02056                     (errcode(ERRCODE_DUPLICATE_CURSOR),
02057                      errmsg("cursor \"%s\" already in use", curname)));
02058     }
02059 
02060     /* ----------
02061      * Open the cursor just like an OPEN command
02062      *
02063      * Note: parser should already have checked that statement supplies
02064      * args iff cursor needs them, but we check again to be safe.
02065      * ----------
02066      */
02067     if (stmt->argquery != NULL)
02068     {
02069         /* ----------
02070          * OPEN CURSOR with args.  We fake a SELECT ... INTO ...
02071          * statement to evaluate the args and put 'em into the
02072          * internal row.
02073          * ----------
02074          */
02075         PLpgSQL_stmt_execsql set_args;
02076 
02077         if (curvar->cursor_explicit_argrow < 0)
02078             ereport(ERROR,
02079                     (errcode(ERRCODE_SYNTAX_ERROR),
02080                      errmsg("arguments given for cursor without arguments")));
02081 
02082         memset(&set_args, 0, sizeof(set_args));
02083         set_args.cmd_type = PLPGSQL_STMT_EXECSQL;
02084         set_args.lineno = stmt->lineno;
02085         set_args.sqlstmt = stmt->argquery;
02086         set_args.into = true;
02087         /* XXX historically this has not been STRICT */
02088         set_args.row = (PLpgSQL_row *)
02089             (estate->datums[curvar->cursor_explicit_argrow]);
02090 
02091         if (exec_stmt_execsql(estate, &set_args) != PLPGSQL_RC_OK)
02092             elog(ERROR, "open cursor failed during argument processing");
02093     }
02094     else
02095     {
02096         if (curvar->cursor_explicit_argrow >= 0)
02097             ereport(ERROR,
02098                     (errcode(ERRCODE_SYNTAX_ERROR),
02099                      errmsg("arguments required for cursor")));
02100     }
02101 
02102     query = curvar->cursor_explicit_expr;
02103     Assert(query);
02104 
02105     if (query->plan == NULL)
02106         exec_prepare_plan(estate, query, curvar->cursor_options);
02107 
02108     /*
02109      * Set up ParamListInfo (hook function and possibly data values)
02110      */
02111     paramLI = setup_param_list(estate, query);
02112 
02113     /*
02114      * Open the cursor (the paramlist will get copied into the portal)
02115      */
02116     portal = SPI_cursor_open_with_paramlist(curname, query->plan,
02117                                             paramLI,
02118                                             estate->readonly_func);
02119     if (portal == NULL)
02120         elog(ERROR, "could not open cursor: %s",
02121              SPI_result_code_string(SPI_result));
02122 
02123     /* don't need paramlist any more */
02124     if (paramLI)
02125         pfree(paramLI);
02126 
02127     /*
02128      * If cursor variable was NULL, store the generated portal name in it
02129      */
02130     if (curname == NULL)
02131         assign_text_var(curvar, portal->name);
02132 
02133     /*
02134      * Execute the loop.  We can't prefetch because the cursor is accessible
02135      * to the user, for instance via UPDATE WHERE CURRENT OF within the loop.
02136      */
02137     rc = exec_for_query(estate, (PLpgSQL_stmt_forq *) stmt, portal, false);
02138 
02139     /* ----------
02140      * Close portal, and restore cursor variable if it was initially NULL.
02141      * ----------
02142      */
02143     SPI_cursor_close(portal);
02144 
02145     if (curname == NULL)
02146     {
02147         free_var(curvar);
02148         curvar->value = (Datum) 0;
02149         curvar->isnull = true;
02150     }
02151 
02152     if (curname)
02153         pfree(curname);
02154 
02155     return rc;
02156 }
02157 
02158 
02159 /* ----------
02160  * exec_stmt_foreach_a          Loop over elements or slices of an array
02161  *
02162  * When looping over elements, the loop variable is the same type that the
02163  * array stores (eg: integer), when looping through slices, the loop variable
02164  * is an array of size and dimensions to match the size of the slice.
02165  * ----------
02166  */
02167 static int
02168 exec_stmt_foreach_a(PLpgSQL_execstate *estate, PLpgSQL_stmt_foreach_a *stmt)
02169 {
02170     ArrayType  *arr;
02171     Oid         arrtype;
02172     PLpgSQL_datum *loop_var;
02173     Oid         loop_var_elem_type;
02174     bool        found = false;
02175     int         rc = PLPGSQL_RC_OK;
02176     ArrayIterator array_iterator;
02177     Oid         iterator_result_type;
02178     Datum       value;
02179     bool        isnull;
02180 
02181     /* get the value of the array expression */
02182     value = exec_eval_expr(estate, stmt->expr, &isnull, &arrtype);
02183     if (isnull)
02184         ereport(ERROR,
02185                 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
02186                  errmsg("FOREACH expression must not be null")));
02187 
02188     /* check the type of the expression - must be an array */
02189     if (!OidIsValid(get_element_type(arrtype)))
02190         ereport(ERROR,
02191                 (errcode(ERRCODE_DATATYPE_MISMATCH),
02192                  errmsg("FOREACH expression must yield an array, not type %s",
02193                         format_type_be(arrtype))));
02194 
02195     /*
02196      * We must copy the array, else it will disappear in exec_eval_cleanup.
02197      * This is annoying, but cleanup will certainly happen while running the
02198      * loop body, so we have little choice.
02199      */
02200     arr = DatumGetArrayTypePCopy(value);
02201 
02202     /* Clean up any leftover temporary memory */
02203     exec_eval_cleanup(estate);
02204 
02205     /* Slice dimension must be less than or equal to array dimension */
02206     if (stmt->slice < 0 || stmt->slice > ARR_NDIM(arr))
02207         ereport(ERROR,
02208                 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
02209                errmsg("slice dimension (%d) is out of the valid range 0..%d",
02210                       stmt->slice, ARR_NDIM(arr))));
02211 
02212     /* Set up the loop variable and see if it is of an array type */
02213     loop_var = estate->datums[stmt->varno];
02214     if (loop_var->dtype == PLPGSQL_DTYPE_REC ||
02215         loop_var->dtype == PLPGSQL_DTYPE_ROW)
02216     {
02217         /*
02218          * Record/row variable is certainly not of array type, and might not
02219          * be initialized at all yet, so don't try to get its type
02220          */
02221         loop_var_elem_type = InvalidOid;
02222     }
02223     else
02224         loop_var_elem_type = get_element_type(exec_get_datum_type(estate,
02225                                                                   loop_var));
02226 
02227     /*
02228      * Sanity-check the loop variable type.  We don't try very hard here, and
02229      * should not be too picky since it's possible that exec_assign_value can
02230      * coerce values of different types.  But it seems worthwhile to complain
02231      * if the array-ness of the loop variable is not right.
02232      */
02233     if (stmt->slice > 0 && loop_var_elem_type == InvalidOid)
02234         ereport(ERROR,
02235                 (errcode(ERRCODE_DATATYPE_MISMATCH),
02236         errmsg("FOREACH ... SLICE loop variable must be of an array type")));
02237     if (stmt->slice == 0 && loop_var_elem_type != InvalidOid)
02238         ereport(ERROR,
02239                 (errcode(ERRCODE_DATATYPE_MISMATCH),
02240               errmsg("FOREACH loop variable must not be of an array type")));
02241 
02242     /* Create an iterator to step through the array */
02243     array_iterator = array_create_iterator(arr, stmt->slice);
02244 
02245     /* Identify iterator result type */
02246     if (stmt->slice > 0)
02247     {
02248         /* When slicing, nominal type of result is same as array type */
02249         iterator_result_type = arrtype;
02250     }
02251     else
02252     {
02253         /* Without slicing, results are individual array elements */
02254         iterator_result_type = ARR_ELEMTYPE(arr);
02255     }
02256 
02257     /* Iterate over the array elements or slices */
02258     while (array_iterate(array_iterator, &value, &isnull))
02259     {
02260         found = true;           /* looped at least once */
02261 
02262         /* Assign current element/slice to the loop variable */
02263         exec_assign_value(estate, loop_var, value, iterator_result_type,
02264                           &isnull);
02265 
02266         /* In slice case, value is temporary; must free it to avoid leakage */
02267         if (stmt->slice > 0)
02268             pfree(DatumGetPointer(value));
02269 
02270         /*
02271          * Execute the statements
02272          */
02273         rc = exec_stmts(estate, stmt->body);
02274 
02275         /* Handle the return code */
02276         if (rc == PLPGSQL_RC_RETURN)
02277             break;              /* break out of the loop */
02278         else if (rc == PLPGSQL_RC_EXIT)
02279         {
02280             if (estate->exitlabel == NULL)
02281                 /* unlabelled exit, finish the current loop */
02282                 rc = PLPGSQL_RC_OK;
02283             else if (stmt->label != NULL &&
02284                      strcmp(stmt->label, estate->exitlabel) == 0)
02285             {
02286                 /* labelled exit, matches the current stmt's label */
02287                 estate->exitlabel = NULL;
02288                 rc = PLPGSQL_RC_OK;
02289             }
02290 
02291             /*
02292              * otherwise, this is a labelled exit that does not match the
02293              * current statement's label, if any: return RC_EXIT so that the
02294              * EXIT continues to propagate up the stack.
02295              */
02296             break;
02297         }
02298         else if (rc == PLPGSQL_RC_CONTINUE)
02299         {
02300             if (estate->exitlabel == NULL)
02301                 /* unlabelled continue, so re-run the current loop */
02302                 rc = PLPGSQL_RC_OK;
02303             else if (stmt->label != NULL &&
02304                      strcmp(stmt->label, estate->exitlabel) == 0)
02305             {
02306                 /* label matches named continue, so re-run loop */
02307                 estate->exitlabel = NULL;
02308                 rc = PLPGSQL_RC_OK;
02309             }
02310             else
02311             {
02312                 /*
02313                  * otherwise, this is a named continue that does not match the
02314                  * current statement's label, if any: return RC_CONTINUE so
02315                  * that the CONTINUE will propagate up the stack.
02316                  */
02317                 break;
02318             }
02319         }
02320     }
02321 
02322     /* Release temporary memory, including the array value */
02323     array_free_iterator(array_iterator);
02324     pfree(arr);
02325 
02326     /*
02327      * Set the FOUND variable to indicate the result of executing the loop
02328      * (namely, whether we looped one or more times). This must be set here so
02329      * that it does not interfere with the value of the FOUND variable inside
02330      * the loop processing itself.
02331      */
02332     exec_set_found(estate, found);
02333 
02334     return rc;
02335 }
02336 
02337 
02338 /* ----------
02339  * exec_stmt_exit           Implements EXIT and CONTINUE
02340  *
02341  * This begins the process of exiting / restarting a loop.
02342  * ----------
02343  */
02344 static int
02345 exec_stmt_exit(PLpgSQL_execstate *estate, PLpgSQL_stmt_exit *stmt)
02346 {
02347     /*
02348      * If the exit / continue has a condition, evaluate it
02349      */
02350     if (stmt->cond != NULL)
02351     {
02352         bool        value;
02353         bool        isnull;
02354 
02355         value = exec_eval_boolean(estate, stmt->cond, &isnull);
02356         exec_eval_cleanup(estate);
02357         if (isnull || value == false)
02358             return PLPGSQL_RC_OK;
02359     }
02360 
02361     estate->exitlabel = stmt->label;
02362     if (stmt->is_exit)
02363         return PLPGSQL_RC_EXIT;
02364     else
02365         return PLPGSQL_RC_CONTINUE;
02366 }
02367 
02368 
02369 /* ----------
02370  * exec_stmt_return         Evaluate an expression and start
02371  *                  returning from the function.
02372  * ----------
02373  */
02374 static int
02375 exec_stmt_return(PLpgSQL_execstate *estate, PLpgSQL_stmt_return *stmt)
02376 {
02377     /*
02378      * If processing a set-returning PL/pgSQL function, the final RETURN
02379      * indicates that the function is finished producing tuples.  The rest of
02380      * the work will be done at the top level.
02381      */
02382     if (estate->retisset)
02383         return PLPGSQL_RC_RETURN;
02384 
02385     /* initialize for null result (possibly a tuple) */
02386     estate->retval = (Datum) 0;
02387     estate->rettupdesc = NULL;
02388     estate->retisnull = true;
02389 
02390     /*
02391      * This special-case path covers record/row variables in fn_retistuple
02392      * functions, as well as functions with one or more OUT parameters.
02393      */
02394     if (stmt->retvarno >= 0)
02395     {
02396         PLpgSQL_datum *retvar = estate->datums[stmt->retvarno];
02397 
02398         switch (retvar->dtype)
02399         {
02400             case PLPGSQL_DTYPE_VAR:
02401                 {
02402                     PLpgSQL_var *var = (PLpgSQL_var *) retvar;
02403 
02404                     estate->retval = var->value;
02405                     estate->retisnull = var->isnull;
02406                     estate->rettype = var->datatype->typoid;
02407                 }
02408                 break;
02409 
02410             case PLPGSQL_DTYPE_REC:
02411                 {
02412                     PLpgSQL_rec *rec = (PLpgSQL_rec *) retvar;
02413 
02414                     if (HeapTupleIsValid(rec->tup))
02415                     {
02416                         estate->retval = PointerGetDatum(rec->tup);
02417                         estate->rettupdesc = rec->tupdesc;
02418                         estate->retisnull = false;
02419                     }
02420                 }
02421                 break;
02422 
02423             case PLPGSQL_DTYPE_ROW:
02424                 {
02425                     PLpgSQL_row *row = (PLpgSQL_row *) retvar;
02426 
02427                     Assert(row->rowtupdesc);
02428                     estate->retval =
02429                         PointerGetDatum(make_tuple_from_row(estate, row,
02430                                                             row->rowtupdesc));
02431                     if (DatumGetPointer(estate->retval) == NULL)        /* should not happen */
02432                         elog(ERROR, "row not compatible with its own tupdesc");
02433                     estate->rettupdesc = row->rowtupdesc;
02434                     estate->retisnull = false;
02435                 }
02436                 break;
02437 
02438             default:
02439                 elog(ERROR, "unrecognized dtype: %d", retvar->dtype);
02440         }
02441 
02442         return PLPGSQL_RC_RETURN;
02443     }
02444 
02445     if (stmt->expr != NULL)
02446     {
02447         estate->retval = exec_eval_expr(estate, stmt->expr,
02448                                         &(estate->retisnull),
02449                                         &(estate->rettype));
02450 
02451         if (estate->retistuple && !estate->retisnull)
02452         {
02453             /* Convert composite datum to a HeapTuple and TupleDesc */
02454             HeapTuple   tuple;
02455             TupleDesc   tupdesc;
02456 
02457             /* Source must be of RECORD or composite type */
02458             if (!type_is_rowtype(estate->rettype))
02459                 ereport(ERROR,
02460                         (errcode(ERRCODE_DATATYPE_MISMATCH),
02461                          errmsg("cannot return non-composite value from function returning composite type")));
02462             tuple = get_tuple_from_datum(estate->retval);
02463             tupdesc = get_tupdesc_from_datum(estate->retval);
02464             estate->retval = PointerGetDatum(tuple);
02465             estate->rettupdesc = CreateTupleDescCopy(tupdesc);
02466             ReleaseTupleDesc(tupdesc);
02467         }
02468 
02469         return PLPGSQL_RC_RETURN;
02470     }
02471 
02472     /*
02473      * Special hack for function returning VOID: instead of NULL, return a
02474      * non-null VOID value.  This is of dubious importance but is kept for
02475      * backwards compatibility.
02476      */
02477     if (estate->fn_rettype == VOIDOID)
02478     {
02479         estate->retval = (Datum) 0;
02480         estate->retisnull = false;
02481         estate->rettype = VOIDOID;
02482     }
02483 
02484     return PLPGSQL_RC_RETURN;
02485 }
02486 
02487 /* ----------
02488  * exec_stmt_return_next        Evaluate an expression and add it to the
02489  *                              list of tuples returned by the current
02490  *                              SRF.
02491  * ----------
02492  */
02493 static int
02494 exec_stmt_return_next(PLpgSQL_execstate *estate,
02495                       PLpgSQL_stmt_return_next *stmt)
02496 {
02497     TupleDesc   tupdesc;
02498     int         natts;
02499     HeapTuple   tuple = NULL;
02500     bool        free_tuple = false;
02501 
02502     if (!estate->retisset)
02503         ereport(ERROR,
02504                 (errcode(ERRCODE_SYNTAX_ERROR),
02505                  errmsg("cannot use RETURN NEXT in a non-SETOF function")));
02506 
02507     if (estate->tuple_store == NULL)
02508         exec_init_tuple_store(estate);
02509 
02510     /* rettupdesc will be filled by exec_init_tuple_store */
02511     tupdesc = estate->rettupdesc;
02512     natts = tupdesc->natts;
02513 
02514     /*
02515      * This special-case path covers record/row variables in fn_retistuple
02516      * functions, as well as functions with one or more OUT parameters.
02517      */
02518     if (stmt->retvarno >= 0)
02519     {
02520         PLpgSQL_datum *retvar = estate->datums[stmt->retvarno];
02521 
02522         switch (retvar->dtype)
02523         {
02524             case PLPGSQL_DTYPE_VAR:
02525                 {
02526                     PLpgSQL_var *var = (PLpgSQL_var *) retvar;
02527                     Datum       retval = var->value;
02528                     bool        isNull = var->isnull;
02529 
02530                     if (natts != 1)
02531                         ereport(ERROR,
02532                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
02533                         errmsg("wrong result type supplied in RETURN NEXT")));
02534 
02535                     /* coerce type if needed */
02536                     retval = exec_simple_cast_value(estate,
02537                                                     retval,
02538                                                     var->datatype->typoid,
02539                                                  tupdesc->attrs[0]->atttypid,
02540                                                 tupdesc->attrs[0]->atttypmod,
02541                                                     isNull);
02542 
02543                     tuplestore_putvalues(estate->tuple_store, tupdesc,
02544                                          &retval, &isNull);
02545                 }
02546                 break;
02547 
02548             case PLPGSQL_DTYPE_REC:
02549                 {
02550                     PLpgSQL_rec *rec = (PLpgSQL_rec *) retvar;
02551                     TupleConversionMap *tupmap;
02552 
02553                     if (!HeapTupleIsValid(rec->tup))
02554                         ereport(ERROR,
02555                           (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
02556                            errmsg("record \"%s\" is not assigned yet",
02557                                   rec->refname),
02558                         errdetail("The tuple structure of a not-yet-assigned"
02559                                   " record is indeterminate.")));
02560                     tupmap = convert_tuples_by_position(rec->tupdesc,
02561                                                         tupdesc,
02562                                                         gettext_noop("wrong record type supplied in RETURN NEXT"));
02563                     tuple = rec->tup;
02564                     /* it might need conversion */
02565                     if (tupmap)
02566                     {
02567                         tuple = do_convert_tuple(tuple, tupmap);
02568                         free_conversion_map(tupmap);
02569                         free_tuple = true;
02570                     }
02571                 }
02572                 break;
02573 
02574             case PLPGSQL_DTYPE_ROW:
02575                 {
02576                     PLpgSQL_row *row = (PLpgSQL_row *) retvar;
02577 
02578                     tuple = make_tuple_from_row(estate, row, tupdesc);
02579                     if (tuple == NULL)
02580                         ereport(ERROR,
02581                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
02582                         errmsg("wrong record type supplied in RETURN NEXT")));
02583                     free_tuple = true;
02584                 }
02585                 break;
02586 
02587             default:
02588                 elog(ERROR, "unrecognized dtype: %d", retvar->dtype);
02589                 break;
02590         }
02591     }
02592     else if (stmt->expr)
02593     {
02594         Datum       retval;
02595         bool        isNull;
02596         Oid         rettype;
02597 
02598         retval = exec_eval_expr(estate,
02599                                 stmt->expr,
02600                                 &isNull,
02601                                 &rettype);
02602 
02603         if (estate->retistuple)
02604         {
02605             /* Expression should be of RECORD or composite type */
02606             if (!isNull)
02607             {
02608                 TupleDesc   retvaldesc;
02609                 TupleConversionMap *tupmap;
02610 
02611                 if (!type_is_rowtype(rettype))
02612                     ereport(ERROR,
02613                             (errcode(ERRCODE_DATATYPE_MISMATCH),
02614                              errmsg("cannot return non-composite value from function returning composite type")));
02615 
02616                 tuple = get_tuple_from_datum(retval);
02617                 free_tuple = true;      /* tuple is always freshly palloc'd */
02618 
02619                 /* it might need conversion */
02620                 retvaldesc = get_tupdesc_from_datum(retval);
02621                 tupmap = convert_tuples_by_position(retvaldesc, tupdesc,
02622                                                     gettext_noop("returned record type does not match expected record type"));
02623                 if (tupmap)
02624                 {
02625                     HeapTuple   newtuple;
02626 
02627                     newtuple = do_convert_tuple(tuple, tupmap);
02628                     free_conversion_map(tupmap);
02629                     heap_freetuple(tuple);
02630                     tuple = newtuple;
02631                 }
02632                 ReleaseTupleDesc(retvaldesc);
02633                 /* tuple will be stored into tuplestore below */
02634             }
02635             else
02636             {
02637                 /* Composite NULL --- store a row of nulls */
02638                 Datum      *nulldatums;
02639                 bool       *nullflags;
02640 
02641                 nulldatums = (Datum *) palloc0(natts * sizeof(Datum));
02642                 nullflags = (bool *) palloc(natts * sizeof(bool));
02643                 memset(nullflags, true, natts * sizeof(bool));
02644                 tuplestore_putvalues(estate->tuple_store, tupdesc,
02645                                      nulldatums, nullflags);
02646                 pfree(nulldatums);
02647                 pfree(nullflags);
02648             }
02649         }
02650         else
02651         {
02652             /* Simple scalar result */
02653             if (natts != 1)
02654                 ereport(ERROR,
02655                         (errcode(ERRCODE_DATATYPE_MISMATCH),
02656                        errmsg("wrong result type supplied in RETURN NEXT")));
02657 
02658             /* coerce type if needed */
02659             retval = exec_simple_cast_value(estate,
02660                                             retval,
02661                                             rettype,
02662                                             tupdesc->attrs[0]->atttypid,
02663                                             tupdesc->attrs[0]->atttypmod,
02664                                             isNull);
02665 
02666             tuplestore_putvalues(estate->tuple_store, tupdesc,
02667                                  &retval, &isNull);
02668         }
02669     }
02670     else
02671     {
02672         ereport(ERROR,
02673                 (errcode(ERRCODE_SYNTAX_ERROR),
02674                  errmsg("RETURN NEXT must have a parameter")));
02675     }
02676 
02677     if (HeapTupleIsValid(tuple))
02678     {
02679         tuplestore_puttuple(estate->tuple_store, tuple);
02680 
02681         if (free_tuple)
02682             heap_freetuple(tuple);
02683     }
02684 
02685     exec_eval_cleanup(estate);
02686 
02687     return PLPGSQL_RC_OK;
02688 }
02689 
02690 /* ----------
02691  * exec_stmt_return_query       Evaluate a query and add it to the
02692  *                              list of tuples returned by the current
02693  *                              SRF.
02694  * ----------
02695  */
02696 static int
02697 exec_stmt_return_query(PLpgSQL_execstate *estate,
02698                        PLpgSQL_stmt_return_query *stmt)
02699 {
02700     Portal      portal;
02701     uint32      processed = 0;
02702     TupleConversionMap *tupmap;
02703 
02704     if (!estate->retisset)
02705         ereport(ERROR,
02706                 (errcode(ERRCODE_SYNTAX_ERROR),
02707                  errmsg("cannot use RETURN QUERY in a non-SETOF function")));
02708 
02709     if (estate->tuple_store == NULL)
02710         exec_init_tuple_store(estate);
02711 
02712     if (stmt->query != NULL)
02713     {
02714         /* static query */
02715         exec_run_select(estate, stmt->query, 0, &portal);
02716     }
02717     else
02718     {
02719         /* RETURN QUERY EXECUTE */
02720         Assert(stmt->dynquery != NULL);
02721         portal = exec_dynquery_with_params(estate, stmt->dynquery,
02722                                            stmt->params, NULL, 0);
02723     }
02724 
02725     tupmap = convert_tuples_by_position(portal->tupDesc,
02726                                         estate->rettupdesc,
02727      gettext_noop("structure of query does not match function result type"));
02728 
02729     while (true)
02730     {
02731         int         i;
02732 
02733         SPI_cursor_fetch(portal, true, 50);
02734         if (SPI_processed == 0)
02735             break;
02736 
02737         for (i = 0; i < SPI_processed; i++)
02738         {
02739             HeapTuple   tuple = SPI_tuptable->vals[i];
02740 
02741             if (tupmap)
02742                 tuple = do_convert_tuple(tuple, tupmap);
02743             tuplestore_puttuple(estate->tuple_store, tuple);
02744             if (tupmap)
02745                 heap_freetuple(tuple);
02746             processed++;
02747         }
02748 
02749         SPI_freetuptable(SPI_tuptable);
02750     }
02751 
02752     if (tupmap)
02753         free_conversion_map(tupmap);
02754 
02755     SPI_freetuptable(SPI_tuptable);
02756     SPI_cursor_close(portal);
02757 
02758     estate->eval_processed = processed;
02759     exec_set_found(estate, processed != 0);
02760 
02761     return PLPGSQL_RC_OK;
02762 }
02763 
02764 static void
02765 exec_init_tuple_store(PLpgSQL_execstate *estate)
02766 {
02767     ReturnSetInfo *rsi = estate->rsi;
02768     MemoryContext oldcxt;
02769     ResourceOwner oldowner;
02770 
02771     /*
02772      * Check caller can handle a set result in the way we want
02773      */
02774     if (!rsi || !IsA(rsi, ReturnSetInfo) ||
02775         (rsi->allowedModes & SFRM_Materialize) == 0 ||
02776         rsi->expectedDesc == NULL)
02777         ereport(ERROR,
02778                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02779                  errmsg("set-valued function called in context that cannot accept a set")));
02780 
02781     /*
02782      * Switch to the right memory context and resource owner for storing the
02783      * tuplestore for return set. If we're within a subtransaction opened for
02784      * an exception-block, for example, we must still create the tuplestore in
02785      * the resource owner that was active when this function was entered, and
02786      * not in the subtransaction resource owner.
02787      */
02788     oldcxt = MemoryContextSwitchTo(estate->tuple_store_cxt);
02789     oldowner = CurrentResourceOwner;
02790     CurrentResourceOwner = estate->tuple_store_owner;
02791 
02792     estate->tuple_store =
02793         tuplestore_begin_heap(rsi->allowedModes & SFRM_Materialize_Random,
02794                               false, work_mem);
02795 
02796     CurrentResourceOwner = oldowner;
02797     MemoryContextSwitchTo(oldcxt);
02798 
02799     estate->rettupdesc = rsi->expectedDesc;
02800 }
02801 
02802 /* ----------
02803  * exec_stmt_raise          Build a message and throw it with elog()
02804  * ----------
02805  */
02806 static int
02807 exec_stmt_raise(PLpgSQL_execstate *estate, PLpgSQL_stmt_raise *stmt)
02808 {
02809     int         err_code = 0;
02810     char       *condname = NULL;
02811     char       *err_message = NULL;
02812     char       *err_detail = NULL;
02813     char       *err_hint = NULL;
02814     ListCell   *lc;
02815 
02816     /* RAISE with no parameters: re-throw current exception */
02817     if (stmt->condname == NULL && stmt->message == NULL &&
02818         stmt->options == NIL)
02819     {
02820         if (estate->cur_error != NULL)
02821             ReThrowError(estate->cur_error);
02822         /* oops, we're not inside a handler */
02823         ereport(ERROR,
02824         (errcode(ERRCODE_STACKED_DIAGNOSTICS_ACCESSED_WITHOUT_ACTIVE_HANDLER),
02825          errmsg("RAISE without parameters cannot be used outside an exception handler")));
02826     }
02827 
02828     if (stmt->condname)
02829     {
02830         err_code = plpgsql_recognize_err_condition(stmt->condname, true);
02831         condname = pstrdup(stmt->condname);
02832     }
02833 
02834     if (stmt->message)
02835     {
02836         StringInfoData ds;
02837         ListCell   *current_param;
02838         char       *cp;
02839 
02840         initStringInfo(&ds);
02841         current_param = list_head(stmt->params);
02842 
02843         for (cp = stmt->message; *cp; cp++)
02844         {
02845             /*
02846              * Occurrences of a single % are replaced by the next parameter's
02847              * external representation. Double %'s are converted to one %.
02848              */
02849             if (cp[0] == '%')
02850             {
02851                 Oid         paramtypeid;
02852                 Datum       paramvalue;
02853                 bool        paramisnull;
02854                 char       *extval;
02855 
02856                 if (cp[1] == '%')
02857                 {
02858                     appendStringInfoChar(&ds, '%');
02859                     cp++;
02860                     continue;
02861                 }
02862 
02863                 if (current_param == NULL)
02864                     ereport(ERROR,
02865                             (errcode(ERRCODE_SYNTAX_ERROR),
02866                           errmsg("too few parameters specified for RAISE")));
02867 
02868                 paramvalue = exec_eval_expr(estate,
02869                                       (PLpgSQL_expr *) lfirst(current_param),
02870                                             &paramisnull,
02871                                             &paramtypeid);
02872 
02873                 if (paramisnull)
02874                     extval = "<NULL>";
02875                 else
02876                     extval = convert_value_to_string(estate,
02877                                                      paramvalue,
02878                                                      paramtypeid);
02879                 appendStringInfoString(&ds, extval);
02880                 current_param = lnext(current_param);
02881                 exec_eval_cleanup(estate);
02882             }
02883             else
02884                 appendStringInfoChar(&ds, cp[0]);
02885         }
02886 
02887         /*
02888          * If more parameters were specified than were required to process the
02889          * format string, throw an error
02890          */
02891         if (current_param != NULL)
02892             ereport(ERROR,
02893                     (errcode(ERRCODE_SYNTAX_ERROR),
02894                      errmsg("too many parameters specified for RAISE")));
02895 
02896         err_message = ds.data;
02897         /* No pfree(ds.data), the pfree(err_message) does it */
02898     }
02899 
02900     foreach(lc, stmt->options)
02901     {
02902         PLpgSQL_raise_option *opt = (PLpgSQL_raise_option *) lfirst(lc);
02903         Datum       optionvalue;
02904         bool        optionisnull;
02905         Oid         optiontypeid;
02906         char       *extval;
02907 
02908         optionvalue = exec_eval_expr(estate, opt->expr,
02909                                      &optionisnull,
02910                                      &optiontypeid);
02911         if (optionisnull)
02912             ereport(ERROR,
02913                     (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
02914                      errmsg("RAISE statement option cannot be null")));
02915 
02916         extval = convert_value_to_string(estate, optionvalue, optiontypeid);
02917 
02918         switch (opt->opt_type)
02919         {
02920             case PLPGSQL_RAISEOPTION_ERRCODE:
02921                 if (err_code)
02922                     ereport(ERROR,
02923                             (errcode(ERRCODE_SYNTAX_ERROR),
02924                              errmsg("RAISE option already specified: %s",
02925                                     "ERRCODE")));
02926                 err_code = plpgsql_recognize_err_condition(extval, true);
02927                 condname = pstrdup(extval);
02928                 break;
02929             case PLPGSQL_RAISEOPTION_MESSAGE:
02930                 if (err_message)
02931                     ereport(ERROR,
02932                             (errcode(ERRCODE_SYNTAX_ERROR),
02933                              errmsg("RAISE option already specified: %s",
02934                                     "MESSAGE")));
02935                 err_message = pstrdup(extval);
02936                 break;
02937             case PLPGSQL_RAISEOPTION_DETAIL:
02938                 if (err_detail)
02939                     ereport(ERROR,
02940                             (errcode(ERRCODE_SYNTAX_ERROR),
02941                              errmsg("RAISE option already specified: %s",
02942                                     "DETAIL")));
02943                 err_detail = pstrdup(extval);
02944                 break;
02945             case PLPGSQL_RAISEOPTION_HINT:
02946                 if (err_hint)
02947                     ereport(ERROR,
02948                             (errcode(ERRCODE_SYNTAX_ERROR),
02949                              errmsg("RAISE option already specified: %s",
02950                                     "HINT")));
02951                 err_hint = pstrdup(extval);
02952                 break;
02953             default:
02954                 elog(ERROR, "unrecognized raise option: %d", opt->opt_type);
02955         }
02956 
02957         exec_eval_cleanup(estate);
02958     }
02959 
02960     /* Default code if nothing specified */
02961     if (err_code == 0 && stmt->elog_level >= ERROR)
02962         err_code = ERRCODE_RAISE_EXCEPTION;
02963 
02964     /* Default error message if nothing specified */
02965     if (err_message == NULL)
02966     {
02967         if (condname)
02968         {
02969             err_message = condname;
02970             condname = NULL;
02971         }
02972         else
02973             err_message = pstrdup(unpack_sql_state(err_code));
02974     }
02975 
02976     /*
02977      * Throw the error (may or may not come back)
02978      */
02979     estate->err_text = raise_skip_msg;  /* suppress traceback of raise */
02980 
02981     ereport(stmt->elog_level,
02982             (err_code ? errcode(err_code) : 0,
02983              errmsg_internal("%s", err_message),
02984              (err_detail != NULL) ? errdetail_internal("%s", err_detail) : 0,
02985              (err_hint != NULL) ? errhint("%s", err_hint) : 0));
02986 
02987     estate->err_text = NULL;    /* un-suppress... */
02988 
02989     if (condname != NULL)
02990         pfree(condname);
02991     if (err_message != NULL)
02992         pfree(err_message);
02993     if (err_detail != NULL)
02994         pfree(err_detail);
02995     if (err_hint != NULL)
02996         pfree(err_hint);
02997 
02998     return PLPGSQL_RC_OK;
02999 }
03000 
03001 
03002 /* ----------
03003  * Initialize a mostly empty execution state
03004  * ----------
03005  */
03006 static void
03007 plpgsql_estate_setup(PLpgSQL_execstate *estate,
03008                      PLpgSQL_function *func,
03009                      ReturnSetInfo *rsi)
03010 {
03011     /* this link will be restored at exit from plpgsql_call_handler */
03012     func->cur_estate = estate;
03013 
03014     estate->func = func;
03015 
03016     estate->retval = (Datum) 0;
03017     estate->retisnull = true;
03018     estate->rettype = InvalidOid;
03019 
03020     estate->fn_rettype = func->fn_rettype;
03021     estate->retistuple = func->fn_retistuple;
03022     estate->retisset = func->fn_retset;
03023 
03024     estate->readonly_func = func->fn_readonly;
03025 
03026     estate->rettupdesc = NULL;
03027     estate->exitlabel = NULL;
03028     estate->cur_error = NULL;
03029 
03030     estate->tuple_store = NULL;
03031     if (rsi)
03032     {
03033         estate->tuple_store_cxt = rsi->econtext->ecxt_per_query_memory;
03034         estate->tuple_store_owner = CurrentResourceOwner;
03035     }
03036     else
03037     {
03038         estate->tuple_store_cxt = NULL;
03039         estate->tuple_store_owner = NULL;
03040     }
03041     estate->rsi = rsi;
03042 
03043     estate->found_varno = func->found_varno;
03044     estate->ndatums = func->ndatums;
03045     estate->datums = palloc(sizeof(PLpgSQL_datum *) * estate->ndatums);
03046     /* caller is expected to fill the datums array */
03047 
03048     estate->eval_tuptable = NULL;
03049     estate->eval_processed = 0;
03050     estate->eval_lastoid = InvalidOid;
03051     estate->eval_econtext = NULL;
03052     estate->cur_expr = NULL;
03053 
03054     estate->err_stmt = NULL;
03055     estate->err_text = NULL;
03056 
03057     estate->plugin_info = NULL;
03058 
03059     /*
03060      * Create an EState and ExprContext for evaluation of simple expressions.
03061      */
03062     plpgsql_create_econtext(estate);
03063 
03064     /*
03065      * Let the plugin see this function before we initialize any local
03066      * PL/pgSQL variables - note that we also give the plugin a few function
03067      * pointers so it can call back into PL/pgSQL for doing things like
03068      * variable assignments and stack traces
03069      */
03070     if (*plugin_ptr)
03071     {
03072         (*plugin_ptr)->error_callback = plpgsql_exec_error_callback;
03073         (*plugin_ptr)->assign_expr = exec_assign_expr;
03074 
03075         if ((*plugin_ptr)->func_setup)
03076             ((*plugin_ptr)->func_setup) (estate, func);
03077     }
03078 }
03079 
03080 /* ----------
03081  * Release temporary memory used by expression/subselect evaluation
03082  *
03083  * NB: the result of the evaluation is no longer valid after this is done,
03084  * unless it is a pass-by-value datatype.
03085  *
03086  * NB: if you change this code, see also the hacks in exec_assign_value's
03087  * PLPGSQL_DTYPE_ARRAYELEM case.
03088  * ----------
03089  */
03090 static void
03091 exec_eval_cleanup(PLpgSQL_execstate *estate)
03092 {
03093     /* Clear result of a full SPI_execute */
03094     if (estate->eval_tuptable != NULL)
03095         SPI_freetuptable(estate->eval_tuptable);
03096     estate->eval_tuptable = NULL;
03097 
03098     /* Clear result of exec_eval_simple_expr (but keep the econtext) */
03099     if (estate->eval_econtext != NULL)
03100         ResetExprContext(estate->eval_econtext);
03101 }
03102 
03103 
03104 /* ----------
03105  * Generate a prepared plan
03106  * ----------
03107  */
03108 static void
03109 exec_prepare_plan(PLpgSQL_execstate *estate,
03110                   PLpgSQL_expr *expr, int cursorOptions)
03111 {
03112     SPIPlanPtr  plan;
03113 
03114     /*
03115      * The grammar can't conveniently set expr->func while building the parse
03116      * tree, so make sure it's set before parser hooks need it.
03117      */
03118     expr->func = estate->func;
03119 
03120     /*
03121      * Generate and save the plan
03122      */
03123     plan = SPI_prepare_params(expr->query,
03124                               (ParserSetupHook) plpgsql_parser_setup,
03125                               (void *) expr,
03126                               cursorOptions);
03127     if (plan == NULL)
03128     {
03129         /* Some SPI errors deserve specific error messages */
03130         switch (SPI_result)
03131         {
03132             case SPI_ERROR_COPY:
03133                 ereport(ERROR,
03134                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
03135                          errmsg("cannot COPY to/from client in PL/pgSQL")));
03136             case SPI_ERROR_TRANSACTION:
03137                 ereport(ERROR,
03138                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
03139                          errmsg("cannot begin/end transactions in PL/pgSQL"),
03140                          errhint("Use a BEGIN block with an EXCEPTION clause instead.")));
03141             default:
03142                 elog(ERROR, "SPI_prepare_params failed for \"%s\": %s",
03143                      expr->query, SPI_result_code_string(SPI_result));
03144         }
03145     }
03146     SPI_keepplan(plan);
03147     expr->plan = plan;
03148 
03149     /* Check to see if it's a simple expression */
03150     exec_simple_check_plan(expr);
03151 }
03152 
03153 
03154 /* ----------
03155  * exec_stmt_execsql            Execute an SQL statement (possibly with INTO).
03156  * ----------
03157  */
03158 static int
03159 exec_stmt_execsql(PLpgSQL_execstate *estate,
03160                   PLpgSQL_stmt_execsql *stmt)
03161 {
03162     ParamListInfo paramLI;
03163     long        tcount;
03164     int         rc;
03165     PLpgSQL_expr *expr = stmt->sqlstmt;
03166 
03167     /*
03168      * On the first call for this statement generate the plan, and detect
03169      * whether the statement is INSERT/UPDATE/DELETE
03170      */
03171     if (expr->plan == NULL)
03172     {
03173         ListCell   *l;
03174 
03175         exec_prepare_plan(estate, expr, 0);
03176         stmt->mod_stmt = false;
03177         foreach(l, SPI_plan_get_plan_sources(expr->plan))
03178         {
03179             CachedPlanSource *plansource = (CachedPlanSource *) lfirst(l);
03180             ListCell   *l2;
03181 
03182             foreach(l2, plansource->query_list)
03183             {
03184                 Query      *q = (Query *) lfirst(l2);
03185 
03186                 Assert(IsA(q, Query));
03187                 if (q->canSetTag)
03188                 {
03189                     if (q->commandType == CMD_INSERT ||
03190                         q->commandType == CMD_UPDATE ||
03191                         q->commandType == CMD_DELETE)
03192                         stmt->mod_stmt = true;
03193                 }
03194             }
03195         }
03196     }
03197 
03198     /*
03199      * Set up ParamListInfo (hook function and possibly data values)
03200      */
03201     paramLI = setup_param_list(estate, expr);
03202 
03203     /*
03204      * If we have INTO, then we only need one row back ... but if we have INTO
03205      * STRICT, ask for two rows, so that we can verify the statement returns
03206      * only one.  INSERT/UPDATE/DELETE are always treated strictly. Without
03207      * INTO, just run the statement to completion (tcount = 0).
03208      *
03209      * We could just ask for two rows always when using INTO, but there are
03210      * some cases where demanding the extra row costs significant time, eg by
03211      * forcing completion of a sequential scan.  So don't do it unless we need
03212      * to enforce strictness.
03213      */
03214     if (stmt->into)
03215     {
03216         if (stmt->strict || stmt->mod_stmt)
03217             tcount = 2;
03218         else
03219             tcount = 1;
03220     }
03221     else
03222         tcount = 0;
03223 
03224     /*
03225      * Execute the plan
03226      */
03227     rc = SPI_execute_plan_with_paramlist(expr->plan, paramLI,
03228                                          estate->readonly_func, tcount);
03229 
03230     /*
03231      * Check for error, and set FOUND if appropriate (for historical reasons
03232      * we set FOUND only for certain query types).  Also Assert that we
03233      * identified the statement type the same as SPI did.
03234      */
03235     switch (rc)
03236     {
03237         case SPI_OK_SELECT:
03238             Assert(!stmt->mod_stmt);
03239             exec_set_found(estate, (SPI_processed != 0));
03240             break;
03241 
03242         case SPI_OK_INSERT:
03243         case SPI_OK_UPDATE:
03244         case SPI_OK_DELETE:
03245         case SPI_OK_INSERT_RETURNING:
03246         case SPI_OK_UPDATE_RETURNING:
03247         case SPI_OK_DELETE_RETURNING:
03248             Assert(stmt->mod_stmt);
03249             exec_set_found(estate, (SPI_processed != 0));
03250             break;
03251 
03252         case SPI_OK_SELINTO:
03253         case SPI_OK_UTILITY:
03254             Assert(!stmt->mod_stmt);
03255             break;
03256 
03257         case SPI_OK_REWRITTEN:
03258             Assert(!stmt->mod_stmt);
03259 
03260             /*
03261              * The command was rewritten into another kind of command. It's
03262              * not clear what FOUND would mean in that case (and SPI doesn't
03263              * return the row count either), so just set it to false.
03264              */
03265             exec_set_found(estate, false);
03266             break;
03267 
03268             /* Some SPI errors deserve specific error messages */
03269         case SPI_ERROR_COPY:
03270             ereport(ERROR,
03271                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
03272                      errmsg("cannot COPY to/from client in PL/pgSQL")));
03273         case SPI_ERROR_TRANSACTION:
03274             ereport(ERROR,
03275                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
03276                      errmsg("cannot begin/end transactions in PL/pgSQL"),
03277             errhint("Use a BEGIN block with an EXCEPTION clause instead.")));
03278 
03279         default:
03280             elog(ERROR, "SPI_execute_plan_with_paramlist failed executing query \"%s\": %s",
03281                  expr->query, SPI_result_code_string(rc));
03282     }
03283 
03284     /* All variants should save result info for GET DIAGNOSTICS */
03285     estate->eval_processed = SPI_processed;
03286     estate->eval_lastoid = SPI_lastoid;
03287 
03288     /* Process INTO if present */
03289     if (stmt->into)
03290     {
03291         SPITupleTable *tuptab = SPI_tuptable;
03292         uint32      n = SPI_processed;
03293         PLpgSQL_rec *rec = NULL;
03294         PLpgSQL_row *row = NULL;
03295 
03296         /* If the statement did not return a tuple table, complain */
03297         if (tuptab == NULL)
03298             ereport(ERROR,
03299                     (errcode(ERRCODE_SYNTAX_ERROR),
03300                 errmsg("INTO used with a command that cannot return data")));
03301 
03302         /* Determine if we assign to a record or a row */
03303         if (stmt->rec != NULL)
03304             rec = (PLpgSQL_rec *) (estate->datums[stmt->rec->dno]);
03305         else if (stmt->row != NULL)
03306             row = (PLpgSQL_row *) (estate->datums[stmt->row->dno]);
03307         else
03308             elog(ERROR, "unsupported target");
03309 
03310         /*
03311          * If SELECT ... INTO specified STRICT, and the query didn't find
03312          * exactly one row, throw an error.  If STRICT was not specified, then
03313          * allow the query to find any number of rows.
03314          */
03315         if (n == 0)
03316         {
03317             if (stmt->strict)
03318                 ereport(ERROR,
03319                         (errcode(ERRCODE_NO_DATA_FOUND),
03320                          errmsg("query returned no rows")));
03321             /* set the target to NULL(s) */
03322             exec_move_row(estate, rec, row, NULL, tuptab->tupdesc);
03323         }
03324         else
03325         {
03326             if (n > 1 && (stmt->strict || stmt->mod_stmt))
03327                 ereport(ERROR,
03328                         (errcode(ERRCODE_TOO_MANY_ROWS),
03329                          errmsg("query returned more than one row")));
03330             /* Put the first result row into the target */
03331             exec_move_row(estate, rec, row, tuptab->vals[0], tuptab->tupdesc);
03332         }
03333 
03334         /* Clean up */
03335         exec_eval_cleanup(estate);
03336         SPI_freetuptable(SPI_tuptable);
03337     }
03338     else
03339     {
03340         /* If the statement returned a tuple table, complain */
03341         if (SPI_tuptable != NULL)
03342             ereport(ERROR,
03343                     (errcode(ERRCODE_SYNTAX_ERROR),
03344                      errmsg("query has no destination for result data"),
03345                      (rc == SPI_OK_SELECT) ? errhint("If you want to discard the results of a SELECT, use PERFORM instead.") : 0));
03346     }
03347 
03348     if (paramLI)
03349         pfree(paramLI);
03350 
03351     return PLPGSQL_RC_OK;
03352 }
03353 
03354 
03355 /* ----------
03356  * exec_stmt_dynexecute         Execute a dynamic SQL query
03357  *                  (possibly with INTO).
03358  * ----------
03359  */
03360 static int
03361 exec_stmt_dynexecute(PLpgSQL_execstate *estate,
03362                      PLpgSQL_stmt_dynexecute *stmt)
03363 {
03364     Datum       query;
03365     bool        isnull = false;
03366     Oid         restype;
03367     char       *querystr;
03368     int         exec_res;
03369 
03370     /*
03371      * First we evaluate the string expression after the EXECUTE keyword. Its
03372      * result is the querystring we have to execute.
03373      */
03374     query = exec_eval_expr(estate, stmt->query, &isnull, &restype);
03375     if (isnull)
03376         ereport(ERROR,
03377                 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
03378                  errmsg("query string argument of EXECUTE is null")));
03379 
03380     /* Get the C-String representation */
03381     querystr = convert_value_to_string(estate, query, restype);
03382 
03383     /* copy it out of the temporary context before we clean up */
03384     querystr = pstrdup(querystr);
03385 
03386     exec_eval_cleanup(estate);
03387 
03388     /*
03389      * Execute the query without preparing a saved plan.
03390      */
03391     if (stmt->params)
03392     {
03393         PreparedParamsData *ppd;
03394 
03395         ppd = exec_eval_using_params(estate, stmt->params);
03396         exec_res = SPI_execute_with_args(querystr,
03397                                          ppd->nargs, ppd->types,
03398                                          ppd->values, ppd->nulls,
03399                                          estate->readonly_func, 0);
03400         free_params_data(ppd);
03401     }
03402     else
03403         exec_res = SPI_execute(querystr, estate->readonly_func, 0);
03404 
03405     switch (exec_res)
03406     {
03407         case SPI_OK_SELECT:
03408         case SPI_OK_INSERT:
03409         case SPI_OK_UPDATE:
03410         case SPI_OK_DELETE:
03411         case SPI_OK_INSERT_RETURNING:
03412         case SPI_OK_UPDATE_RETURNING:
03413         case SPI_OK_DELETE_RETURNING:
03414         case SPI_OK_UTILITY:
03415         case SPI_OK_REWRITTEN:
03416             break;
03417 
03418         case 0:
03419 
03420             /*
03421              * Also allow a zero return, which implies the querystring
03422              * contained no commands.
03423              */
03424             break;
03425 
03426         case SPI_OK_SELINTO:
03427 
03428             /*
03429              * We want to disallow SELECT INTO for now, because its behavior
03430              * is not consistent with SELECT INTO in a normal plpgsql context.
03431              * (We need to reimplement EXECUTE to parse the string as a
03432              * plpgsql command, not just feed it to SPI_execute.)  This is not
03433              * a functional limitation because CREATE TABLE AS is allowed.
03434              */
03435             ereport(ERROR,
03436                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
03437                      errmsg("EXECUTE of SELECT ... INTO is not implemented"),
03438                      errhint("You might want to use EXECUTE ... INTO or EXECUTE CREATE TABLE ... AS instead.")));
03439             break;
03440 
03441             /* Some SPI errors deserve specific error messages */
03442         case SPI_ERROR_COPY:
03443             ereport(ERROR,
03444                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
03445                      errmsg("cannot COPY to/from client in PL/pgSQL")));
03446         case SPI_ERROR_TRANSACTION:
03447             ereport(ERROR,
03448                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
03449                      errmsg("cannot begin/end transactions in PL/pgSQL"),
03450             errhint("Use a BEGIN block with an EXCEPTION clause instead.")));
03451 
03452         default:
03453             elog(ERROR, "SPI_execute failed executing query \"%s\": %s",
03454                  querystr, SPI_result_code_string(exec_res));
03455             break;
03456     }
03457 
03458     /* Save result info for GET DIAGNOSTICS */
03459     estate->eval_processed = SPI_processed;
03460     estate->eval_lastoid = SPI_lastoid;
03461 
03462     /* Process INTO if present */
03463     if (stmt->into)
03464     {
03465         SPITupleTable *tuptab = SPI_tuptable;
03466         uint32      n = SPI_processed;
03467         PLpgSQL_rec *rec = NULL;
03468         PLpgSQL_row *row = NULL;
03469 
03470         /* If the statement did not return a tuple table, complain */
03471         if (tuptab == NULL)
03472             ereport(ERROR,
03473                     (errcode(ERRCODE_SYNTAX_ERROR),
03474                 errmsg("INTO used with a command that cannot return data")));
03475 
03476         /* Determine if we assign to a record or a row */
03477         if (stmt->rec != NULL)
03478             rec = (PLpgSQL_rec *) (estate->datums[stmt->rec->dno]);
03479         else if (stmt->row != NULL)
03480             row = (PLpgSQL_row *) (estate->datums[stmt->row->dno]);
03481         else
03482             elog(ERROR, "unsupported target");
03483 
03484         /*
03485          * If SELECT ... INTO specified STRICT, and the query didn't find
03486          * exactly one row, throw an error.  If STRICT was not specified, then
03487          * allow the query to find any number of rows.
03488          */
03489         if (n == 0)
03490         {
03491             if (stmt->strict)
03492                 ereport(ERROR,
03493                         (errcode(ERRCODE_NO_DATA_FOUND),
03494                          errmsg("query returned no rows")));
03495             /* set the target to NULL(s) */
03496             exec_move_row(estate, rec, row, NULL, tuptab->tupdesc);
03497         }
03498         else
03499         {
03500             if (n > 1 && stmt->strict)
03501                 ereport(ERROR,
03502                         (errcode(ERRCODE_TOO_MANY_ROWS),
03503                          errmsg("query returned more than one row")));
03504             /* Put the first result row into the target */
03505             exec_move_row(estate, rec, row, tuptab->vals[0], tuptab->tupdesc);
03506         }
03507         /* clean up after exec_move_row() */
03508         exec_eval_cleanup(estate);
03509     }
03510     else
03511     {
03512         /*
03513          * It might be a good idea to raise an error if the query returned
03514          * tuples that are being ignored, but historically we have not done
03515          * that.
03516          */
03517     }
03518 
03519     /* Release any result from SPI_execute, as well as the querystring */
03520     SPI_freetuptable(SPI_tuptable);
03521     pfree(querystr);
03522 
03523     return PLPGSQL_RC_OK;
03524 }
03525 
03526 
03527 /* ----------
03528  * exec_stmt_dynfors            Execute a dynamic query, assign each
03529  *                  tuple to a record or row and
03530  *                  execute a group of statements
03531  *                  for it.
03532  * ----------
03533  */
03534 static int
03535 exec_stmt_dynfors(PLpgSQL_execstate *estate, PLpgSQL_stmt_dynfors *stmt)
03536 {
03537     Portal      portal;
03538     int         rc;
03539 
03540     portal = exec_dynquery_with_params(estate, stmt->query, stmt->params,
03541                                        NULL, 0);
03542 
03543     /*
03544      * Execute the loop
03545      */
03546     rc = exec_for_query(estate, (PLpgSQL_stmt_forq *) stmt, portal, true);
03547 
03548     /*
03549      * Close the implicit cursor
03550      */
03551     SPI_cursor_close(portal);
03552 
03553     return rc;
03554 }
03555 
03556 
03557 /* ----------
03558  * exec_stmt_open           Execute an OPEN cursor statement
03559  * ----------
03560  */
03561 static int
03562 exec_stmt_open(PLpgSQL_execstate *estate, PLpgSQL_stmt_open *stmt)
03563 {
03564     PLpgSQL_var *curvar;
03565     char       *curname = NULL;
03566     PLpgSQL_expr *query;
03567     Portal      portal;
03568     ParamListInfo paramLI;
03569 
03570     /* ----------
03571      * Get the cursor variable and if it has an assigned name, check
03572      * that it's not in use currently.
03573      * ----------
03574      */
03575     curvar = (PLpgSQL_var *) (estate->datums[stmt->curvar]);
03576     if (!curvar->isnull)
03577     {
03578         curname = TextDatumGetCString(curvar->value);
03579         if (SPI_cursor_find(curname) != NULL)
03580             ereport(ERROR,
03581                     (errcode(ERRCODE_DUPLICATE_CURSOR),
03582                      errmsg("cursor \"%s\" already in use", curname)));
03583     }
03584 
03585     /* ----------
03586      * Process the OPEN according to it's type.
03587      * ----------
03588      */
03589     if (stmt->query != NULL)
03590     {
03591         /* ----------
03592          * This is an OPEN refcursor FOR SELECT ...
03593          *
03594          * We just make sure the query is planned. The real work is
03595          * done downstairs.
03596          * ----------
03597          */
03598         query = stmt->query;
03599         if (query->plan == NULL)
03600             exec_prepare_plan(estate, query, stmt->cursor_options);
03601     }
03602     else if (stmt->dynquery != NULL)
03603     {
03604         /* ----------
03605          * This is an OPEN refcursor FOR EXECUTE ...
03606          * ----------
03607          */
03608         portal = exec_dynquery_with_params(estate,
03609                                            stmt->dynquery,
03610                                            stmt->params,
03611                                            curname,
03612                                            stmt->cursor_options);
03613 
03614         /*
03615          * If cursor variable was NULL, store the generated portal name in it
03616          */
03617         if (curname == NULL)
03618             assign_text_var(curvar, portal->name);
03619 
03620         return PLPGSQL_RC_OK;
03621     }
03622     else
03623     {
03624         /* ----------
03625          * This is an OPEN cursor
03626          *
03627          * Note: parser should already have checked that statement supplies
03628          * args iff cursor needs them, but we check again to be safe.
03629          * ----------
03630          */
03631         if (stmt->argquery != NULL)
03632         {
03633             /* ----------
03634              * OPEN CURSOR with args.  We fake a SELECT ... INTO ...
03635              * statement to evaluate the args and put 'em into the
03636              * internal row.
03637              * ----------
03638              */
03639             PLpgSQL_stmt_execsql set_args;
03640 
03641             if (curvar->cursor_explicit_argrow < 0)
03642                 ereport(ERROR,
03643                         (errcode(ERRCODE_SYNTAX_ERROR),
03644                     errmsg("arguments given for cursor without arguments")));
03645 
03646             memset(&set_args, 0, sizeof(set_args));
03647             set_args.cmd_type = PLPGSQL_STMT_EXECSQL;
03648             set_args.lineno = stmt->lineno;
03649             set_args.sqlstmt = stmt->argquery;
03650             set_args.into = true;
03651             /* XXX historically this has not been STRICT */
03652             set_args.row = (PLpgSQL_row *)
03653                 (estate->datums[curvar->cursor_explicit_argrow]);
03654 
03655             if (exec_stmt_execsql(estate, &set_args) != PLPGSQL_RC_OK)
03656                 elog(ERROR, "open cursor failed during argument processing");
03657         }
03658         else
03659         {
03660             if (curvar->cursor_explicit_argrow >= 0)
03661                 ereport(ERROR,
03662                         (errcode(ERRCODE_SYNTAX_ERROR),
03663                          errmsg("arguments required for cursor")));
03664         }
03665 
03666         query = curvar->cursor_explicit_expr;
03667         if (query->plan == NULL)
03668             exec_prepare_plan(estate, query, curvar->cursor_options);
03669     }
03670 
03671     /*
03672      * Set up ParamListInfo (hook function and possibly data values)
03673      */
03674     paramLI = setup_param_list(estate, query);
03675 
03676     /*
03677      * Open the cursor
03678      */
03679     portal = SPI_cursor_open_with_paramlist(curname, query->plan,
03680                                             paramLI,
03681                                             estate->readonly_func);
03682     if (portal == NULL)
03683         elog(ERROR, "could not open cursor: %s",
03684              SPI_result_code_string(SPI_result));
03685 
03686     /*
03687      * If cursor variable was NULL, store the generated portal name in it
03688      */
03689     if (curname == NULL)
03690         assign_text_var(curvar, portal->name);
03691 
03692     if (curname)
03693         pfree(curname);
03694     if (paramLI)
03695         pfree(paramLI);
03696 
03697     return PLPGSQL_RC_OK;
03698 }
03699 
03700 
03701 /* ----------
03702  * exec_stmt_fetch          Fetch from a cursor into a target, or just
03703  *                          move the current position of the cursor
03704  * ----------
03705  */
03706 static int
03707 exec_stmt_fetch(PLpgSQL_execstate *estate, PLpgSQL_stmt_fetch *stmt)
03708 {
03709     PLpgSQL_var *curvar = NULL;
03710     PLpgSQL_rec *rec = NULL;
03711     PLpgSQL_row *row = NULL;
03712     long        how_many = stmt->how_many;
03713     SPITupleTable *tuptab;
03714     Portal      portal;
03715     char       *curname;
03716     uint32      n;
03717 
03718     /* ----------
03719      * Get the portal of the cursor by name
03720      * ----------
03721      */
03722     curvar = (PLpgSQL_var *) (estate->datums[stmt->curvar]);
03723     if (curvar->isnull)
03724         ereport(ERROR,
03725                 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
03726                  errmsg("cursor variable \"%s\" is null", curvar->refname)));
03727     curname = TextDatumGetCString(curvar->value);
03728 
03729     portal = SPI_cursor_find(curname);
03730     if (portal == NULL)
03731         ereport(ERROR,
03732                 (errcode(ERRCODE_UNDEFINED_CURSOR),
03733                  errmsg("cursor \"%s\" does not exist", curname)));
03734     pfree(curname);
03735 
03736     /* Calculate position for FETCH_RELATIVE or FETCH_ABSOLUTE */
03737     if (stmt->expr)
03738     {
03739         bool        isnull;
03740 
03741         /* XXX should be doing this in LONG not INT width */
03742         how_many = exec_eval_integer(estate, stmt->expr, &isnull);
03743 
03744         if (isnull)
03745             ereport(ERROR,
03746                     (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
03747                      errmsg("relative or absolute cursor position is null")));
03748 
03749         exec_eval_cleanup(estate);
03750     }
03751 
03752     if (!stmt->is_move)
03753     {
03754         /* ----------
03755          * Determine if we fetch into a record or a row
03756          * ----------
03757          */
03758         if (stmt->rec != NULL)
03759             rec = (PLpgSQL_rec *) (estate->datums[stmt->rec->dno]);
03760         else if (stmt->row != NULL)
03761             row = (PLpgSQL_row *) (estate->datums[stmt->row->dno]);
03762         else
03763             elog(ERROR, "unsupported target");
03764 
03765         /* ----------
03766          * Fetch 1 tuple from the cursor
03767          * ----------
03768          */
03769         SPI_scroll_cursor_fetch(portal, stmt->direction, how_many);
03770         tuptab = SPI_tuptable;
03771         n = SPI_processed;
03772 
03773         /* ----------
03774          * Set the target appropriately.
03775          * ----------
03776          */
03777         if (n == 0)
03778             exec_move_row(estate, rec, row, NULL, tuptab->tupdesc);
03779         else
03780             exec_move_row(estate, rec, row, tuptab->vals[0], tuptab->tupdesc);
03781 
03782         exec_eval_cleanup(estate);
03783         SPI_freetuptable(tuptab);
03784     }
03785     else
03786     {
03787         /* Move the cursor */
03788         SPI_scroll_cursor_move(portal, stmt->direction, how_many);
03789         n = SPI_processed;
03790     }
03791 
03792     /* Set the ROW_COUNT and the global FOUND variable appropriately. */
03793     estate->eval_processed = n;
03794     exec_set_found(estate, n != 0);
03795 
03796     return PLPGSQL_RC_OK;
03797 }
03798 
03799 /* ----------
03800  * exec_stmt_close          Close a cursor
03801  * ----------
03802  */
03803 static int
03804 exec_stmt_close(PLpgSQL_execstate *estate, PLpgSQL_stmt_close *stmt)
03805 {
03806     PLpgSQL_var *curvar = NULL;
03807     Portal      portal;
03808     char       *curname;
03809 
03810     /* ----------
03811      * Get the portal of the cursor by name
03812      * ----------
03813      */
03814     curvar = (PLpgSQL_var *) (estate->datums[stmt->curvar]);
03815     if (curvar->isnull)
03816         ereport(ERROR,
03817                 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
03818                  errmsg("cursor variable \"%s\" is null", curvar->refname)));
03819     curname = TextDatumGetCString(curvar->value);
03820 
03821     portal = SPI_cursor_find(curname);
03822     if (portal == NULL)
03823         ereport(ERROR,
03824                 (errcode(ERRCODE_UNDEFINED_CURSOR),
03825                  errmsg("cursor \"%s\" does not exist", curname)));
03826     pfree(curname);
03827 
03828     /* ----------
03829      * And close it.
03830      * ----------
03831      */
03832     SPI_cursor_close(portal);
03833 
03834     return PLPGSQL_RC_OK;
03835 }
03836 
03837 
03838 /* ----------
03839  * exec_assign_expr         Put an expression's result into a variable.
03840  * ----------
03841  */
03842 static void
03843 exec_assign_expr(PLpgSQL_execstate *estate, PLpgSQL_datum *target,
03844                  PLpgSQL_expr *expr)
03845 {
03846     Datum       value;
03847     Oid         valtype;
03848     bool        isnull = false;
03849 
03850     value = exec_eval_expr(estate, expr, &isnull, &valtype);
03851     exec_assign_value(estate, target, value, valtype, &isnull);
03852     exec_eval_cleanup(estate);
03853 }
03854 
03855 
03856 /* ----------
03857  * exec_assign_c_string     Put a C string into a text variable.
03858  *
03859  * We take a NULL pointer as signifying empty string, not SQL null.
03860  * ----------
03861  */
03862 static void
03863 exec_assign_c_string(PLpgSQL_execstate *estate, PLpgSQL_datum *target,
03864                      const char *str)
03865 {
03866     text       *value;
03867     bool        isnull = false;
03868 
03869     if (str != NULL)
03870         value = cstring_to_text(str);
03871     else
03872         value = cstring_to_text("");
03873     exec_assign_value(estate, target, PointerGetDatum(value),
03874                       TEXTOID, &isnull);
03875     pfree(value);
03876 }
03877 
03878 
03879 /* ----------
03880  * exec_assign_value            Put a value into a target field
03881  *
03882  * Note: in some code paths, this will leak memory in the eval_econtext;
03883  * we assume that will be cleaned up later by exec_eval_cleanup.  We cannot
03884  * call exec_eval_cleanup here for fear of destroying the input Datum value.
03885  * ----------
03886  */
03887 static void
03888 exec_assign_value(PLpgSQL_execstate *estate,
03889                   PLpgSQL_datum *target,
03890                   Datum value, Oid valtype, bool *isNull)
03891 {
03892     switch (target->dtype)
03893     {
03894         case PLPGSQL_DTYPE_VAR:
03895             {
03896                 /*
03897                  * Target is a variable
03898                  */
03899                 PLpgSQL_var *var = (PLpgSQL_var *) target;
03900                 Datum       newvalue;
03901 
03902                 newvalue = exec_cast_value(estate,
03903                                            value,
03904                                            valtype,
03905                                            var->datatype->typoid,
03906                                            &(var->datatype->typinput),
03907                                            var->datatype->typioparam,
03908                                            var->datatype->atttypmod,
03909                                            *isNull);
03910 
03911                 if (*isNull && var->notnull)
03912                     ereport(ERROR,
03913                             (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
03914                              errmsg("null value cannot be assigned to variable \"%s\" declared NOT NULL",
03915                                     var->refname)));
03916 
03917                 /*
03918                  * If type is by-reference, copy the new value (which is
03919                  * probably in the eval_econtext) into the procedure's memory
03920                  * context.
03921                  */
03922                 if (!var->datatype->typbyval && !*isNull)
03923                     newvalue = datumCopy(newvalue,
03924                                          false,
03925                                          var->datatype->typlen);
03926 
03927                 /*
03928                  * Now free the old value.  (We can't do this any earlier
03929                  * because of the possibility that we are assigning the var's
03930                  * old value to it, eg "foo := foo".  We could optimize out
03931                  * the assignment altogether in such cases, but it's too
03932                  * infrequent to be worth testing for.)
03933                  */
03934                 free_var(var);
03935 
03936                 var->value = newvalue;
03937                 var->isnull = *isNull;
03938                 if (!var->datatype->typbyval && !*isNull)
03939                     var->freeval = true;
03940                 break;
03941             }
03942 
03943         case PLPGSQL_DTYPE_ROW:
03944             {
03945                 /*
03946                  * Target is a row variable
03947                  */
03948                 PLpgSQL_row *row = (PLpgSQL_row *) target;
03949 
03950                 if (*isNull)
03951                 {
03952                     /* If source is null, just assign nulls to the row */
03953                     exec_move_row(estate, NULL, row, NULL, NULL);
03954                 }
03955                 else
03956                 {
03957                     /* Source must be of RECORD or composite type */
03958                     if (!type_is_rowtype(valtype))
03959                         ereport(ERROR,
03960                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
03961                                  errmsg("cannot assign non-composite value to a row variable")));
03962                     exec_move_row_from_datum(estate, NULL, row, value);
03963                 }
03964                 break;
03965             }
03966 
03967         case PLPGSQL_DTYPE_REC:
03968             {
03969                 /*
03970                  * Target is a record variable
03971                  */
03972                 PLpgSQL_rec *rec = (PLpgSQL_rec *) target;
03973 
03974                 if (*isNull)
03975                 {
03976                     /* If source is null, just assign nulls to the record */
03977                     exec_move_row(estate, rec, NULL, NULL, NULL);
03978                 }
03979                 else
03980                 {
03981                     /* Source must be of RECORD or composite type */
03982                     if (!type_is_rowtype(valtype))
03983                         ereport(ERROR,
03984                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
03985                                  errmsg("cannot assign non-composite value to a record variable")));
03986                     exec_move_row_from_datum(estate, rec, NULL, value);
03987                 }
03988                 break;
03989             }
03990 
03991         case PLPGSQL_DTYPE_RECFIELD:
03992             {
03993                 /*
03994                  * Target is a field of a record
03995                  */
03996                 PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) target;
03997                 PLpgSQL_rec *rec;
03998                 int         fno;
03999                 HeapTuple   newtup;
04000                 int         natts;
04001                 Datum      *values;
04002                 bool       *nulls;
04003                 bool       *replaces;
04004                 bool        attisnull;
04005                 Oid         atttype;
04006                 int32       atttypmod;
04007 
04008                 rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]);
04009 
04010                 /*
04011                  * Check that there is already a tuple in the record. We need
04012                  * that because records don't have any predefined field
04013                  * structure.
04014                  */
04015                 if (!HeapTupleIsValid(rec->tup))
04016                     ereport(ERROR,
04017                           (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
04018                            errmsg("record \"%s\" is not assigned yet",
04019                                   rec->refname),
04020                            errdetail("The tuple structure of a not-yet-assigned record is indeterminate.")));
04021 
04022                 /*
04023                  * Get the number of the records field to change and the
04024                  * number of attributes in the tuple.  Note: disallow system
04025                  * column names because the code below won't cope.
04026                  */
04027                 fno = SPI_fnumber(rec->tupdesc, recfield->fieldname);
04028                 if (fno <= 0)
04029                     ereport(ERROR,
04030                             (errcode(ERRCODE_UNDEFINED_COLUMN),
04031                              errmsg("record \"%s\" has no field \"%s\"",
04032                                     rec->refname, recfield->fieldname)));
04033                 fno--;
04034                 natts = rec->tupdesc->natts;
04035 
04036                 /*
04037                  * Set up values/control arrays for heap_modify_tuple. For all
04038                  * the attributes except the one we want to replace, use the
04039                  * value that's in the old tuple.
04040                  */
04041                 values = palloc(sizeof(Datum) * natts);
04042                 nulls = palloc(sizeof(bool) * natts);
04043                 replaces = palloc(sizeof(bool) * natts);
04044 
04045                 memset(replaces, false, sizeof(bool) * natts);
04046                 replaces[fno] = true;
04047 
04048                 /*
04049                  * Now insert the new value, being careful to cast it to the
04050                  * right type.
04051                  */
04052                 atttype = SPI_gettypeid(rec->tupdesc, fno + 1);
04053                 atttypmod = rec->tupdesc->attrs[fno]->atttypmod;
04054                 attisnull = *isNull;
04055                 values[fno] = exec_simple_cast_value(estate,
04056                                                      value,
04057                                                      valtype,
04058                                                      atttype,
04059                                                      atttypmod,
04060                                                      attisnull);
04061                 nulls[fno] = attisnull;
04062 
04063                 /*
04064                  * Now call heap_modify_tuple() to create a new tuple that
04065                  * replaces the old one in the record.
04066                  */
04067                 newtup = heap_modify_tuple(rec->tup, rec->tupdesc,
04068                                            values, nulls, replaces);
04069 
04070                 if (rec->freetup)
04071                     heap_freetuple(rec->tup);
04072 
04073                 rec->tup = newtup;
04074                 rec->freetup = true;
04075 
04076                 pfree(values);
04077                 pfree(nulls);
04078                 pfree(replaces);
04079 
04080                 break;
04081             }
04082 
04083         case PLPGSQL_DTYPE_ARRAYELEM:
04084             {
04085                 /*
04086                  * Target is an element of an array
04087                  */
04088                 PLpgSQL_arrayelem *arrayelem;
04089                 int         nsubscripts;
04090                 int         i;
04091                 PLpgSQL_expr *subscripts[MAXDIM];
04092                 int         subscriptvals[MAXDIM];
04093                 Datum       oldarraydatum,
04094                             coerced_value;
04095                 bool        oldarrayisnull;
04096                 Oid         parenttypoid;
04097                 int32       parenttypmod;
04098                 ArrayType  *oldarrayval;
04099                 ArrayType  *newarrayval;
04100                 SPITupleTable *save_eval_tuptable;
04101                 MemoryContext oldcontext;
04102 
04103                 /*
04104                  * We need to do subscript evaluation, which might require
04105                  * evaluating general expressions; and the caller might have
04106                  * done that too in order to prepare the input Datum.  We have
04107                  * to save and restore the caller's SPI_execute result, if
04108                  * any.
04109                  */
04110                 save_eval_tuptable = estate->eval_tuptable;
04111                 estate->eval_tuptable = NULL;
04112 
04113                 /*
04114                  * To handle constructs like x[1][2] := something, we have to
04115                  * be prepared to deal with a chain of arrayelem datums. Chase
04116                  * back to find the base array datum, and save the subscript
04117                  * expressions as we go.  (We are scanning right to left here,
04118                  * but want to evaluate the subscripts left-to-right to
04119                  * minimize surprises.)  Note that arrayelem is left pointing
04120                  * to the leftmost arrayelem datum, where we will cache the
04121                  * array element type data.
04122                  */
04123                 nsubscripts = 0;
04124                 do
04125                 {
04126                     arrayelem = (PLpgSQL_arrayelem *) target;
04127                     if (nsubscripts >= MAXDIM)
04128                         ereport(ERROR,
04129                                 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
04130                                  errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
04131                                         nsubscripts + 1, MAXDIM)));
04132                     subscripts[nsubscripts++] = arrayelem->subscript;
04133                     target = estate->datums[arrayelem->arrayparentno];
04134                 } while (target->dtype == PLPGSQL_DTYPE_ARRAYELEM);
04135 
04136                 /* Fetch current value of array datum */
04137                 exec_eval_datum(estate, target,
04138                                 &parenttypoid, &parenttypmod,
04139                                 &oldarraydatum, &oldarrayisnull);
04140 
04141                 /* Update cached type data if necessary */
04142                 if (arrayelem->parenttypoid != parenttypoid ||
04143                     arrayelem->parenttypmod != parenttypmod)
04144                 {
04145                     Oid         arraytypoid;
04146                     int32       arraytypmod = parenttypmod;
04147                     int16       arraytyplen;
04148                     Oid         elemtypoid;
04149                     int16       elemtyplen;
04150                     bool        elemtypbyval;
04151                     char        elemtypalign;
04152 
04153                     /* If target is domain over array, reduce to base type */
04154                     arraytypoid = getBaseTypeAndTypmod(parenttypoid,
04155                                                        &arraytypmod);
04156 
04157                     /* ... and identify the element type */
04158                     elemtypoid = get_element_type(arraytypoid);
04159                     if (!OidIsValid(elemtypoid))
04160                         ereport(ERROR,
04161                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
04162                               errmsg("subscripted object is not an array")));
04163 
04164                     /* Collect needed data about the types */
04165                     arraytyplen = get_typlen(arraytypoid);
04166 
04167                     get_typlenbyvalalign(elemtypoid,
04168                                          &elemtyplen,
04169                                          &elemtypbyval,
04170                                          &elemtypalign);
04171 
04172                     /* Now safe to update the cached data */
04173                     arrayelem->parenttypoid = parenttypoid;
04174                     arrayelem->parenttypmod = parenttypmod;
04175                     arrayelem->arraytypoid = arraytypoid;
04176                     arrayelem->arraytypmod = arraytypmod;
04177                     arrayelem->arraytyplen = arraytyplen;
04178                     arrayelem->elemtypoid = elemtypoid;
04179                     arrayelem->elemtyplen = elemtyplen;
04180                     arrayelem->elemtypbyval = elemtypbyval;
04181                     arrayelem->elemtypalign = elemtypalign;
04182                 }
04183 
04184                 /*
04185                  * Evaluate the subscripts, switch into left-to-right order.
04186                  * Like ExecEvalArrayRef(), complain if any subscript is null.
04187                  */
04188                 for (i = 0; i < nsubscripts; i++)
04189                 {
04190                     bool        subisnull;
04191 
04192                     subscriptvals[i] =
04193                         exec_eval_integer(estate,
04194                                           subscripts[nsubscripts - 1 - i],
04195                                           &subisnull);
04196                     if (subisnull)
04197                         ereport(ERROR,
04198                                 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
04199                                  errmsg("array subscript in assignment must not be null")));
04200 
04201                     /*
04202                      * Clean up in case the subscript expression wasn't
04203                      * simple. We can't do exec_eval_cleanup, but we can do
04204                      * this much (which is safe because the integer subscript
04205                      * value is surely pass-by-value), and we must do it in
04206                      * case the next subscript expression isn't simple either.
04207                      */
04208                     if (estate->eval_tuptable != NULL)
04209                         SPI_freetuptable(estate->eval_tuptable);
04210                     estate->eval_tuptable = NULL;
04211                 }
04212 
04213                 /* Now we can restore caller's SPI_execute result if any. */
04214                 Assert(estate->eval_tuptable == NULL);
04215                 estate->eval_tuptable = save_eval_tuptable;
04216 
04217                 /* Coerce source value to match array element type. */
04218                 coerced_value = exec_simple_cast_value(estate,
04219                                                        value,
04220                                                        valtype,
04221                                                        arrayelem->elemtypoid,
04222                                                        arrayelem->arraytypmod,
04223                                                        *isNull);
04224 
04225                 /*
04226                  * If the original array is null, cons up an empty array so
04227                  * that the assignment can proceed; we'll end with a
04228                  * one-element array containing just the assigned-to
04229                  * subscript.  This only works for varlena arrays, though; for
04230                  * fixed-length array types we skip the assignment.  We can't
04231                  * support assignment of a null entry into a fixed-length
04232                  * array, either, so that's a no-op too.  This is all ugly but
04233                  * corresponds to the current behavior of ExecEvalArrayRef().
04234                  */
04235                 if (arrayelem->arraytyplen > 0 &&       /* fixed-length array? */
04236                     (oldarrayisnull || *isNull))
04237                     return;
04238 
04239                 /* oldarrayval and newarrayval should be short-lived */
04240                 oldcontext = MemoryContextSwitchTo(estate->eval_econtext->ecxt_per_tuple_memory);
04241 
04242                 if (oldarrayisnull)
04243                     oldarrayval = construct_empty_array(arrayelem->elemtypoid);
04244                 else
04245                     oldarrayval = (ArrayType *) DatumGetPointer(oldarraydatum);
04246 
04247                 /*
04248                  * Build the modified array value.
04249                  */
04250                 newarrayval = array_set(oldarrayval,
04251                                         nsubscripts,
04252                                         subscriptvals,
04253                                         coerced_value,
04254                                         *isNull,
04255                                         arrayelem->arraytyplen,
04256                                         arrayelem->elemtyplen,
04257                                         arrayelem->elemtypbyval,
04258                                         arrayelem->elemtypalign);
04259 
04260                 MemoryContextSwitchTo(oldcontext);
04261 
04262                 /*
04263                  * Assign the new array to the base variable.  It's never NULL
04264                  * at this point.  Note that if the target is a domain,
04265                  * coercing the base array type back up to the domain will
04266                  * happen within exec_assign_value.
04267                  */
04268                 *isNull = false;
04269                 exec_assign_value(estate, target,
04270                                   PointerGetDatum(newarrayval),
04271                                   arrayelem->arraytypoid, isNull);
04272                 break;
04273             }
04274 
04275         default:
04276             elog(ERROR, "unrecognized dtype: %d", target->dtype);
04277     }
04278 }
04279 
04280 /*
04281  * exec_eval_datum              Get current value of a PLpgSQL_datum
04282  *
04283  * The type oid, typmod, value in Datum format, and null flag are returned.
04284  *
04285  * At present this doesn't handle PLpgSQL_expr or PLpgSQL_arrayelem datums.
04286  *
04287  * NOTE: caller must not modify the returned value, since it points right
04288  * at the stored value in the case of pass-by-reference datatypes.  In some
04289  * cases we have to palloc a return value, and in such cases we put it into
04290  * the estate's short-term memory context.
04291  */
04292 static void
04293 exec_eval_datum(PLpgSQL_execstate *estate,
04294                 PLpgSQL_datum *datum,
04295                 Oid *typeid,
04296                 int32 *typetypmod,
04297                 Datum *value,
04298                 bool *isnull)
04299 {
04300     MemoryContext oldcontext;
04301 
04302     switch (datum->dtype)
04303     {
04304         case PLPGSQL_DTYPE_VAR:
04305             {
04306                 PLpgSQL_var *var = (PLpgSQL_var *) datum;
04307 
04308                 *typeid = var->datatype->typoid;
04309                 *typetypmod = var->datatype->atttypmod;
04310                 *value = var->value;
04311                 *isnull = var->isnull;
04312                 break;
04313             }
04314 
04315         case PLPGSQL_DTYPE_ROW:
04316             {
04317                 PLpgSQL_row *row = (PLpgSQL_row *) datum;
04318                 HeapTuple   tup;
04319 
04320                 if (!row->rowtupdesc)   /* should not happen */
04321                     elog(ERROR, "row variable has no tupdesc");
04322                 /* Make sure we have a valid type/typmod setting */
04323                 BlessTupleDesc(row->rowtupdesc);
04324                 oldcontext = MemoryContextSwitchTo(estate->eval_econtext->ecxt_per_tuple_memory);
04325                 tup = make_tuple_from_row(estate, row, row->rowtupdesc);
04326                 if (tup == NULL)    /* should not happen */
04327                     elog(ERROR, "row not compatible with its own tupdesc");
04328                 MemoryContextSwitchTo(oldcontext);
04329                 *typeid = row->rowtupdesc->tdtypeid;
04330                 *typetypmod = row->rowtupdesc->tdtypmod;
04331                 *value = HeapTupleGetDatum(tup);
04332                 *isnull = false;
04333                 break;
04334             }
04335 
04336         case PLPGSQL_DTYPE_REC:
04337             {
04338                 PLpgSQL_rec *rec = (PLpgSQL_rec *) datum;
04339                 HeapTupleData worktup;
04340 
04341                 if (!HeapTupleIsValid(rec->tup))
04342                     ereport(ERROR,
04343                           (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
04344                            errmsg("record \"%s\" is not assigned yet",
04345                                   rec->refname),
04346                            errdetail("The tuple structure of a not-yet-assigned record is indeterminate.")));
04347                 Assert(rec->tupdesc != NULL);
04348                 /* Make sure we have a valid type/typmod setting */
04349                 BlessTupleDesc(rec->tupdesc);
04350 
04351                 /*
04352                  * In a trigger, the NEW and OLD parameters are likely to be
04353                  * on-disk tuples that don't have the desired Datum fields.
04354                  * Copy the tuple body and insert the right values.
04355                  */
04356                 oldcontext = MemoryContextSwitchTo(estate->eval_econtext->ecxt_per_tuple_memory);
04357                 heap_copytuple_with_tuple(rec->tup, &worktup);
04358                 HeapTupleHeaderSetDatumLength(worktup.t_data, worktup.t_len);
04359                 HeapTupleHeaderSetTypeId(worktup.t_data, rec->tupdesc->tdtypeid);
04360                 HeapTupleHeaderSetTypMod(worktup.t_data, rec->tupdesc->tdtypmod);
04361                 MemoryContextSwitchTo(oldcontext);
04362                 *typeid = rec->tupdesc->tdtypeid;
04363                 *typetypmod = rec->tupdesc->tdtypmod;
04364                 *value = HeapTupleGetDatum(&worktup);
04365                 *isnull = false;
04366                 break;
04367             }
04368 
04369         case PLPGSQL_DTYPE_RECFIELD:
04370             {
04371                 PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) datum;
04372                 PLpgSQL_rec *rec;
04373                 int         fno;
04374 
04375                 rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]);
04376                 if (!HeapTupleIsValid(rec->tup))
04377                     ereport(ERROR,
04378                           (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
04379                            errmsg("record \"%s\" is not assigned yet",
04380                                   rec->refname),
04381                            errdetail("The tuple structure of a not-yet-assigned record is indeterminate.")));
04382                 fno = SPI_fnumber(rec->tupdesc, recfield->fieldname);
04383                 if (fno == SPI_ERROR_NOATTRIBUTE)
04384                     ereport(ERROR,
04385                             (errcode(ERRCODE_UNDEFINED_COLUMN),
04386                              errmsg("record \"%s\" has no field \"%s\"",
04387                                     rec->refname, recfield->fieldname)));
04388                 *typeid = SPI_gettypeid(rec->tupdesc, fno);
04389                 /* XXX there's no SPI_gettypmod, for some reason */
04390                 if (fno > 0)
04391                     *typetypmod = rec->tupdesc->attrs[fno - 1]->atttypmod;
04392                 else
04393                     *typetypmod = -1;
04394                 *value = SPI_getbinval(rec->tup, rec->tupdesc, fno, isnull);
04395                 break;
04396             }
04397 
04398         default:
04399             elog(ERROR, "unrecognized dtype: %d", datum->dtype);
04400     }
04401 }
04402 
04403 /*
04404  * exec_get_datum_type              Get datatype of a PLpgSQL_datum
04405  *
04406  * This is the same logic as in exec_eval_datum, except that it can handle
04407  * some cases where exec_eval_datum has to fail; specifically, we may have
04408  * a tupdesc but no row value for a record variable.  (This currently can
04409  * happen only for a trigger's NEW/OLD records.)
04410  */
04411 Oid
04412 exec_get_datum_type(PLpgSQL_execstate *estate,
04413                     PLpgSQL_datum *datum)
04414 {
04415     Oid         typeid;
04416 
04417     switch (datum->dtype)
04418     {
04419         case PLPGSQL_DTYPE_VAR:
04420             {
04421                 PLpgSQL_var *var = (PLpgSQL_var *) datum;
04422 
04423                 typeid = var->datatype->typoid;
04424                 break;
04425             }
04426 
04427         case PLPGSQL_DTYPE_ROW:
04428             {
04429                 PLpgSQL_row *row = (PLpgSQL_row *) datum;
04430 
04431                 if (!row->rowtupdesc)   /* should not happen */
04432                     elog(ERROR, "row variable has no tupdesc");
04433                 /* Make sure we have a valid type/typmod setting */
04434                 BlessTupleDesc(row->rowtupdesc);
04435                 typeid = row->rowtupdesc->tdtypeid;
04436                 break;
04437             }
04438 
04439         case PLPGSQL_DTYPE_REC:
04440             {
04441                 PLpgSQL_rec *rec = (PLpgSQL_rec *) datum;
04442 
04443                 if (rec->tupdesc == NULL)
04444                     ereport(ERROR,
04445                           (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
04446                            errmsg("record \"%s\" is not assigned yet",
04447                                   rec->refname),
04448                            errdetail("The tuple structure of a not-yet-assigned record is indeterminate.")));
04449                 /* Make sure we have a valid type/typmod setting */
04450                 BlessTupleDesc(rec->tupdesc);
04451                 typeid = rec->tupdesc->tdtypeid;
04452                 break;
04453             }
04454 
04455         case PLPGSQL_DTYPE_RECFIELD:
04456             {
04457                 PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) datum;
04458                 PLpgSQL_rec *rec;
04459                 int         fno;
04460 
04461                 rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]);
04462                 if (rec->tupdesc == NULL)
04463                     ereport(ERROR,
04464                           (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
04465                            errmsg("record \"%s\" is not assigned yet",
04466                                   rec->refname),
04467                            errdetail("The tuple structure of a not-yet-assigned record is indeterminate.")));
04468                 fno = SPI_fnumber(rec->tupdesc, recfield->fieldname);
04469                 if (fno == SPI_ERROR_NOATTRIBUTE)
04470                     ereport(ERROR,
04471                             (errcode(ERRCODE_UNDEFINED_COLUMN),
04472                              errmsg("record \"%s\" has no field \"%s\"",
04473                                     rec->refname, recfield->fieldname)));
04474                 typeid = SPI_gettypeid(rec->tupdesc, fno);
04475                 break;
04476             }
04477 
04478         default:
04479             elog(ERROR, "unrecognized dtype: %d", datum->dtype);
04480             typeid = InvalidOid;    /* keep compiler quiet */
04481             break;
04482     }
04483 
04484     return typeid;
04485 }
04486 
04487 /*
04488  * exec_get_datum_type_info         Get datatype etc of a PLpgSQL_datum
04489  *
04490  * An extended version of exec_get_datum_type, which also retrieves the
04491  * typmod and collation of the datum.
04492  */
04493 void
04494 exec_get_datum_type_info(PLpgSQL_execstate *estate,
04495                          PLpgSQL_datum *datum,
04496                          Oid *typeid, int32 *typmod, Oid *collation)
04497 {
04498     switch (datum->dtype)
04499     {
04500         case PLPGSQL_DTYPE_VAR:
04501             {
04502                 PLpgSQL_var *var = (PLpgSQL_var *) datum;
04503 
04504                 *typeid = var->datatype->typoid;
04505                 *typmod = var->datatype->atttypmod;
04506                 *collation = var->datatype->collation;
04507                 break;
04508             }
04509 
04510         case PLPGSQL_DTYPE_ROW:
04511             {
04512                 PLpgSQL_row *row = (PLpgSQL_row *) datum;
04513 
04514                 if (!row->rowtupdesc)   /* should not happen */
04515                     elog(ERROR, "row variable has no tupdesc");
04516                 /* Make sure we have a valid type/typmod setting */
04517                 BlessTupleDesc(row->rowtupdesc);
04518                 *typeid = row->rowtupdesc->tdtypeid;
04519                 /* do NOT return the mutable typmod of a RECORD variable */
04520                 *typmod = -1;
04521                 /* composite types are never collatable */
04522                 *collation = InvalidOid;
04523                 break;
04524             }
04525 
04526         case PLPGSQL_DTYPE_REC:
04527             {
04528                 PLpgSQL_rec *rec = (PLpgSQL_rec *) datum;
04529 
04530                 if (rec->tupdesc == NULL)
04531                     ereport(ERROR,
04532                           (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
04533                            errmsg("record \"%s\" is not assigned yet",
04534                                   rec->refname),
04535                            errdetail("The tuple structure of a not-yet-assigned record is indeterminate.")));
04536                 /* Make sure we have a valid type/typmod setting */
04537                 BlessTupleDesc(rec->tupdesc);
04538                 *typeid = rec->tupdesc->tdtypeid;
04539                 /* do NOT return the mutable typmod of a RECORD variable */
04540                 *typmod = -1;
04541                 /* composite types are never collatable */
04542                 *collation = InvalidOid;
04543                 break;
04544             }
04545 
04546         case PLPGSQL_DTYPE_RECFIELD:
04547             {
04548                 PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) datum;
04549                 PLpgSQL_rec *rec;
04550                 int         fno;
04551 
04552                 rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]);
04553                 if (rec->tupdesc == NULL)
04554                     ereport(ERROR,
04555                           (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
04556                            errmsg("record \"%s\" is not assigned yet",
04557                                   rec->refname),
04558                            errdetail("The tuple structure of a not-yet-assigned record is indeterminate.")));
04559                 fno = SPI_fnumber(rec->tupdesc, recfield->fieldname);
04560                 if (fno == SPI_ERROR_NOATTRIBUTE)
04561                     ereport(ERROR,
04562                             (errcode(ERRCODE_UNDEFINED_COLUMN),
04563                              errmsg("record \"%s\" has no field \"%s\"",
04564                                     rec->refname, recfield->fieldname)));
04565                 *typeid = SPI_gettypeid(rec->tupdesc, fno);
04566                 /* XXX there's no SPI_gettypmod, for some reason */
04567                 if (fno > 0)
04568                     *typmod = rec->tupdesc->attrs[fno - 1]->atttypmod;
04569                 else
04570                     *typmod = -1;
04571                 /* XXX there's no SPI_getcollation either */
04572                 if (fno > 0)
04573                     *collation = rec->tupdesc->attrs[fno - 1]->attcollation;
04574                 else    /* no system column types have collation */
04575                     *collation = InvalidOid;
04576                 break;
04577             }
04578 
04579         default:
04580             elog(ERROR, "unrecognized dtype: %d", datum->dtype);
04581             *typeid = InvalidOid;       /* keep compiler quiet */
04582             *typmod = -1;
04583             *collation = InvalidOid;
04584             break;
04585     }
04586 }
04587 
04588 /* ----------
04589  * exec_eval_integer        Evaluate an expression, coerce result to int4
04590  *
04591  * Note we do not do exec_eval_cleanup here; the caller must do it at
04592  * some later point.  (We do this because the caller may be holding the
04593  * results of other, pass-by-reference, expression evaluations, such as
04594  * an array value to be subscripted.  Also see notes in exec_eval_simple_expr
04595  * about allocation of the parameter array.)
04596  * ----------
04597  */
04598 static int
04599 exec_eval_integer(PLpgSQL_execstate *estate,
04600                   PLpgSQL_expr *expr,
04601                   bool *isNull)
04602 {
04603     Datum       exprdatum;
04604     Oid         exprtypeid;
04605 
04606     exprdatum = exec_eval_expr(estate, expr, isNull, &exprtypeid);
04607     exprdatum = exec_simple_cast_value(estate, exprdatum, exprtypeid,
04608                                        INT4OID, -1,
04609                                        *isNull);
04610     return DatumGetInt32(exprdatum);
04611 }
04612 
04613 /* ----------
04614  * exec_eval_boolean        Evaluate an expression, coerce result to bool
04615  *
04616  * Note we do not do exec_eval_cleanup here; the caller must do it at
04617  * some later point.
04618  * ----------
04619  */
04620 static bool
04621 exec_eval_boolean(PLpgSQL_execstate *estate,
04622                   PLpgSQL_expr *expr,
04623                   bool *isNull)
04624 {
04625     Datum       exprdatum;
04626     Oid         exprtypeid;
04627 
04628     exprdatum = exec_eval_expr(estate, expr, isNull, &exprtypeid);
04629     exprdatum = exec_simple_cast_value(estate, exprdatum, exprtypeid,
04630                                        BOOLOID, -1,
04631                                        *isNull);
04632     return DatumGetBool(exprdatum);
04633 }
04634 
04635 /* ----------
04636  * exec_eval_expr           Evaluate an expression and return
04637  *                  the result Datum.
04638  *
04639  * NOTE: caller must do exec_eval_cleanup when done with the Datum.
04640  * ----------
04641  */
04642 static Datum
04643 exec_eval_expr(PLpgSQL_execstate *estate,
04644                PLpgSQL_expr *expr,
04645                bool *isNull,
04646                Oid *rettype)
04647 {
04648     Datum       result = 0;
04649     int         rc;
04650 
04651     /*
04652      * If first time through, create a plan for this expression.
04653      */
04654     if (expr->plan == NULL)
04655         exec_prepare_plan(estate, expr, 0);
04656 
04657     /*
04658      * If this is a simple expression, bypass SPI and use the executor
04659      * directly
04660      */
04661     if (exec_eval_simple_expr(estate, expr, &result, isNull, rettype))
04662         return result;
04663 
04664     /*
04665      * Else do it the hard way via exec_run_select
04666      */
04667     rc = exec_run_select(estate, expr, 2, NULL);
04668     if (rc != SPI_OK_SELECT)
04669         ereport(ERROR,
04670                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
04671                  errmsg("query \"%s\" did not return data", expr->query)));
04672 
04673     /*
04674      * Check that the expression returns exactly one column...
04675      */
04676     if (estate->eval_tuptable->tupdesc->natts != 1)
04677         ereport(ERROR,
04678                 (errcode(ERRCODE_SYNTAX_ERROR),
04679                  errmsg_plural("query \"%s\" returned %d column",
04680                                "query \"%s\" returned %d columns",
04681                                estate->eval_tuptable->tupdesc->natts,
04682                                expr->query,
04683                                estate->eval_tuptable->tupdesc->natts)));
04684 
04685     /*
04686      * ... and get the column's datatype.
04687      */
04688     *rettype = SPI_gettypeid(estate->eval_tuptable->tupdesc, 1);
04689 
04690     /*
04691      * If there are no rows selected, the result is a NULL of that type.
04692      */
04693     if (estate->eval_processed == 0)
04694     {
04695         *isNull = true;
04696         return (Datum) 0;
04697     }
04698 
04699     /*
04700      * Check that the expression returned no more than one row.
04701      */
04702     if (estate->eval_processed != 1)
04703         ereport(ERROR,
04704                 (errcode(ERRCODE_CARDINALITY_VIOLATION),
04705                  errmsg("query \"%s\" returned more than one row",
04706                         expr->query)));
04707 
04708     /*
04709      * Return the single result Datum.
04710      */
04711     return SPI_getbinval(estate->eval_tuptable->vals[0],
04712                          estate->eval_tuptable->tupdesc, 1, isNull);
04713 }
04714 
04715 
04716 /* ----------
04717  * exec_run_select          Execute a select query
04718  * ----------
04719  */
04720 static int
04721 exec_run_select(PLpgSQL_execstate *estate,
04722                 PLpgSQL_expr *expr, long maxtuples, Portal *portalP)
04723 {
04724     ParamListInfo paramLI;
04725     int         rc;
04726 
04727     /*
04728      * On the first call for this expression generate the plan
04729      */
04730     if (expr->plan == NULL)
04731         exec_prepare_plan(estate, expr, 0);
04732 
04733     /*
04734      * Set up ParamListInfo (hook function and possibly data values)
04735      */
04736     paramLI = setup_param_list(estate, expr);
04737 
04738     /*
04739      * If a portal was requested, put the query into the portal
04740      */
04741     if (portalP != NULL)
04742     {
04743         *portalP = SPI_cursor_open_with_paramlist(NULL, expr->plan,
04744                                                   paramLI,
04745                                                   estate->readonly_func);
04746         if (*portalP == NULL)
04747             elog(ERROR, "could not open implicit cursor for query \"%s\": %s",
04748                  expr->query, SPI_result_code_string(SPI_result));
04749         if (paramLI)
04750             pfree(paramLI);
04751         return SPI_OK_CURSOR;
04752     }
04753 
04754     /*
04755      * Execute the query
04756      */
04757     rc = SPI_execute_plan_with_paramlist(expr->plan, paramLI,
04758                                          estate->readonly_func, maxtuples);
04759     if (rc != SPI_OK_SELECT)
04760         ereport(ERROR,
04761                 (errcode(ERRCODE_SYNTAX_ERROR),
04762                  errmsg("query \"%s\" is not a SELECT", expr->query)));
04763 
04764     /* Save query results for eventual cleanup */
04765     Assert(estate->eval_tuptable == NULL);
04766     estate->eval_tuptable = SPI_tuptable;
04767     estate->eval_processed = SPI_processed;
04768     estate->eval_lastoid = SPI_lastoid;
04769 
04770     if (paramLI)
04771         pfree(paramLI);
04772 
04773     return rc;
04774 }
04775 
04776 
04777 /*
04778  * exec_for_query --- execute body of FOR loop for each row from a portal
04779  *
04780  * Used by exec_stmt_fors, exec_stmt_forc and exec_stmt_dynfors
04781  */
04782 static int
04783 exec_for_query(PLpgSQL_execstate *estate, PLpgSQL_stmt_forq *stmt,
04784                Portal portal, bool prefetch_ok)
04785 {
04786     PLpgSQL_rec *rec = NULL;
04787     PLpgSQL_row *row = NULL;
04788     SPITupleTable *tuptab;
04789     bool        found = false;
04790     int         rc = PLPGSQL_RC_OK;
04791     int         n;
04792 
04793     /*
04794      * Determine if we assign to a record or a row
04795      */
04796     if (stmt->rec != NULL)
04797         rec = (PLpgSQL_rec *) (estate->datums[stmt->rec->dno]);
04798     else if (stmt->row != NULL)
04799         row = (PLpgSQL_row *) (estate->datums[stmt->row->dno]);
04800     else
04801         elog(ERROR, "unsupported target");
04802 
04803     /*
04804      * Make sure the portal doesn't get closed by the user statements we
04805      * execute.
04806      */
04807     PinPortal(portal);
04808 
04809     /*
04810      * Fetch the initial tuple(s).  If prefetching is allowed then we grab a
04811      * few more rows to avoid multiple trips through executor startup
04812      * overhead.
04813      */
04814     SPI_cursor_fetch(portal, true, prefetch_ok ? 10 : 1);
04815     tuptab = SPI_tuptable;
04816     n = SPI_processed;
04817 
04818     /*
04819      * If the query didn't return any rows, set the target to NULL and fall
04820      * through with found = false.
04821      */
04822     if (n <= 0)
04823     {
04824         exec_move_row(estate, rec, row, NULL, tuptab->tupdesc);
04825         exec_eval_cleanup(estate);
04826     }
04827     else
04828         found = true;           /* processed at least one tuple */
04829 
04830     /*
04831      * Now do the loop
04832      */
04833     while (n > 0)
04834     {
04835         int         i;
04836 
04837         for (i = 0; i < n; i++)
04838         {
04839             /*
04840              * Assign the tuple to the target
04841              */
04842             exec_move_row(estate, rec, row, tuptab->vals[i], tuptab->tupdesc);
04843             exec_eval_cleanup(estate);
04844 
04845             /*
04846              * Execute the statements
04847              */
04848             rc = exec_stmts(estate, stmt->body);
04849 
04850             if (rc != PLPGSQL_RC_OK)
04851             {
04852                 if (rc == PLPGSQL_RC_EXIT)
04853                 {
04854                     if (estate->exitlabel == NULL)
04855                     {
04856                         /* unlabelled exit, so exit the current loop */
04857                         rc = PLPGSQL_RC_OK;
04858                     }
04859                     else if (stmt->label != NULL &&
04860                              strcmp(stmt->label, estate->exitlabel) == 0)
04861                     {
04862                         /* label matches this loop, so exit loop */
04863                         estate->exitlabel = NULL;
04864                         rc = PLPGSQL_RC_OK;
04865                     }
04866 
04867                     /*
04868                      * otherwise, we processed a labelled exit that does not
04869                      * match the current statement's label, if any; return
04870                      * RC_EXIT so that the EXIT continues to recurse upward.
04871                      */
04872                 }
04873                 else if (rc == PLPGSQL_RC_CONTINUE)
04874                 {
04875                     if (estate->exitlabel == NULL)
04876                     {
04877                         /* unlabelled continue, so re-run the current loop */
04878                         rc = PLPGSQL_RC_OK;
04879                         continue;
04880                     }
04881                     else if (stmt->label != NULL &&
04882                              strcmp(stmt->label, estate->exitlabel) == 0)
04883                     {
04884                         /* label matches this loop, so re-run loop */
04885                         estate->exitlabel = NULL;
04886                         rc = PLPGSQL_RC_OK;
04887                         continue;
04888                     }
04889 
04890                     /*
04891                      * otherwise, we process a labelled continue that does not
04892                      * match the current statement's label, if any; return
04893                      * RC_CONTINUE so that the CONTINUE will propagate up the
04894                      * stack.
04895                      */
04896                 }
04897 
04898                 /*
04899                  * We're aborting the loop.  Need a goto to get out of two
04900                  * levels of loop...
04901                  */
04902                 goto loop_exit;
04903             }
04904         }
04905 
04906         SPI_freetuptable(tuptab);
04907 
04908         /*
04909          * Fetch more tuples.  If prefetching is allowed, grab 50 at a time.
04910          */
04911         SPI_cursor_fetch(portal, true, prefetch_ok ? 50 : 1);
04912         tuptab = SPI_tuptable;
04913         n = SPI_processed;
04914     }
04915 
04916 loop_exit:
04917 
04918     /*
04919      * Release last group of tuples (if any)
04920      */
04921     SPI_freetuptable(tuptab);
04922 
04923     UnpinPortal(portal);
04924 
04925     /*
04926      * Set the FOUND variable to indicate the result of executing the loop
04927      * (namely, whether we looped one or more times). This must be set last so
04928      * that it does not interfere with the value of the FOUND variable inside
04929      * the loop processing itself.
04930      */
04931     exec_set_found(estate, found);
04932 
04933     return rc;
04934 }
04935 
04936 
04937 /* ----------
04938  * exec_eval_simple_expr -      Evaluate a simple expression returning
04939  *                              a Datum by directly calling ExecEvalExpr().
04940  *
04941  * If successful, store results into *result, *isNull, *rettype and return
04942  * TRUE.  If the expression cannot be handled by simple evaluation,
04943  * return FALSE.
04944  *
04945  * Because we only store one execution tree for a simple expression, we
04946  * can't handle recursion cases.  So, if we see the tree is already busy
04947  * with an evaluation in the current xact, we just return FALSE and let the
04948  * caller run the expression the hard way.  (Other alternatives such as
04949  * creating a new tree for a recursive call either introduce memory leaks,
04950  * or add enough bookkeeping to be doubtful wins anyway.)  Another case that
04951  * is covered by the expr_simple_in_use test is where a previous execution
04952  * of the tree was aborted by an error: the tree may contain bogus state
04953  * so we dare not re-use it.
04954  *
04955  * It is possible though unlikely for a simple expression to become non-simple
04956  * (consider for example redefining a trivial view).  We must handle that for
04957  * correctness; fortunately it's normally inexpensive to call
04958  * SPI_plan_get_cached_plan for a simple expression.  We do not consider the
04959  * other direction (non-simple expression becoming simple) because we'll still
04960  * give correct results if that happens, and it's unlikely to be worth the
04961  * cycles to check.
04962  *
04963  * Note: if pass-by-reference, the result is in the eval_econtext's
04964  * temporary memory context.  It will be freed when exec_eval_cleanup
04965  * is done.
04966  * ----------
04967  */
04968 static bool
04969 exec_eval_simple_expr(PLpgSQL_execstate *estate,
04970                       PLpgSQL_expr *expr,
04971                       Datum *result,
04972                       bool *isNull,
04973                       Oid *rettype)
04974 {
04975     ExprContext *econtext = estate->eval_econtext;
04976     LocalTransactionId curlxid = MyProc->lxid;
04977     CachedPlan *cplan;
04978     ParamListInfo paramLI;
04979     PLpgSQL_expr *save_cur_expr;
04980     MemoryContext oldcontext;
04981 
04982     /*
04983      * Forget it if expression wasn't simple before.
04984      */
04985     if (expr->expr_simple_expr == NULL)
04986         return false;
04987 
04988     /*
04989      * If expression is in use in current xact, don't touch it.
04990      */
04991     if (expr->expr_simple_in_use && expr->expr_simple_lxid == curlxid)
04992         return false;
04993 
04994     /*
04995      * Revalidate cached plan, so that we will notice if it became stale. (We
04996      * need to hold a refcount while using the plan, anyway.)
04997      */
04998     cplan = SPI_plan_get_cached_plan(expr->plan);
04999 
05000     /*
05001      * We can't get a failure here, because the number of CachedPlanSources in
05002      * the SPI plan can't change from what exec_simple_check_plan saw; it's a
05003      * property of the raw parsetree generated from the query text.
05004      */
05005     Assert(cplan != NULL);
05006 
05007     if (cplan->generation != expr->expr_simple_generation)
05008     {
05009         /* It got replanned ... is it still simple? */
05010         exec_simple_recheck_plan(expr, cplan);
05011         if (expr->expr_simple_expr == NULL)
05012         {
05013             /* Ooops, release refcount and fail */
05014             ReleaseCachedPlan(cplan, true);
05015             return false;
05016         }
05017     }
05018 
05019     /*
05020      * Pass back previously-determined result type.
05021      */
05022     *rettype = expr->expr_simple_type;
05023 
05024     /*
05025      * Prepare the expression for execution, if it's not been done already in
05026      * the current transaction.  (This will be forced to happen if we called
05027      * exec_simple_recheck_plan above.)
05028      */
05029     if (expr->expr_simple_lxid != curlxid)
05030     {
05031         oldcontext = MemoryContextSwitchTo(simple_eval_estate->es_query_cxt);
05032         expr->expr_simple_state = ExecInitExpr(expr->expr_simple_expr, NULL);
05033         expr->expr_simple_in_use = false;
05034         expr->expr_simple_lxid = curlxid;
05035         MemoryContextSwitchTo(oldcontext);
05036     }
05037 
05038     /*
05039      * We have to do some of the things SPI_execute_plan would do, in
05040      * particular advance the snapshot if we are in a non-read-only function.
05041      * Without this, stable functions within the expression would fail to see
05042      * updates made so far by our own function.
05043      */
05044     SPI_push();
05045 
05046     oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
05047     if (!estate->readonly_func)
05048     {
05049         CommandCounterIncrement();
05050         PushActiveSnapshot(GetTransactionSnapshot());
05051     }
05052 
05053     /*
05054      * Create the param list in econtext's temporary memory context. We won't
05055      * need to free it explicitly, since it will go away at the next reset of
05056      * that context.
05057      *
05058      * Just for paranoia's sake, save and restore the prior value of
05059      * estate->cur_expr, which setup_param_list() sets.
05060      */
05061     save_cur_expr = estate->cur_expr;
05062 
05063     paramLI = setup_param_list(estate, expr);
05064     econtext->ecxt_param_list_info = paramLI;
05065 
05066     /*
05067      * Mark expression as busy for the duration of the ExecEvalExpr call.
05068      */
05069     expr->expr_simple_in_use = true;
05070 
05071     /*
05072      * Finally we can call the executor to evaluate the expression
05073      */
05074     *result = ExecEvalExpr(expr->expr_simple_state,
05075                            econtext,
05076                            isNull,
05077                            NULL);
05078 
05079     /* Assorted cleanup */
05080     expr->expr_simple_in_use = false;
05081 
05082     estate->cur_expr = save_cur_expr;
05083 
05084     if (!estate->readonly_func)
05085         PopActiveSnapshot();
05086 
05087     MemoryContextSwitchTo(oldcontext);
05088 
05089     SPI_pop();
05090 
05091     /*
05092      * Now we can release our refcount on the cached plan.
05093      */
05094     ReleaseCachedPlan(cplan, true);
05095 
05096     /*
05097      * That's it.
05098      */
05099     return true;
05100 }
05101 
05102 
05103 /*
05104  * Create a ParamListInfo to pass to SPI
05105  *
05106  * We fill in the values for any expression parameters that are plain
05107  * PLpgSQL_var datums; these are cheap and safe to evaluate, and by setting
05108  * them with PARAM_FLAG_CONST flags, we allow the planner to use those values
05109  * in custom plans.  However, parameters that are not plain PLpgSQL_vars
05110  * should not be evaluated here, because they could throw errors (for example
05111  * "no such record field") and we do not want that to happen in a part of
05112  * the expression that might never be evaluated at runtime.  To handle those
05113  * parameters, we set up a paramFetch hook for the executor to call when it
05114  * wants a not-presupplied value.
05115  *
05116  * The result is a locally palloc'd array that should be pfree'd after use;
05117  * but note it can be NULL.
05118  */
05119 static ParamListInfo
05120 setup_param_list(PLpgSQL_execstate *estate, PLpgSQL_expr *expr)
05121 {
05122     ParamListInfo paramLI;
05123 
05124     /*
05125      * We must have created the SPIPlan already (hence, query text has been
05126      * parsed/analyzed at least once); else we cannot rely on expr->paramnos.
05127      */
05128     Assert(expr->plan != NULL);
05129 
05130     /*
05131      * Could we re-use these arrays instead of palloc'ing a new one each time?
05132      * However, we'd have to re-fill the array each time anyway, since new
05133      * values might have been assigned to the variables.
05134      */
05135     if (!bms_is_empty(expr->paramnos))
05136     {
05137         Bitmapset  *tmpset;
05138         int         dno;
05139 
05140         paramLI = (ParamListInfo)
05141             palloc0(offsetof(ParamListInfoData, params) +
05142                     estate->ndatums * sizeof(ParamExternData));
05143         paramLI->paramFetch = plpgsql_param_fetch;
05144         paramLI->paramFetchArg = (void *) estate;
05145         paramLI->parserSetup = (ParserSetupHook) plpgsql_parser_setup;
05146         paramLI->parserSetupArg = (void *) expr;
05147         paramLI->numParams = estate->ndatums;
05148 
05149         /* Instantiate values for "safe" parameters of the expression */
05150         tmpset = bms_copy(expr->paramnos);
05151         while ((dno = bms_first_member(tmpset)) >= 0)
05152         {
05153             PLpgSQL_datum *datum = estate->datums[dno];
05154 
05155             if (datum->dtype == PLPGSQL_DTYPE_VAR)
05156             {
05157                 PLpgSQL_var *var = (PLpgSQL_var *) datum;
05158                 ParamExternData *prm = &paramLI->params[dno];
05159 
05160                 prm->value = var->value;
05161                 prm->isnull = var->isnull;
05162                 prm->pflags = PARAM_FLAG_CONST;
05163                 prm->ptype = var->datatype->typoid;
05164             }
05165         }
05166         bms_free(tmpset);
05167 
05168         /*
05169          * Set up link to active expr where the hook functions can find it.
05170          * Callers must save and restore cur_expr if there is any chance that
05171          * they are interrupting an active use of parameters.
05172          */
05173         estate->cur_expr = expr;
05174 
05175         /*
05176          * Also make sure this is set before parser hooks need it.  There is
05177          * no need to save and restore, since the value is always correct once
05178          * set.  (Should be set already, but let's be sure.)
05179          */
05180         expr->func = estate->func;
05181     }
05182     else
05183     {
05184         /*
05185          * Expression requires no parameters.  Be sure we represent this case
05186          * as a NULL ParamListInfo, so that plancache.c knows there is no
05187          * point in a custom plan.
05188          */
05189         paramLI = NULL;
05190     }
05191     return paramLI;
05192 }
05193 
05194 /*
05195  * plpgsql_param_fetch      paramFetch callback for dynamic parameter fetch
05196  */
05197 static void
05198 plpgsql_param_fetch(ParamListInfo params, int paramid)
05199 {
05200     int         dno;
05201     PLpgSQL_execstate *estate;
05202     PLpgSQL_expr *expr;
05203     PLpgSQL_datum *datum;
05204     ParamExternData *prm;
05205     int32       prmtypmod;
05206 
05207     /* paramid's are 1-based, but dnos are 0-based */
05208     dno = paramid - 1;
05209     Assert(dno >= 0 && dno < params->numParams);
05210 
05211     /* fetch back the hook data */
05212     estate = (PLpgSQL_execstate *) params->paramFetchArg;
05213     expr = estate->cur_expr;
05214     Assert(params->numParams == estate->ndatums);
05215 
05216     /*
05217      * Do nothing if asked for a value that's not supposed to be used by this
05218      * SQL expression.  This avoids unwanted evaluations when functions such
05219      * as copyParamList try to materialize all the values.
05220      */
05221     if (!bms_is_member(dno, expr->paramnos))
05222         return;
05223 
05224     /* OK, evaluate the value and store into the appropriate paramlist slot */
05225     datum = estate->datums[dno];
05226     prm = &params->params[dno];
05227     exec_eval_datum(estate, datum,
05228                     &prm->ptype, &prmtypmod,
05229                     &prm->value, &prm->isnull);
05230 }
05231 
05232 
05233 /* ----------
05234  * exec_move_row            Move one tuple's values into a record or row
05235  *
05236  * Since this uses exec_assign_value, caller should eventually call
05237  * exec_eval_cleanup to prevent long-term memory leaks.
05238  * ----------
05239  */
05240 static void
05241 exec_move_row(PLpgSQL_execstate *estate,
05242               PLpgSQL_rec *rec,
05243               PLpgSQL_row *row,
05244               HeapTuple tup, TupleDesc tupdesc)
05245 {
05246     /*
05247      * Record is simple - just copy the tuple and its descriptor into the
05248      * record variable
05249      */
05250     if (rec != NULL)
05251     {
05252         /*
05253          * Copy input first, just in case it is pointing at variable's value
05254          */
05255         if (HeapTupleIsValid(tup))
05256             tup = heap_copytuple(tup);
05257         else if (tupdesc)
05258         {
05259             /* If we have a tupdesc but no data, form an all-nulls tuple */
05260             bool       *nulls;
05261 
05262             nulls = (bool *) palloc(tupdesc->natts * sizeof(bool));
05263             memset(nulls, true, tupdesc->natts * sizeof(bool));
05264 
05265             tup = heap_form_tuple(tupdesc, NULL, nulls);
05266 
05267             pfree(nulls);
05268         }
05269 
05270         if (tupdesc)
05271             tupdesc = CreateTupleDescCopy(tupdesc);
05272 
05273         /* Free the old value ... */
05274         if (rec->freetup)
05275         {
05276             heap_freetuple(rec->tup);
05277             rec->freetup = false;
05278         }
05279         if (rec->freetupdesc)
05280         {
05281             FreeTupleDesc(rec->tupdesc);
05282             rec->freetupdesc = false;
05283         }
05284 
05285         /* ... and install the new */
05286         if (HeapTupleIsValid(tup))
05287         {
05288             rec->tup = tup;
05289             rec->freetup = true;
05290         }
05291         else
05292             rec->tup = NULL;
05293 
05294         if (tupdesc)
05295         {
05296             rec->tupdesc = tupdesc;
05297             rec->freetupdesc = true;
05298         }
05299         else
05300             rec->tupdesc = NULL;
05301 
05302         return;
05303     }
05304 
05305     /*
05306      * Row is a bit more complicated in that we assign the individual
05307      * attributes of the tuple to the variables the row points to.
05308      *
05309      * NOTE: this code used to demand row->nfields ==
05310      * HeapTupleHeaderGetNatts(tup->t_data), but that's wrong.  The tuple
05311      * might have more fields than we expected if it's from an
05312      * inheritance-child table of the current table, or it might have fewer if
05313      * the table has had columns added by ALTER TABLE. Ignore extra columns
05314      * and assume NULL for missing columns, the same as heap_getattr would do.
05315      * We also have to skip over dropped columns in either the source or
05316      * destination.
05317      *
05318      * If we have no tuple data at all, we'll assign NULL to all columns of
05319      * the row variable.
05320      */
05321     if (row != NULL)
05322     {
05323         int         td_natts = tupdesc ? tupdesc->natts : 0;
05324         int         t_natts;
05325         int         fnum;
05326         int         anum;
05327 
05328         if (HeapTupleIsValid(tup))
05329             t_natts = HeapTupleHeaderGetNatts(tup->t_data);
05330         else
05331             t_natts = 0;
05332 
05333         anum = 0;
05334         for (fnum = 0; fnum < row->nfields; fnum++)
05335         {
05336             PLpgSQL_var *var;
05337             Datum       value;
05338             bool        isnull;
05339             Oid         valtype;
05340 
05341             if (row->varnos[fnum] < 0)
05342                 continue;       /* skip dropped column in row struct */
05343 
05344             var = (PLpgSQL_var *) (estate->datums[row->varnos[fnum]]);
05345 
05346             while (anum < td_natts && tupdesc->attrs[anum]->attisdropped)
05347                 anum++;         /* skip dropped column in tuple */
05348 
05349             if (anum < td_natts)
05350             {
05351                 if (anum < t_natts)
05352                     value = SPI_getbinval(tup, tupdesc, anum + 1, &isnull);
05353                 else
05354                 {
05355                     value = (Datum) 0;
05356                     isnull = true;
05357                 }
05358                 valtype = SPI_gettypeid(tupdesc, anum + 1);
05359                 anum++;
05360             }
05361             else
05362             {
05363                 value = (Datum) 0;
05364                 isnull = true;
05365 
05366                 /*
05367                  * InvalidOid is OK because exec_assign_value doesn't care
05368                  * about the type of a source NULL
05369                  */
05370                 valtype = InvalidOid;
05371             }
05372 
05373             exec_assign_value(estate, (PLpgSQL_datum *) var,
05374                               value, valtype, &isnull);
05375         }
05376 
05377         return;
05378     }
05379 
05380     elog(ERROR, "unsupported target");
05381 }
05382 
05383 /* ----------
05384  * make_tuple_from_row      Make a tuple from the values of a row object
05385  *
05386  * A NULL return indicates rowtype mismatch; caller must raise suitable error
05387  * ----------
05388  */
05389 static HeapTuple
05390 make_tuple_from_row(PLpgSQL_execstate *estate,
05391                     PLpgSQL_row *row,
05392                     TupleDesc tupdesc)
05393 {
05394     int         natts = tupdesc->natts;
05395     HeapTuple   tuple;
05396     Datum      *dvalues;
05397     bool       *nulls;
05398     int         i;
05399 
05400     if (natts != row->nfields)
05401         return NULL;
05402 
05403     dvalues = (Datum *) palloc0(natts * sizeof(Datum));
05404     nulls = (bool *) palloc(natts * sizeof(bool));
05405 
05406     for (i = 0; i < natts; i++)
05407     {
05408         Oid         fieldtypeid;
05409         int32       fieldtypmod;
05410 
05411         if (tupdesc->attrs[i]->attisdropped)
05412         {
05413             nulls[i] = true;    /* leave the column as null */
05414             continue;
05415         }
05416         if (row->varnos[i] < 0) /* should not happen */
05417             elog(ERROR, "dropped rowtype entry for non-dropped column");
05418 
05419         exec_eval_datum(estate, estate->datums[row->varnos[i]],
05420                         &fieldtypeid, &fieldtypmod,
05421                         &dvalues[i], &nulls[i]);
05422         if (fieldtypeid != tupdesc->attrs[i]->atttypid)
05423             return NULL;
05424         /* XXX should we insist on typmod match, too? */
05425     }
05426 
05427     tuple = heap_form_tuple(tupdesc, dvalues, nulls);
05428 
05429     pfree(dvalues);
05430     pfree(nulls);
05431 
05432     return tuple;
05433 }
05434 
05435 /* ----------
05436  * get_tuple_from_datum     extract a tuple from a composite Datum
05437  *
05438  * Returns a freshly palloc'd HeapTuple.
05439  *
05440  * Note: it's caller's responsibility to be sure value is of composite type.
05441  * ----------
05442  */
05443 static HeapTuple
05444 get_tuple_from_datum(Datum value)
05445 {
05446     HeapTupleHeader td = DatumGetHeapTupleHeader(value);
05447     HeapTupleData tmptup;
05448 
05449     /* Build a temporary HeapTuple control structure */
05450     tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
05451     ItemPointerSetInvalid(&(tmptup.t_self));
05452     tmptup.t_tableOid = InvalidOid;
05453     tmptup.t_data = td;
05454 
05455     /* Build a copy and return it */
05456     return heap_copytuple(&tmptup);
05457 }
05458 
05459 /* ----------
05460  * get_tupdesc_from_datum   get a tuple descriptor for a composite Datum
05461  *
05462  * Returns a pointer to the TupleDesc of the tuple's rowtype.
05463  * Caller is responsible for calling ReleaseTupleDesc when done with it.
05464  *
05465  * Note: it's caller's responsibility to be sure value is of composite type.
05466  * ----------
05467  */
05468 static TupleDesc
05469 get_tupdesc_from_datum(Datum value)
05470 {
05471     HeapTupleHeader td = DatumGetHeapTupleHeader(value);
05472     Oid         tupType;
05473     int32       tupTypmod;
05474 
05475     /* Extract rowtype info and find a tupdesc */
05476     tupType = HeapTupleHeaderGetTypeId(td);
05477     tupTypmod = HeapTupleHeaderGetTypMod(td);
05478     return lookup_rowtype_tupdesc(tupType, tupTypmod);
05479 }
05480 
05481 /* ----------
05482  * exec_move_row_from_datum     Move a composite Datum into a record or row
05483  *
05484  * This is equivalent to get_tuple_from_datum() followed by exec_move_row(),
05485  * but we avoid constructing an intermediate physical copy of the tuple.
05486  * ----------
05487  */
05488 static void
05489 exec_move_row_from_datum(PLpgSQL_execstate *estate,
05490                          PLpgSQL_rec *rec,
05491                          PLpgSQL_row *row,
05492                          Datum value)
05493 {
05494     HeapTupleHeader td = DatumGetHeapTupleHeader(value);
05495     Oid         tupType;
05496     int32       tupTypmod;
05497     TupleDesc   tupdesc;
05498     HeapTupleData tmptup;
05499 
05500     /* Extract rowtype info and find a tupdesc */
05501     tupType = HeapTupleHeaderGetTypeId(td);
05502     tupTypmod = HeapTupleHeaderGetTypMod(td);
05503     tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
05504 
05505     /* Build a temporary HeapTuple control structure */
05506     tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
05507     ItemPointerSetInvalid(&(tmptup.t_self));
05508     tmptup.t_tableOid = InvalidOid;
05509     tmptup.t_data = td;
05510 
05511     /* Do the move */
05512     exec_move_row(estate, rec, row, &tmptup, tupdesc);
05513 
05514     /* Release tupdesc usage count */
05515     ReleaseTupleDesc(tupdesc);
05516 }
05517 
05518 /* ----------
05519  * convert_value_to_string          Convert a non-null Datum to C string
05520  *
05521  * Note: the result is in the estate's eval_econtext, and will be cleared
05522  * by the next exec_eval_cleanup() call.  The invoked output function might
05523  * leave additional cruft there as well, so just pfree'ing the result string
05524  * would not be enough to avoid memory leaks if we did not do it like this.
05525  * In most usages the Datum being passed in is also in that context (if
05526  * pass-by-reference) and so an exec_eval_cleanup() call is needed anyway.
05527  *
05528  * Note: not caching the conversion function lookup is bad for performance.
05529  * ----------
05530  */
05531 static char *
05532 convert_value_to_string(PLpgSQL_execstate *estate, Datum value, Oid valtype)
05533 {
05534     char       *result;
05535     MemoryContext oldcontext;
05536     Oid         typoutput;
05537     bool        typIsVarlena;
05538 
05539     oldcontext = MemoryContextSwitchTo(estate->eval_econtext->ecxt_per_tuple_memory);
05540     getTypeOutputInfo(valtype, &typoutput, &typIsVarlena);
05541     result = OidOutputFunctionCall(typoutput, value);
05542     MemoryContextSwitchTo(oldcontext);
05543 
05544     return result;
05545 }
05546 
05547 /* ----------
05548  * exec_cast_value          Cast a value if required
05549  *
05550  * Note: the estate's eval_econtext is used for temporary storage, and may
05551  * also contain the result Datum if we have to do a conversion to a pass-
05552  * by-reference data type.  Be sure to do an exec_eval_cleanup() call when
05553  * done with the result.
05554  * ----------
05555  */
05556 static Datum
05557 exec_cast_value(PLpgSQL_execstate *estate,
05558                 Datum value, Oid valtype,
05559                 Oid reqtype,
05560                 FmgrInfo *reqinput,
05561                 Oid reqtypioparam,
05562                 int32 reqtypmod,
05563                 bool isnull)
05564 {
05565     /*
05566      * If the type of the given value isn't what's requested, convert it.
05567      */
05568     if (valtype != reqtype || reqtypmod != -1)
05569     {
05570         MemoryContext oldcontext;
05571 
05572         oldcontext = MemoryContextSwitchTo(estate->eval_econtext->ecxt_per_tuple_memory);
05573         if (!isnull)
05574         {
05575             char       *extval;
05576 
05577             extval = convert_value_to_string(estate, value, valtype);
05578             value = InputFunctionCall(reqinput, extval,
05579                                       reqtypioparam, reqtypmod);
05580         }
05581         else
05582         {
05583             value = InputFunctionCall(reqinput, NULL,
05584                                       reqtypioparam, reqtypmod);
05585         }
05586         MemoryContextSwitchTo(oldcontext);
05587     }
05588 
05589     return value;
05590 }
05591 
05592 /* ----------
05593  * exec_simple_cast_value           Cast a value if required
05594  *
05595  * As above, but need not supply details about target type.  Note that this
05596  * is slower than exec_cast_value with cached type info, and so should be
05597  * avoided in heavily used code paths.
05598  * ----------
05599  */
05600 static Datum
05601 exec_simple_cast_value(PLpgSQL_execstate *estate,
05602                        Datum value, Oid valtype,
05603                        Oid reqtype, int32 reqtypmod,
05604                        bool isnull)
05605 {
05606     if (valtype != reqtype || reqtypmod != -1)
05607     {
05608         Oid         typinput;
05609         Oid         typioparam;
05610         FmgrInfo    finfo_input;
05611 
05612         getTypeInputInfo(reqtype, &typinput, &typioparam);
05613 
05614         fmgr_info(typinput, &finfo_input);
05615 
05616         value = exec_cast_value(estate,
05617                                 value,
05618                                 valtype,
05619                                 reqtype,
05620                                 &finfo_input,
05621                                 typioparam,
05622                                 reqtypmod,
05623                                 isnull);
05624     }
05625 
05626     return value;
05627 }
05628 
05629 
05630 /* ----------
05631  * exec_simple_check_node -     Recursively check if an expression
05632  *                              is made only of simple things we can
05633  *                              hand out directly to ExecEvalExpr()
05634  *                              instead of calling SPI.
05635  * ----------
05636  */
05637 static bool
05638 exec_simple_check_node(Node *node)
05639 {
05640     if (node == NULL)
05641         return TRUE;
05642 
05643     switch (nodeTag(node))
05644     {
05645         case T_Const:
05646             return TRUE;
05647 
05648         case T_Param:
05649             return TRUE;
05650 
05651         case T_ArrayRef:
05652             {
05653                 ArrayRef   *expr = (ArrayRef *) node;
05654 
05655                 if (!exec_simple_check_node((Node *) expr->refupperindexpr))
05656                     return FALSE;
05657                 if (!exec_simple_check_node((Node *) expr->reflowerindexpr))
05658                     return FALSE;
05659                 if (!exec_simple_check_node((Node *) expr->refexpr))
05660                     return FALSE;
05661                 if (!exec_simple_check_node((Node *) expr->refassgnexpr))
05662                     return FALSE;
05663 
05664                 return TRUE;
05665             }
05666 
05667         case T_FuncExpr:
05668             {
05669                 FuncExpr   *expr = (FuncExpr *) node;
05670 
05671                 if (expr->funcretset)
05672                     return FALSE;
05673                 if (!exec_simple_check_node((Node *) expr->args))
05674                     return FALSE;
05675 
05676                 return TRUE;
05677             }
05678 
05679         case T_OpExpr:
05680             {
05681                 OpExpr     *expr = (OpExpr *) node;
05682 
05683                 if (expr->opretset)
05684                     return FALSE;
05685                 if (!exec_simple_check_node((Node *) expr->args))
05686                     return FALSE;
05687 
05688                 return TRUE;
05689             }
05690 
05691         case T_DistinctExpr:
05692             {
05693                 DistinctExpr *expr = (DistinctExpr *) node;
05694 
05695                 if (expr->opretset)
05696                     return FALSE;
05697                 if (!exec_simple_check_node((Node *) expr->args))
05698                     return FALSE;
05699 
05700                 return TRUE;
05701             }
05702 
05703         case T_NullIfExpr:
05704             {
05705                 NullIfExpr *expr = (NullIfExpr *) node;
05706 
05707                 if (expr->opretset)
05708                     return FALSE;
05709                 if (!exec_simple_check_node((Node *) expr->args))
05710                     return FALSE;
05711 
05712                 return TRUE;
05713             }
05714 
05715         case T_ScalarArrayOpExpr:
05716             {
05717                 ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
05718 
05719                 if (!exec_simple_check_node((Node *) expr->args))
05720                     return FALSE;
05721 
05722                 return TRUE;
05723             }
05724 
05725         case T_BoolExpr:
05726             {
05727                 BoolExpr   *expr = (BoolExpr *) node;
05728 
05729                 if (!exec_simple_check_node((Node *) expr->args))
05730                     return FALSE;
05731 
05732                 return TRUE;
05733             }
05734 
05735         case T_FieldSelect:
05736             return exec_simple_check_node((Node *) ((FieldSelect *) node)->arg);
05737 
05738         case T_FieldStore:
05739             {
05740                 FieldStore *expr = (FieldStore *) node;
05741 
05742                 if (!exec_simple_check_node((Node *) expr->arg))
05743                     return FALSE;
05744                 if (!exec_simple_check_node((Node *) expr->newvals))
05745                     return FALSE;
05746 
05747                 return TRUE;
05748             }
05749 
05750         case T_RelabelType:
05751             return exec_simple_check_node((Node *) ((RelabelType *) node)->arg);
05752 
05753         case T_CoerceViaIO:
05754             return exec_simple_check_node((Node *) ((CoerceViaIO *) node)->arg);
05755 
05756         case T_ArrayCoerceExpr:
05757             return exec_simple_check_node((Node *) ((ArrayCoerceExpr *) node)->arg);
05758 
05759         case T_ConvertRowtypeExpr:
05760             return exec_simple_check_node((Node *) ((ConvertRowtypeExpr *) node)->arg);
05761 
05762         case T_CaseExpr:
05763             {
05764                 CaseExpr   *expr = (CaseExpr *) node;
05765 
05766                 if (!exec_simple_check_node((Node *) expr->arg))
05767                     return FALSE;
05768                 if (!exec_simple_check_node((Node *) expr->args))
05769                     return FALSE;
05770                 if (!exec_simple_check_node((Node *) expr->defresult))
05771                     return FALSE;
05772 
05773                 return TRUE;
05774             }
05775 
05776         case T_CaseWhen:
05777             {
05778                 CaseWhen   *when = (CaseWhen *) node;
05779 
05780                 if (!exec_simple_check_node((Node *) when->expr))
05781                     return FALSE;
05782                 if (!exec_simple_check_node((Node *) when->result))
05783                     return FALSE;
05784 
05785                 return TRUE;
05786             }
05787 
05788         case T_CaseTestExpr:
05789             return TRUE;
05790 
05791         case T_ArrayExpr:
05792             {
05793                 ArrayExpr  *expr = (ArrayExpr *) node;
05794 
05795                 if (!exec_simple_check_node((Node *) expr->elements))
05796                     return FALSE;
05797 
05798                 return TRUE;
05799             }
05800 
05801         case T_RowExpr:
05802             {
05803                 RowExpr    *expr = (RowExpr *) node;
05804 
05805                 if (!exec_simple_check_node((Node *) expr->args))
05806                     return FALSE;
05807 
05808                 return TRUE;
05809             }
05810 
05811         case T_RowCompareExpr:
05812             {
05813                 RowCompareExpr *expr = (RowCompareExpr *) node;
05814 
05815                 if (!exec_simple_check_node((Node *) expr->largs))
05816                     return FALSE;
05817                 if (!exec_simple_check_node((Node *) expr->rargs))
05818                     return FALSE;
05819 
05820                 return TRUE;
05821             }
05822 
05823         case T_CoalesceExpr:
05824             {
05825                 CoalesceExpr *expr = (CoalesceExpr *) node;
05826 
05827                 if (!exec_simple_check_node((Node *) expr->args))
05828                     return FALSE;
05829 
05830                 return TRUE;
05831             }
05832 
05833         case T_MinMaxExpr:
05834             {
05835                 MinMaxExpr *expr = (MinMaxExpr *) node;
05836 
05837                 if (!exec_simple_check_node((Node *) expr->args))
05838                     return FALSE;
05839 
05840                 return TRUE;
05841             }
05842 
05843         case T_XmlExpr:
05844             {
05845                 XmlExpr    *expr = (XmlExpr *) node;
05846 
05847                 if (!exec_simple_check_node((Node *) expr->named_args))
05848                     return FALSE;
05849                 if (!exec_simple_check_node((Node *) expr->args))
05850                     return FALSE;
05851 
05852                 return TRUE;
05853             }
05854 
05855         case T_NullTest:
05856             return exec_simple_check_node((Node *) ((NullTest *) node)->arg);
05857 
05858         case T_BooleanTest:
05859             return exec_simple_check_node((Node *) ((BooleanTest *) node)->arg);
05860 
05861         case T_CoerceToDomain:
05862             return exec_simple_check_node((Node *) ((CoerceToDomain *) node)->arg);
05863 
05864         case T_CoerceToDomainValue:
05865             return TRUE;
05866 
05867         case T_List:
05868             {
05869                 List       *expr = (List *) node;
05870                 ListCell   *l;
05871 
05872                 foreach(l, expr)
05873                 {
05874                     if (!exec_simple_check_node(lfirst(l)))
05875                         return FALSE;
05876                 }
05877 
05878                 return TRUE;
05879             }
05880 
05881         default:
05882             return FALSE;
05883     }
05884 }
05885 
05886 
05887 /* ----------
05888  * exec_simple_check_plan -     Check if a plan is simple enough to
05889  *                              be evaluated by ExecEvalExpr() instead
05890  *                              of SPI.
05891  * ----------
05892  */
05893 static void
05894 exec_simple_check_plan(PLpgSQL_expr *expr)
05895 {
05896     List       *plansources;
05897     CachedPlanSource *plansource;
05898     Query      *query;
05899     CachedPlan *cplan;
05900 
05901     /*
05902      * Initialize to "not simple", and remember the plan generation number we
05903      * last checked.  (If we don't get as far as obtaining a plan to check, we
05904      * just leave expr_simple_generation set to 0.)
05905      */
05906     expr->expr_simple_expr = NULL;
05907     expr->expr_simple_generation = 0;
05908 
05909     /*
05910      * We can only test queries that resulted in exactly one CachedPlanSource
05911      */
05912     plansources = SPI_plan_get_plan_sources(expr->plan);
05913     if (list_length(plansources) != 1)
05914         return;
05915     plansource = (CachedPlanSource *) linitial(plansources);
05916 
05917     /*
05918      * Do some checking on the analyzed-and-rewritten form of the query. These
05919      * checks are basically redundant with the tests in
05920      * exec_simple_recheck_plan, but the point is to avoid building a plan if
05921      * possible.  Since this function is only called immediately after
05922      * creating the CachedPlanSource, we need not worry about the query being
05923      * stale.
05924      */
05925 
05926     /*
05927      * 1. There must be one single querytree.
05928      */
05929     if (list_length(plansource->query_list) != 1)
05930         return;
05931     query = (Query *) linitial(plansource->query_list);
05932 
05933     /*
05934      * 2. It must be a plain SELECT query without any input tables
05935      */
05936     if (!IsA(query, Query))
05937         return;
05938     if (query->commandType != CMD_SELECT)
05939         return;
05940     if (query->rtable != NIL)
05941         return;
05942 
05943     /*
05944      * 3. Can't have any subplans, aggregates, qual clauses either
05945      */
05946     if (query->hasAggs ||
05947         query->hasWindowFuncs ||
05948         query->hasSubLinks ||
05949         query->hasForUpdate ||
05950         query->cteList ||
05951         query->jointree->quals ||
05952         query->groupClause ||
05953         query->havingQual ||
05954         query->windowClause ||
05955         query->distinctClause ||
05956         query->sortClause ||
05957         query->limitOffset ||
05958         query->limitCount ||
05959         query->setOperations)
05960         return;
05961 
05962     /*
05963      * 4. The query must have a single attribute as result
05964      */
05965     if (list_length(query->targetList) != 1)
05966         return;
05967 
05968     /*
05969      * OK, it seems worth constructing a plan for more careful checking.
05970      */
05971 
05972     /* Get the generic plan for the query */
05973     cplan = SPI_plan_get_cached_plan(expr->plan);
05974 
05975     /* Can't fail, because we checked for a single CachedPlanSource above */
05976     Assert(cplan != NULL);
05977 
05978     /* Share the remaining work with recheck code path */
05979     exec_simple_recheck_plan(expr, cplan);
05980 
05981     /* Release our plan refcount */
05982     ReleaseCachedPlan(cplan, true);
05983 }
05984 
05985 /*
05986  * exec_simple_recheck_plan --- check for simple plan once we have CachedPlan
05987  */
05988 static void
05989 exec_simple_recheck_plan(PLpgSQL_expr *expr, CachedPlan *cplan)
05990 {
05991     PlannedStmt *stmt;
05992     Plan       *plan;
05993     TargetEntry *tle;
05994 
05995     /*
05996      * Initialize to "not simple", and remember the plan generation number we
05997      * last checked.
05998      */
05999     expr->expr_simple_expr = NULL;
06000     expr->expr_simple_generation = cplan->generation;
06001 
06002     /*
06003      * 1. There must be one single plantree
06004      */
06005     if (list_length(cplan->stmt_list) != 1)
06006         return;
06007     stmt = (PlannedStmt *) linitial(cplan->stmt_list);
06008 
06009     /*
06010      * 2. It must be a RESULT plan --> no scan's required
06011      */
06012     if (!IsA(stmt, PlannedStmt))
06013         return;
06014     if (stmt->commandType != CMD_SELECT)
06015         return;
06016     plan = stmt->planTree;
06017     if (!IsA(plan, Result))
06018         return;
06019 
06020     /*
06021      * 3. Can't have any subplan or qual clause, either
06022      */
06023     if (plan->lefttree != NULL ||
06024         plan->righttree != NULL ||
06025         plan->initPlan != NULL ||
06026         plan->qual != NULL ||
06027         ((Result *) plan)->resconstantqual != NULL)
06028         return;
06029 
06030     /*
06031      * 4. The plan must have a single attribute as result
06032      */
06033     if (list_length(plan->targetlist) != 1)
06034         return;
06035 
06036     tle = (TargetEntry *) linitial(plan->targetlist);
06037 
06038     /*
06039      * 5. Check that all the nodes in the expression are non-scary.
06040      */
06041     if (!exec_simple_check_node((Node *) tle->expr))
06042         return;
06043 
06044     /*
06045      * Yes - this is a simple expression.  Mark it as such, and initialize
06046      * state to "not valid in current transaction".
06047      */
06048     expr->expr_simple_expr = tle->expr;
06049     expr->expr_simple_state = NULL;
06050     expr->expr_simple_in_use = false;
06051     expr->expr_simple_lxid = InvalidLocalTransactionId;
06052     /* Also stash away the expression result type */
06053     expr->expr_simple_type = exprType((Node *) tle->expr);
06054 }
06055 
06056 /* ----------
06057  * exec_set_found           Set the global found variable to true/false
06058  * ----------
06059  */
06060 static void
06061 exec_set_found(PLpgSQL_execstate *estate, bool state)
06062 {
06063     PLpgSQL_var *var;
06064 
06065     var = (PLpgSQL_var *) (estate->datums[estate->found_varno]);
06066     var->value = BoolGetDatum(state);
06067     var->isnull = false;
06068 }
06069 
06070 /*
06071  * plpgsql_create_econtext --- create an eval_econtext for the current function
06072  *
06073  * We may need to create a new simple_eval_estate too, if there's not one
06074  * already for the current transaction.  The EState will be cleaned up at
06075  * transaction end.
06076  */
06077 static void
06078 plpgsql_create_econtext(PLpgSQL_execstate *estate)
06079 {
06080     SimpleEcontextStackEntry *entry;
06081 
06082     /*
06083      * Create an EState for evaluation of simple expressions, if there's not
06084      * one already in the current transaction.  The EState is made a child of
06085      * TopTransactionContext so it will have the right lifespan.
06086      */
06087     if (simple_eval_estate == NULL)
06088     {
06089         MemoryContext oldcontext;
06090 
06091         oldcontext = MemoryContextSwitchTo(TopTransactionContext);
06092         simple_eval_estate = CreateExecutorState();
06093         MemoryContextSwitchTo(oldcontext);
06094     }
06095 
06096     /*
06097      * Create a child econtext for the current function.
06098      */
06099     estate->eval_econtext = CreateExprContext(simple_eval_estate);
06100 
06101     /*
06102      * Make a stack entry so we can clean up the econtext at subxact end.
06103      * Stack entries are kept in TopTransactionContext for simplicity.
06104      */
06105     entry = (SimpleEcontextStackEntry *)
06106         MemoryContextAlloc(TopTransactionContext,
06107                            sizeof(SimpleEcontextStackEntry));
06108 
06109     entry->stack_econtext = estate->eval_econtext;
06110     entry->xact_subxid = GetCurrentSubTransactionId();
06111 
06112     entry->next = simple_econtext_stack;
06113     simple_econtext_stack = entry;
06114 }
06115 
06116 /*
06117  * plpgsql_destroy_econtext --- destroy function's econtext
06118  *
06119  * We check that it matches the top stack entry, and destroy the stack
06120  * entry along with the context.
06121  */
06122 static void
06123 plpgsql_destroy_econtext(PLpgSQL_execstate *estate)
06124 {
06125     SimpleEcontextStackEntry *next;
06126 
06127     Assert(simple_econtext_stack != NULL);
06128     Assert(simple_econtext_stack->stack_econtext == estate->eval_econtext);
06129 
06130     next = simple_econtext_stack->next;
06131     pfree(simple_econtext_stack);
06132     simple_econtext_stack = next;
06133 
06134     FreeExprContext(estate->eval_econtext, true);
06135     estate->eval_econtext = NULL;
06136 }
06137 
06138 /*
06139  * plpgsql_xact_cb --- post-transaction-commit-or-abort cleanup
06140  *
06141  * If a simple-expression EState was created in the current transaction,
06142  * it has to be cleaned up.
06143  */
06144 void
06145 plpgsql_xact_cb(XactEvent event, void *arg)
06146 {
06147     /*
06148      * If we are doing a clean transaction shutdown, free the EState (so that
06149      * any remaining resources will be released correctly). In an abort, we
06150      * expect the regular abort recovery procedures to release everything of
06151      * interest.
06152      */
06153     if (event == XACT_EVENT_COMMIT || event == XACT_EVENT_PREPARE)
06154     {
06155         /* Shouldn't be any econtext stack entries left at commit */
06156         Assert(simple_econtext_stack == NULL);
06157 
06158         if (simple_eval_estate)
06159             FreeExecutorState(simple_eval_estate);
06160         simple_eval_estate = NULL;
06161     }
06162     else if (event == XACT_EVENT_ABORT)
06163     {
06164         simple_econtext_stack = NULL;
06165         simple_eval_estate = NULL;
06166     }
06167 }
06168 
06169 /*
06170  * plpgsql_subxact_cb --- post-subtransaction-commit-or-abort cleanup
06171  *
06172  * Make sure any simple-expression econtexts created in the current
06173  * subtransaction get cleaned up.  We have to do this explicitly because
06174  * no other code knows which child econtexts of simple_eval_estate belong
06175  * to which level of subxact.
06176  */
06177 void
06178 plpgsql_subxact_cb(SubXactEvent event, SubTransactionId mySubid,
06179                    SubTransactionId parentSubid, void *arg)
06180 {
06181     if (event == SUBXACT_EVENT_COMMIT_SUB || event == SUBXACT_EVENT_ABORT_SUB)
06182     {
06183         while (simple_econtext_stack != NULL &&
06184                simple_econtext_stack->xact_subxid == mySubid)
06185         {
06186             SimpleEcontextStackEntry *next;
06187 
06188             FreeExprContext(simple_econtext_stack->stack_econtext,
06189                             (event == SUBXACT_EVENT_COMMIT_SUB));
06190             next = simple_econtext_stack->next;
06191             pfree(simple_econtext_stack);
06192             simple_econtext_stack = next;
06193         }
06194     }
06195 }
06196 
06197 /*
06198  * free_var --- pfree any pass-by-reference value of the variable.
06199  *
06200  * This should always be followed by some assignment to var->value,
06201  * as it leaves a dangling pointer.
06202  */
06203 static void
06204 free_var(PLpgSQL_var *var)
06205 {
06206     if (var->freeval)
06207     {
06208         pfree(DatumGetPointer(var->value));
06209         var->freeval = false;
06210     }
06211 }
06212 
06213 /*
06214  * free old value of a text variable and assign new value from C string
06215  */
06216 static void
06217 assign_text_var(PLpgSQL_var *var, const char *str)
06218 {
06219     free_var(var);
06220     var->value = CStringGetTextDatum(str);
06221     var->isnull = false;
06222     var->freeval = true;
06223 }
06224 
06225 /*
06226  * exec_eval_using_params --- evaluate params of USING clause
06227  */
06228 static PreparedParamsData *
06229 exec_eval_using_params(PLpgSQL_execstate *estate, List *params)
06230 {
06231     PreparedParamsData *ppd;
06232     int         nargs;
06233     int         i;
06234     ListCell   *lc;
06235 
06236     ppd = (PreparedParamsData *) palloc(sizeof(PreparedParamsData));
06237     nargs = list_length(params);
06238 
06239     ppd->nargs = nargs;
06240     ppd->types = (Oid *) palloc(nargs * sizeof(Oid));
06241     ppd->values = (Datum *) palloc(nargs * sizeof(Datum));
06242     ppd->nulls = (char *) palloc(nargs * sizeof(char));
06243     ppd->freevals = (bool *) palloc(nargs * sizeof(bool));
06244 
06245     i = 0;
06246     foreach(lc, params)
06247     {
06248         PLpgSQL_expr *param = (PLpgSQL_expr *) lfirst(lc);
06249         bool        isnull;
06250 
06251         ppd->values[i] = exec_eval_expr(estate, param,
06252                                         &isnull,
06253                                         &ppd->types[i]);
06254         ppd->nulls[i] = isnull ? 'n' : ' ';
06255         ppd->freevals[i] = false;
06256 
06257         if (ppd->types[i] == UNKNOWNOID)
06258         {
06259             /*
06260              * Treat 'unknown' parameters as text, since that's what most
06261              * people would expect. SPI_execute_with_args can coerce unknown
06262              * constants in a more intelligent way, but not unknown Params.
06263              * This code also takes care of copying into the right context.
06264              * Note we assume 'unknown' has the representation of C-string.
06265              */
06266             ppd->types[i] = TEXTOID;
06267             if (!isnull)
06268             {
06269                 ppd->values[i] = CStringGetTextDatum(DatumGetCString(ppd->values[i]));
06270                 ppd->freevals[i] = true;
06271             }
06272         }
06273         /* pass-by-ref non null values must be copied into plpgsql context */
06274         else if (!isnull)
06275         {
06276             int16       typLen;
06277             bool        typByVal;
06278 
06279             get_typlenbyval(ppd->types[i], &typLen, &typByVal);
06280             if (!typByVal)
06281             {
06282                 ppd->values[i] = datumCopy(ppd->values[i], typByVal, typLen);
06283                 ppd->freevals[i] = true;
06284             }
06285         }
06286 
06287         exec_eval_cleanup(estate);
06288 
06289         i++;
06290     }
06291 
06292     return ppd;
06293 }
06294 
06295 /*
06296  * free_params_data --- pfree all pass-by-reference values used in USING clause
06297  */
06298 static void
06299 free_params_data(PreparedParamsData *ppd)
06300 {
06301     int         i;
06302 
06303     for (i = 0; i < ppd->nargs; i++)
06304     {
06305         if (ppd->freevals[i])
06306             pfree(DatumGetPointer(ppd->values[i]));
06307     }
06308 
06309     pfree(ppd->types);
06310     pfree(ppd->values);
06311     pfree(ppd->nulls);
06312     pfree(ppd->freevals);
06313 
06314     pfree(ppd);
06315 }
06316 
06317 /*
06318  * Open portal for dynamic query
06319  */
06320 static Portal
06321 exec_dynquery_with_params(PLpgSQL_execstate *estate,
06322                           PLpgSQL_expr *dynquery,
06323                           List *params,
06324                           const char *portalname,
06325                           int cursorOptions)
06326 {
06327     Portal      portal;
06328     Datum       query;
06329     bool        isnull;
06330     Oid         restype;
06331     char       *querystr;
06332 
06333     /*
06334      * Evaluate the string expression after the EXECUTE keyword. Its result is
06335      * the querystring we have to execute.
06336      */
06337     query = exec_eval_expr(estate, dynquery, &isnull, &restype);
06338     if (isnull)
06339         ereport(ERROR,
06340                 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
06341                  errmsg("query string argument of EXECUTE is null")));
06342 
06343     /* Get the C-String representation */
06344     querystr = convert_value_to_string(estate, query, restype);
06345 
06346     /* copy it out of the temporary context before we clean up */
06347     querystr = pstrdup(querystr);
06348 
06349     exec_eval_cleanup(estate);
06350 
06351     /*
06352      * Open an implicit cursor for the query.  We use
06353      * SPI_cursor_open_with_args even when there are no params, because this
06354      * avoids making and freeing one copy of the plan.
06355      */
06356     if (params)
06357     {
06358         PreparedParamsData *ppd;
06359 
06360         ppd = exec_eval_using_params(estate, params);
06361         portal = SPI_cursor_open_with_args(portalname,
06362                                            querystr,
06363                                            ppd->nargs, ppd->types,
06364                                            ppd->values, ppd->nulls,
06365                                            estate->readonly_func,
06366                                            cursorOptions);
06367         free_params_data(ppd);
06368     }
06369     else
06370     {
06371         portal = SPI_cursor_open_with_args(portalname,
06372                                            querystr,
06373                                            0, NULL,
06374                                            NULL, NULL,
06375                                            estate->readonly_func,
06376                                            cursorOptions);
06377     }
06378 
06379     if (portal == NULL)
06380         elog(ERROR, "could not open implicit cursor for query \"%s\": %s",
06381              querystr, SPI_result_code_string(SPI_result));
06382     pfree(querystr);
06383 
06384     return portal;
06385 }