LCOV - differential code coverage report
Current view: top level - src/pl/plpgsql/src - pl_exec.c (source / functions) Coverage Total Hit LBC UIC UBC GBC GIC GNC CBC EUB ECB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 91.2 % 2717 2477 52 118 70 45 1176 5 1251 125 1172 2
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 94 94 75 1 18 75
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /*-------------------------------------------------------------------------
       2                 :  *
       3                 :  * pl_exec.c        - Executor for the PL/pgSQL
       4                 :  *            procedural language
       5                 :  *
       6                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
       7                 :  * Portions Copyright (c) 1994, Regents of the University of California
       8                 :  *
       9                 :  *
      10                 :  * IDENTIFICATION
      11                 :  *    src/pl/plpgsql/src/pl_exec.c
      12                 :  *
      13                 :  *-------------------------------------------------------------------------
      14                 :  */
      15                 : 
      16                 : #include "postgres.h"
      17                 : 
      18                 : #include <ctype.h>
      19                 : 
      20                 : #include "access/detoast.h"
      21                 : #include "access/htup_details.h"
      22                 : #include "access/transam.h"
      23                 : #include "access/tupconvert.h"
      24                 : #include "catalog/pg_proc.h"
      25                 : #include "catalog/pg_type.h"
      26                 : #include "commands/defrem.h"
      27                 : #include "executor/execExpr.h"
      28                 : #include "executor/spi.h"
      29                 : #include "executor/tstoreReceiver.h"
      30                 : #include "funcapi.h"
      31                 : #include "mb/stringinfo_mb.h"
      32                 : #include "miscadmin.h"
      33                 : #include "nodes/nodeFuncs.h"
      34                 : #include "optimizer/optimizer.h"
      35                 : #include "parser/parse_coerce.h"
      36                 : #include "parser/parse_type.h"
      37                 : #include "parser/scansup.h"
      38                 : #include "plpgsql.h"
      39                 : #include "storage/proc.h"
      40                 : #include "tcop/cmdtag.h"
      41                 : #include "tcop/pquery.h"
      42                 : #include "tcop/tcopprot.h"
      43                 : #include "tcop/utility.h"
      44                 : #include "utils/array.h"
      45                 : #include "utils/builtins.h"
      46                 : #include "utils/datum.h"
      47                 : #include "utils/fmgroids.h"
      48                 : #include "utils/lsyscache.h"
      49                 : #include "utils/memutils.h"
      50                 : #include "utils/rel.h"
      51                 : #include "utils/snapmgr.h"
      52                 : #include "utils/syscache.h"
      53                 : #include "utils/typcache.h"
      54                 : 
      55                 : /*
      56                 :  * All plpgsql function executions within a single transaction share the same
      57                 :  * executor EState for evaluating "simple" expressions.  Each function call
      58                 :  * creates its own "eval_econtext" ExprContext within this estate for
      59                 :  * per-evaluation workspace.  eval_econtext is freed at normal function exit,
      60                 :  * and the EState is freed at transaction end (in case of error, we assume
      61                 :  * that the abort mechanisms clean it all up).  Furthermore, any exception
      62                 :  * block within a function has to have its own eval_econtext separate from
      63                 :  * the containing function's, so that we can clean up ExprContext callbacks
      64                 :  * properly at subtransaction exit.  We maintain a stack that tracks the
      65                 :  * individual econtexts so that we can clean up correctly at subxact exit.
      66                 :  *
      67                 :  * This arrangement is a bit tedious to maintain, but it's worth the trouble
      68                 :  * so that we don't have to re-prepare simple expressions on each trip through
      69                 :  * a function.  (We assume the case to optimize is many repetitions of a
      70                 :  * function within a transaction.)
      71                 :  *
      72                 :  * However, there's no value in trying to amortize simple expression setup
      73                 :  * across multiple executions of a DO block (inline code block), since there
      74                 :  * can never be any.  If we use the shared EState for a DO block, the expr
      75                 :  * state trees are effectively leaked till end of transaction, and that can
      76                 :  * add up if the user keeps on submitting DO blocks.  Therefore, each DO block
      77                 :  * has its own simple-expression EState, which is cleaned up at exit from
      78                 :  * plpgsql_inline_handler().  DO blocks still use the simple_econtext_stack,
      79                 :  * though, so that subxact abort cleanup does the right thing.
      80                 :  *
      81                 :  * (However, if a DO block executes COMMIT or ROLLBACK, then exec_stmt_commit
      82                 :  * or exec_stmt_rollback will unlink it from the DO's simple-expression EState
      83                 :  * and create a new shared EState that will be used thenceforth.  The original
      84                 :  * EState will be cleaned up when we get back to plpgsql_inline_handler.  This
      85                 :  * is a bit ugly, but it isn't worth doing better, since scenarios like this
      86                 :  * can't result in indefinite accumulation of state trees.)
      87                 :  */
      88                 : typedef struct SimpleEcontextStackEntry
      89                 : {
      90                 :     ExprContext *stack_econtext;    /* a stacked econtext */
      91                 :     SubTransactionId xact_subxid;   /* ID for current subxact */
      92                 :     struct SimpleEcontextStackEntry *next;  /* next stack entry up */
      93                 : } SimpleEcontextStackEntry;
      94                 : 
      95                 : static EState *shared_simple_eval_estate = NULL;
      96                 : static SimpleEcontextStackEntry *simple_econtext_stack = NULL;
      97                 : 
      98                 : /*
      99                 :  * In addition to the shared simple-eval EState, we have a shared resource
     100                 :  * owner that holds refcounts on the CachedPlans for any "simple" expressions
     101                 :  * we have evaluated in the current transaction.  This allows us to avoid
     102                 :  * continually grabbing and releasing a plan refcount when a simple expression
     103                 :  * is used over and over.  (DO blocks use their own resowner, in exactly the
     104                 :  * same way described above for shared_simple_eval_estate.)
     105                 :  */
     106                 : static ResourceOwner shared_simple_eval_resowner = NULL;
     107                 : 
     108                 : /*
     109                 :  * Memory management within a plpgsql function generally works with three
     110                 :  * contexts:
     111                 :  *
     112                 :  * 1. Function-call-lifespan data, such as variable values, is kept in the
     113                 :  * "main" context, a/k/a the "SPI Proc" context established by SPI_connect().
     114                 :  * This is usually the CurrentMemoryContext while running code in this module
     115                 :  * (which is not good, because careless coding can easily cause
     116                 :  * function-lifespan memory leaks, but we live with it for now).
     117                 :  *
     118                 :  * 2. Some statement-execution routines need statement-lifespan workspace.
     119                 :  * A suitable context is created on-demand by get_stmt_mcontext(), and must
     120                 :  * be reset at the end of the requesting routine.  Error recovery will clean
     121                 :  * it up automatically.  Nested statements requiring statement-lifespan
     122                 :  * workspace will result in a stack of such contexts, see push_stmt_mcontext().
     123                 :  *
     124                 :  * 3. We use the eval_econtext's per-tuple memory context for expression
     125                 :  * evaluation, and as a general-purpose workspace for short-lived allocations.
     126                 :  * Such allocations usually aren't explicitly freed, but are left to be
     127                 :  * cleaned up by a context reset, typically done by exec_eval_cleanup().
     128                 :  *
     129                 :  * These macros are for use in making short-lived allocations:
     130                 :  */
     131                 : #define get_eval_mcontext(estate) \
     132                 :     ((estate)->eval_econtext->ecxt_per_tuple_memory)
     133                 : #define eval_mcontext_alloc(estate, sz) \
     134                 :     MemoryContextAlloc(get_eval_mcontext(estate), sz)
     135                 : #define eval_mcontext_alloc0(estate, sz) \
     136                 :     MemoryContextAllocZero(get_eval_mcontext(estate), sz)
     137                 : 
     138                 : /*
     139                 :  * We use a session-wide hash table for caching cast information.
     140                 :  *
     141                 :  * Once built, the compiled expression trees (cast_expr fields) survive for
     142                 :  * the life of the session.  At some point it might be worth invalidating
     143                 :  * those after pg_cast changes, but for the moment we don't bother.
     144                 :  *
     145                 :  * The evaluation state trees (cast_exprstate) are managed in the same way as
     146                 :  * simple expressions (i.e., we assume cast expressions are always simple).
     147                 :  *
     148                 :  * As with simple expressions, DO blocks don't use the shared hash table but
     149                 :  * must have their own.  This isn't ideal, but we don't want to deal with
     150                 :  * multiple simple_eval_estates within a DO block.
     151                 :  */
     152                 : typedef struct                  /* lookup key for cast info */
     153                 : {
     154                 :     /* NB: we assume this struct contains no padding bytes */
     155                 :     Oid         srctype;        /* source type for cast */
     156                 :     Oid         dsttype;        /* destination type for cast */
     157                 :     int32       srctypmod;      /* source typmod for cast */
     158                 :     int32       dsttypmod;      /* destination typmod for cast */
     159                 : } plpgsql_CastHashKey;
     160                 : 
     161                 : typedef struct                  /* cast_hash table entry */
     162                 : {
     163                 :     plpgsql_CastHashKey key;    /* hash key --- MUST BE FIRST */
     164                 :     Expr       *cast_expr;      /* cast expression, or NULL if no-op cast */
     165                 :     CachedExpression *cast_cexpr;   /* cached expression backing the above */
     166                 :     /* ExprState is valid only when cast_lxid matches current LXID */
     167                 :     ExprState  *cast_exprstate; /* expression's eval tree */
     168                 :     bool        cast_in_use;    /* true while we're executing eval tree */
     169                 :     LocalTransactionId cast_lxid;
     170                 : } plpgsql_CastHashEntry;
     171                 : 
     172                 : static MemoryContext shared_cast_context = NULL;
     173                 : static HTAB *shared_cast_hash = NULL;
     174                 : 
     175                 : /*
     176                 :  * LOOP_RC_PROCESSING encapsulates common logic for looping statements to
     177                 :  * handle return/exit/continue result codes from the loop body statement(s).
     178                 :  * It's meant to be used like this:
     179                 :  *
     180                 :  *      int rc = PLPGSQL_RC_OK;
     181                 :  *      for (...)
     182                 :  *      {
     183                 :  *          ...
     184                 :  *          rc = exec_stmts(estate, stmt->body);
     185                 :  *          LOOP_RC_PROCESSING(stmt->label, break);
     186                 :  *          ...
     187                 :  *      }
     188                 :  *      return rc;
     189                 :  *
     190                 :  * If execution of the loop should terminate, LOOP_RC_PROCESSING will execute
     191                 :  * "exit_action" (typically a "break" or "goto"), after updating "rc" to the
     192                 :  * value the current statement should return.  If execution should continue,
     193                 :  * LOOP_RC_PROCESSING will do nothing except reset "rc" to PLPGSQL_RC_OK.
     194                 :  *
     195                 :  * estate and rc are implicit arguments to the macro.
     196                 :  * estate->exitlabel is examined and possibly updated.
     197                 :  */
     198                 : #define LOOP_RC_PROCESSING(looplabel, exit_action) \
     199                 :     if (rc == PLPGSQL_RC_RETURN) \
     200                 :     { \
     201                 :         /* RETURN, so propagate RC_RETURN out */ \
     202                 :         exit_action; \
     203                 :     } \
     204                 :     else if (rc == PLPGSQL_RC_EXIT) \
     205                 :     { \
     206                 :         if (estate->exitlabel == NULL) \
     207                 :         { \
     208                 :             /* unlabeled EXIT terminates this loop */ \
     209                 :             rc = PLPGSQL_RC_OK; \
     210                 :             exit_action; \
     211                 :         } \
     212                 :         else if ((looplabel) != NULL && \
     213                 :                  strcmp(looplabel, estate->exitlabel) == 0) \
     214                 :         { \
     215                 :             /* labeled EXIT matching this loop, so terminate loop */ \
     216                 :             estate->exitlabel = NULL; \
     217                 :             rc = PLPGSQL_RC_OK; \
     218                 :             exit_action; \
     219                 :         } \
     220                 :         else \
     221                 :         { \
     222                 :             /* non-matching labeled EXIT, propagate RC_EXIT out */ \
     223                 :             exit_action; \
     224                 :         } \
     225                 :     } \
     226                 :     else if (rc == PLPGSQL_RC_CONTINUE) \
     227                 :     { \
     228                 :         if (estate->exitlabel == NULL) \
     229                 :         { \
     230                 :             /* unlabeled CONTINUE matches this loop, so continue in loop */ \
     231                 :             rc = PLPGSQL_RC_OK; \
     232                 :         } \
     233                 :         else if ((looplabel) != NULL && \
     234                 :                  strcmp(looplabel, estate->exitlabel) == 0) \
     235                 :         { \
     236                 :             /* labeled CONTINUE matching this loop, so continue in loop */ \
     237                 :             estate->exitlabel = NULL; \
     238                 :             rc = PLPGSQL_RC_OK; \
     239                 :         } \
     240                 :         else \
     241                 :         { \
     242                 :             /* non-matching labeled CONTINUE, propagate RC_CONTINUE out */ \
     243                 :             exit_action; \
     244                 :         } \
     245                 :     } \
     246                 :     else \
     247                 :         Assert(rc == PLPGSQL_RC_OK)
     248                 : 
     249                 : /************************************************************
     250                 :  * Local function forward declarations
     251                 :  ************************************************************/
     252                 : static void coerce_function_result_tuple(PLpgSQL_execstate *estate,
     253                 :                                          TupleDesc tupdesc);
     254                 : static void plpgsql_exec_error_callback(void *arg);
     255                 : static void copy_plpgsql_datums(PLpgSQL_execstate *estate,
     256                 :                                 PLpgSQL_function *func);
     257                 : static void plpgsql_fulfill_promise(PLpgSQL_execstate *estate,
     258                 :                                     PLpgSQL_var *var);
     259                 : static MemoryContext get_stmt_mcontext(PLpgSQL_execstate *estate);
     260                 : static void push_stmt_mcontext(PLpgSQL_execstate *estate);
     261                 : static void pop_stmt_mcontext(PLpgSQL_execstate *estate);
     262                 : 
     263                 : static int  exec_toplevel_block(PLpgSQL_execstate *estate,
     264                 :                                 PLpgSQL_stmt_block *block);
     265                 : static int  exec_stmt_block(PLpgSQL_execstate *estate,
     266                 :                             PLpgSQL_stmt_block *block);
     267                 : static int  exec_stmts(PLpgSQL_execstate *estate,
     268                 :                        List *stmts);
     269                 : static int  exec_stmt_assign(PLpgSQL_execstate *estate,
     270                 :                              PLpgSQL_stmt_assign *stmt);
     271                 : static int  exec_stmt_perform(PLpgSQL_execstate *estate,
     272                 :                               PLpgSQL_stmt_perform *stmt);
     273                 : static int  exec_stmt_call(PLpgSQL_execstate *estate,
     274                 :                            PLpgSQL_stmt_call *stmt);
     275                 : static int  exec_stmt_getdiag(PLpgSQL_execstate *estate,
     276                 :                               PLpgSQL_stmt_getdiag *stmt);
     277                 : static int  exec_stmt_if(PLpgSQL_execstate *estate,
     278                 :                          PLpgSQL_stmt_if *stmt);
     279                 : static int  exec_stmt_case(PLpgSQL_execstate *estate,
     280                 :                            PLpgSQL_stmt_case *stmt);
     281                 : static int  exec_stmt_loop(PLpgSQL_execstate *estate,
     282                 :                            PLpgSQL_stmt_loop *stmt);
     283                 : static int  exec_stmt_while(PLpgSQL_execstate *estate,
     284                 :                             PLpgSQL_stmt_while *stmt);
     285                 : static int  exec_stmt_fori(PLpgSQL_execstate *estate,
     286                 :                            PLpgSQL_stmt_fori *stmt);
     287                 : static int  exec_stmt_fors(PLpgSQL_execstate *estate,
     288                 :                            PLpgSQL_stmt_fors *stmt);
     289                 : static int  exec_stmt_forc(PLpgSQL_execstate *estate,
     290                 :                            PLpgSQL_stmt_forc *stmt);
     291                 : static int  exec_stmt_foreach_a(PLpgSQL_execstate *estate,
     292                 :                                 PLpgSQL_stmt_foreach_a *stmt);
     293                 : static int  exec_stmt_open(PLpgSQL_execstate *estate,
     294                 :                            PLpgSQL_stmt_open *stmt);
     295                 : static int  exec_stmt_fetch(PLpgSQL_execstate *estate,
     296                 :                             PLpgSQL_stmt_fetch *stmt);
     297                 : static int  exec_stmt_close(PLpgSQL_execstate *estate,
     298                 :                             PLpgSQL_stmt_close *stmt);
     299                 : static int  exec_stmt_exit(PLpgSQL_execstate *estate,
     300                 :                            PLpgSQL_stmt_exit *stmt);
     301                 : static int  exec_stmt_return(PLpgSQL_execstate *estate,
     302                 :                              PLpgSQL_stmt_return *stmt);
     303                 : static int  exec_stmt_return_next(PLpgSQL_execstate *estate,
     304                 :                                   PLpgSQL_stmt_return_next *stmt);
     305                 : static int  exec_stmt_return_query(PLpgSQL_execstate *estate,
     306                 :                                    PLpgSQL_stmt_return_query *stmt);
     307                 : static int  exec_stmt_raise(PLpgSQL_execstate *estate,
     308                 :                             PLpgSQL_stmt_raise *stmt);
     309                 : static int  exec_stmt_assert(PLpgSQL_execstate *estate,
     310                 :                              PLpgSQL_stmt_assert *stmt);
     311                 : static int  exec_stmt_execsql(PLpgSQL_execstate *estate,
     312                 :                               PLpgSQL_stmt_execsql *stmt);
     313                 : static int  exec_stmt_dynexecute(PLpgSQL_execstate *estate,
     314                 :                                  PLpgSQL_stmt_dynexecute *stmt);
     315                 : static int  exec_stmt_dynfors(PLpgSQL_execstate *estate,
     316                 :                               PLpgSQL_stmt_dynfors *stmt);
     317                 : static int  exec_stmt_commit(PLpgSQL_execstate *estate,
     318                 :                              PLpgSQL_stmt_commit *stmt);
     319                 : static int  exec_stmt_rollback(PLpgSQL_execstate *estate,
     320                 :                                PLpgSQL_stmt_rollback *stmt);
     321                 : 
     322                 : static void plpgsql_estate_setup(PLpgSQL_execstate *estate,
     323                 :                                  PLpgSQL_function *func,
     324                 :                                  ReturnSetInfo *rsi,
     325                 :                                  EState *simple_eval_estate,
     326                 :                                  ResourceOwner simple_eval_resowner);
     327                 : static void exec_eval_cleanup(PLpgSQL_execstate *estate);
     328                 : 
     329                 : static void exec_prepare_plan(PLpgSQL_execstate *estate,
     330                 :                               PLpgSQL_expr *expr, int cursorOptions);
     331                 : static void exec_simple_check_plan(PLpgSQL_execstate *estate, PLpgSQL_expr *expr);
     332                 : static void exec_save_simple_expr(PLpgSQL_expr *expr, CachedPlan *cplan);
     333                 : static void exec_check_rw_parameter(PLpgSQL_expr *expr);
     334                 : static void exec_check_assignable(PLpgSQL_execstate *estate, int dno);
     335                 : static bool exec_eval_simple_expr(PLpgSQL_execstate *estate,
     336                 :                                   PLpgSQL_expr *expr,
     337                 :                                   Datum *result,
     338                 :                                   bool *isNull,
     339                 :                                   Oid *rettype,
     340                 :                                   int32 *rettypmod);
     341                 : 
     342                 : static void exec_assign_expr(PLpgSQL_execstate *estate,
     343                 :                              PLpgSQL_datum *target,
     344                 :                              PLpgSQL_expr *expr);
     345                 : static void exec_assign_c_string(PLpgSQL_execstate *estate,
     346                 :                                  PLpgSQL_datum *target,
     347                 :                                  const char *str);
     348                 : static void exec_assign_value(PLpgSQL_execstate *estate,
     349                 :                               PLpgSQL_datum *target,
     350                 :                               Datum value, bool isNull,
     351                 :                               Oid valtype, int32 valtypmod);
     352                 : static void exec_eval_datum(PLpgSQL_execstate *estate,
     353                 :                             PLpgSQL_datum *datum,
     354                 :                             Oid *typeid,
     355                 :                             int32 *typetypmod,
     356                 :                             Datum *value,
     357                 :                             bool *isnull);
     358                 : static int  exec_eval_integer(PLpgSQL_execstate *estate,
     359                 :                               PLpgSQL_expr *expr,
     360                 :                               bool *isNull);
     361                 : static bool exec_eval_boolean(PLpgSQL_execstate *estate,
     362                 :                               PLpgSQL_expr *expr,
     363                 :                               bool *isNull);
     364                 : static Datum exec_eval_expr(PLpgSQL_execstate *estate,
     365                 :                             PLpgSQL_expr *expr,
     366                 :                             bool *isNull,
     367                 :                             Oid *rettype,
     368                 :                             int32 *rettypmod);
     369                 : static int  exec_run_select(PLpgSQL_execstate *estate,
     370                 :                             PLpgSQL_expr *expr, long maxtuples, Portal *portalP);
     371                 : static int  exec_for_query(PLpgSQL_execstate *estate, PLpgSQL_stmt_forq *stmt,
     372                 :                            Portal portal, bool prefetch_ok);
     373                 : static ParamListInfo setup_param_list(PLpgSQL_execstate *estate,
     374                 :                                       PLpgSQL_expr *expr);
     375                 : static ParamExternData *plpgsql_param_fetch(ParamListInfo params,
     376                 :                                             int paramid, bool speculative,
     377                 :                                             ParamExternData *prm);
     378                 : static void plpgsql_param_compile(ParamListInfo params, Param *param,
     379                 :                                   ExprState *state,
     380                 :                                   Datum *resv, bool *resnull);
     381                 : static void plpgsql_param_eval_var(ExprState *state, ExprEvalStep *op,
     382                 :                                    ExprContext *econtext);
     383                 : static void plpgsql_param_eval_var_ro(ExprState *state, ExprEvalStep *op,
     384                 :                                       ExprContext *econtext);
     385                 : static void plpgsql_param_eval_recfield(ExprState *state, ExprEvalStep *op,
     386                 :                                         ExprContext *econtext);
     387                 : static void plpgsql_param_eval_generic(ExprState *state, ExprEvalStep *op,
     388                 :                                        ExprContext *econtext);
     389                 : static void plpgsql_param_eval_generic_ro(ExprState *state, ExprEvalStep *op,
     390                 :                                           ExprContext *econtext);
     391                 : static void exec_move_row(PLpgSQL_execstate *estate,
     392                 :                           PLpgSQL_variable *target,
     393                 :                           HeapTuple tup, TupleDesc tupdesc);
     394                 : static void revalidate_rectypeid(PLpgSQL_rec *rec);
     395                 : static ExpandedRecordHeader *make_expanded_record_for_rec(PLpgSQL_execstate *estate,
     396                 :                                                           PLpgSQL_rec *rec,
     397                 :                                                           TupleDesc srctupdesc,
     398                 :                                                           ExpandedRecordHeader *srcerh);
     399                 : static void exec_move_row_from_fields(PLpgSQL_execstate *estate,
     400                 :                                       PLpgSQL_variable *target,
     401                 :                                       ExpandedRecordHeader *newerh,
     402                 :                                       Datum *values, bool *nulls,
     403                 :                                       TupleDesc tupdesc);
     404                 : static bool compatible_tupdescs(TupleDesc src_tupdesc, TupleDesc dst_tupdesc);
     405                 : static HeapTuple make_tuple_from_row(PLpgSQL_execstate *estate,
     406                 :                                      PLpgSQL_row *row,
     407                 :                                      TupleDesc tupdesc);
     408                 : static TupleDesc deconstruct_composite_datum(Datum value,
     409                 :                                              HeapTupleData *tmptup);
     410                 : static void exec_move_row_from_datum(PLpgSQL_execstate *estate,
     411                 :                                      PLpgSQL_variable *target,
     412                 :                                      Datum value);
     413                 : static void instantiate_empty_record_variable(PLpgSQL_execstate *estate,
     414                 :                                               PLpgSQL_rec *rec);
     415                 : static char *convert_value_to_string(PLpgSQL_execstate *estate,
     416                 :                                      Datum value, Oid valtype);
     417                 : static inline Datum exec_cast_value(PLpgSQL_execstate *estate,
     418                 :                                     Datum value, bool *isnull,
     419                 :                                     Oid valtype, int32 valtypmod,
     420                 :                                     Oid reqtype, int32 reqtypmod);
     421                 : static Datum do_cast_value(PLpgSQL_execstate *estate,
     422                 :                            Datum value, bool *isnull,
     423                 :                            Oid valtype, int32 valtypmod,
     424                 :                            Oid reqtype, int32 reqtypmod);
     425                 : static plpgsql_CastHashEntry *get_cast_hashentry(PLpgSQL_execstate *estate,
     426                 :                                                  Oid srctype, int32 srctypmod,
     427                 :                                                  Oid dsttype, int32 dsttypmod);
     428                 : static void exec_init_tuple_store(PLpgSQL_execstate *estate);
     429                 : static void exec_set_found(PLpgSQL_execstate *estate, bool state);
     430                 : static void plpgsql_create_econtext(PLpgSQL_execstate *estate);
     431                 : static void plpgsql_destroy_econtext(PLpgSQL_execstate *estate);
     432                 : static void assign_simple_var(PLpgSQL_execstate *estate, PLpgSQL_var *var,
     433                 :                               Datum newvalue, bool isnull, bool freeable);
     434                 : static void assign_text_var(PLpgSQL_execstate *estate, PLpgSQL_var *var,
     435                 :                             const char *str);
     436                 : static void assign_record_var(PLpgSQL_execstate *estate, PLpgSQL_rec *rec,
     437                 :                               ExpandedRecordHeader *erh);
     438                 : static ParamListInfo exec_eval_using_params(PLpgSQL_execstate *estate,
     439                 :                                             List *params);
     440                 : static Portal exec_dynquery_with_params(PLpgSQL_execstate *estate,
     441                 :                                         PLpgSQL_expr *dynquery, List *params,
     442                 :                                         const char *portalname, int cursorOptions);
     443                 : static char *format_expr_params(PLpgSQL_execstate *estate,
     444                 :                                 const PLpgSQL_expr *expr);
     445                 : static char *format_preparedparamsdata(PLpgSQL_execstate *estate,
     446                 :                                        ParamListInfo paramLI);
     447                 : static PLpgSQL_variable *make_callstmt_target(PLpgSQL_execstate *estate,
     448                 :                                               PLpgSQL_expr *expr);
     449                 : 
     450                 : 
     451                 : /* ----------
     452                 :  * plpgsql_exec_function    Called by the call handler for
     453                 :  *              function execution.
     454                 :  *
     455                 :  * This is also used to execute inline code blocks (DO blocks).  The only
     456                 :  * difference that this code is aware of is that for a DO block, we want
     457                 :  * to use a private simple_eval_estate and a private simple_eval_resowner,
     458                 :  * which are created and passed in by the caller.  For regular functions,
     459                 :  * pass NULL, which implies using shared_simple_eval_estate and
     460                 :  * shared_simple_eval_resowner.  (When using a private simple_eval_estate,
     461                 :  * we must also use a private cast hashtable, but that's taken care of
     462                 :  * within plpgsql_estate_setup.)
     463                 :  * procedure_resowner is a resowner that will survive for the duration
     464                 :  * of execution of this function/procedure.  It is needed only if we
     465                 :  * are doing non-atomic execution and there are CALL or DO statements
     466                 :  * in the function; otherwise it can be NULL.  We use it to hold refcounts
     467                 :  * on the CALL/DO statements' plans.
     468                 :  * ----------
     469                 :  */
     470                 : Datum
     471 CBC       32264 : plpgsql_exec_function(PLpgSQL_function *func, FunctionCallInfo fcinfo,
     472                 :                       EState *simple_eval_estate,
     473                 :                       ResourceOwner simple_eval_resowner,
     474                 :                       ResourceOwner procedure_resowner,
     475                 :                       bool atomic)
     476                 : {
     477                 :     PLpgSQL_execstate estate;
     478                 :     ErrorContextCallback plerrcontext;
     479                 :     int         i;
     480                 :     int         rc;
     481                 : 
     482                 :     /*
     483                 :      * Setup the execution state
     484                 :      */
     485           32264 :     plpgsql_estate_setup(&estate, func, (ReturnSetInfo *) fcinfo->resultinfo,
     486                 :                          simple_eval_estate, simple_eval_resowner);
     487           32264 :     estate.procedure_resowner = procedure_resowner;
     488           32264 :     estate.atomic = atomic;
     489                 : 
     490                 :     /*
     491                 :      * Setup error traceback support for ereport()
     492                 :      */
     493           32264 :     plerrcontext.callback = plpgsql_exec_error_callback;
     494           32264 :     plerrcontext.arg = &estate;
     495           32264 :     plerrcontext.previous = error_context_stack;
     496           32264 :     error_context_stack = &plerrcontext;
     497                 : 
     498                 :     /*
     499                 :      * Make local execution copies of all the datums
     500                 :      */
     501           32264 :     estate.err_text = gettext_noop("during initialization of execution state");
     502           32264 :     copy_plpgsql_datums(&estate, func);
     503                 : 
     504                 :     /*
     505                 :      * Store the actual call argument values into the appropriate variables
     506                 :      */
     507           32264 :     estate.err_text = gettext_noop("while storing call arguments into local variables");
     508           72035 :     for (i = 0; i < func->fn_nargs; i++)
     509                 :     {
     510           39771 :         int         n = func->fn_argvarnos[i];
     511                 : 
     512           39771 :         switch (estate.datums[n]->dtype)
     513                 :         {
     514           39629 :             case PLPGSQL_DTYPE_VAR:
     515                 :                 {
     516           39629 :                     PLpgSQL_var *var = (PLpgSQL_var *) estate.datums[n];
     517                 : 
     518           39629 :                     assign_simple_var(&estate, var,
     519                 :                                       fcinfo->args[i].value,
     520           39629 :                                       fcinfo->args[i].isnull,
     521                 :                                       false);
     522                 : 
     523                 :                     /*
     524                 :                      * Force any array-valued parameter to be stored in
     525                 :                      * expanded form in our local variable, in hopes of
     526                 :                      * improving efficiency of uses of the variable.  (This is
     527                 :                      * a hack, really: why only arrays? Need more thought
     528                 :                      * about which cases are likely to win.  See also
     529                 :                      * typisarray-specific heuristic in exec_assign_value.)
     530                 :                      *
     531                 :                      * Special cases: If passed a R/W expanded pointer, assume
     532                 :                      * we can commandeer the object rather than having to copy
     533                 :                      * it.  If passed a R/O expanded pointer, just keep it as
     534                 :                      * the value of the variable for the moment.  (We'll force
     535                 :                      * it to R/W if the variable gets modified, but that may
     536                 :                      * very well never happen.)
     537                 :                      */
     538           39629 :                     if (!var->isnull && var->datatype->typisarray)
     539                 :                     {
     540            1730 :                         if (VARATT_IS_EXTERNAL_EXPANDED_RW(DatumGetPointer(var->value)))
     541                 :                         {
     542                 :                             /* take ownership of R/W object */
     543               3 :                             assign_simple_var(&estate, var,
     544                 :                                               TransferExpandedObject(var->value,
     545                 :                                                                      estate.datum_context),
     546                 :                                               false,
     547                 :                                               true);
     548                 :                         }
     549            1727 :                         else if (VARATT_IS_EXTERNAL_EXPANDED_RO(DatumGetPointer(var->value)))
     550                 :                         {
     551                 :                             /* R/O pointer, keep it as-is until assigned to */
     552                 :                         }
     553                 :                         else
     554                 :                         {
     555                 :                             /* flat array, so force to expanded form */
     556            1703 :                             assign_simple_var(&estate, var,
     557                 :                                               expand_array(var->value,
     558                 :                                                            estate.datum_context,
     559                 :                                                            NULL),
     560                 :                                               false,
     561                 :                                               true);
     562                 :                         }
     563                 :                     }
     564                 :                 }
     565           39629 :                 break;
     566                 : 
     567             142 :             case PLPGSQL_DTYPE_REC:
     568                 :                 {
     569             142 :                     PLpgSQL_rec *rec = (PLpgSQL_rec *) estate.datums[n];
     570                 : 
     571             142 :                     if (!fcinfo->args[i].isnull)
     572                 :                     {
     573                 :                         /* Assign row value from composite datum */
     574             112 :                         exec_move_row_from_datum(&estate,
     575                 :                                                  (PLpgSQL_variable *) rec,
     576                 :                                                  fcinfo->args[i].value);
     577                 :                     }
     578                 :                     else
     579                 :                     {
     580                 :                         /* If arg is null, set variable to null */
     581              30 :                         exec_move_row(&estate, (PLpgSQL_variable *) rec,
     582                 :                                       NULL, NULL);
     583                 :                     }
     584                 :                     /* clean up after exec_move_row() */
     585             142 :                     exec_eval_cleanup(&estate);
     586                 :                 }
     587             142 :                 break;
     588                 : 
     589 UBC           0 :             default:
     590                 :                 /* Anything else should not be an argument variable */
     591               0 :                 elog(ERROR, "unrecognized dtype: %d", func->datums[i]->dtype);
     592                 :         }
     593                 :     }
     594                 : 
     595 CBC       32264 :     estate.err_text = gettext_noop("during function entry");
     596                 : 
     597                 :     /*
     598                 :      * Set the magic variable FOUND to false
     599                 :      */
     600           32264 :     exec_set_found(&estate, false);
     601                 : 
     602                 :     /*
     603                 :      * Let the instrumentation plugin peek at this function
     604                 :      */
     605           32264 :     if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_beg)
     606 UBC           0 :         ((*plpgsql_plugin_ptr)->func_beg) (&estate, func);
     607                 : 
     608                 :     /*
     609                 :      * Now call the toplevel block of statements
     610                 :      */
     611 CBC       32264 :     estate.err_text = NULL;
     612           32264 :     rc = exec_toplevel_block(&estate, func->action);
     613           31845 :     if (rc != PLPGSQL_RC_RETURN)
     614                 :     {
     615               3 :         estate.err_text = NULL;
     616               3 :         ereport(ERROR,
     617                 :                 (errcode(ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT),
     618                 :                  errmsg("control reached end of function without RETURN")));
     619                 :     }
     620                 : 
     621                 :     /*
     622                 :      * We got a return value - process it
     623                 :      */
     624           31842 :     estate.err_text = gettext_noop("while casting return value to function's return type");
     625                 : 
     626           31842 :     fcinfo->isnull = estate.retisnull;
     627                 : 
     628           31842 :     if (estate.retisset)
     629                 :     {
     630            1680 :         ReturnSetInfo *rsi = estate.rsi;
     631                 : 
     632                 :         /* Check caller can handle a set result */
     633            1680 :         if (!rsi || !IsA(rsi, ReturnSetInfo))
     634 UBC           0 :             ereport(ERROR,
     635                 :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     636                 :                      errmsg("set-valued function called in context that cannot accept a set")));
     637                 : 
     638 CBC        1680 :         if (!(rsi->allowedModes & SFRM_Materialize))
     639 UBC           0 :             ereport(ERROR,
     640                 :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     641                 :                      errmsg("materialize mode required, but it is not allowed in this context")));
     642                 : 
     643 CBC        1680 :         rsi->returnMode = SFRM_Materialize;
     644                 : 
     645                 :         /* If we produced any tuples, send back the result */
     646            1680 :         if (estate.tuple_store)
     647                 :         {
     648                 :             MemoryContext oldcxt;
     649                 : 
     650            1671 :             rsi->setResult = estate.tuple_store;
     651            1671 :             oldcxt = MemoryContextSwitchTo(estate.tuple_store_cxt);
     652            1671 :             rsi->setDesc = CreateTupleDescCopy(estate.tuple_store_desc);
     653            1671 :             MemoryContextSwitchTo(oldcxt);
     654                 :         }
     655            1680 :         estate.retval = (Datum) 0;
     656            1680 :         fcinfo->isnull = true;
     657                 :     }
     658           30162 :     else if (!estate.retisnull)
     659                 :     {
     660                 :         /*
     661                 :          * Cast result value to function's declared result type, and copy it
     662                 :          * out to the upper executor memory context.  We must treat tuple
     663                 :          * results specially in order to deal with cases like rowtypes
     664                 :          * involving dropped columns.
     665                 :          */
     666           29954 :         if (estate.retistuple)
     667                 :         {
     668                 :             /* Don't need coercion if rowtype is known to match */
     669            3214 :             if (func->fn_rettype == estate.rettype &&
     670            3183 :                 func->fn_rettype != RECORDOID)
     671                 :             {
     672                 :                 /*
     673                 :                  * Copy the tuple result into upper executor memory context.
     674                 :                  * However, if we have a R/W expanded datum, we can just
     675                 :                  * transfer its ownership out to the upper context.
     676                 :                  */
     677             109 :                 estate.retval = SPI_datumTransfer(estate.retval,
     678                 :                                                   false,
     679                 :                                                   -1);
     680                 :             }
     681                 :             else
     682                 :             {
     683                 :                 /*
     684                 :                  * Need to look up the expected result type.  XXX would be
     685                 :                  * better to cache the tupdesc instead of repeating
     686                 :                  * get_call_result_type(), but the only easy place to save it
     687                 :                  * is in the PLpgSQL_function struct, and that's too
     688                 :                  * long-lived: composite types could change during the
     689                 :                  * existence of a PLpgSQL_function.
     690                 :                  */
     691                 :                 Oid         resultTypeId;
     692                 :                 TupleDesc   tupdesc;
     693                 : 
     694            3105 :                 switch (get_call_result_type(fcinfo, &resultTypeId, &tupdesc))
     695                 :                 {
     696            3069 :                     case TYPEFUNC_COMPOSITE:
     697                 :                         /* got the expected result rowtype, now coerce it */
     698            3069 :                         coerce_function_result_tuple(&estate, tupdesc);
     699            3054 :                         break;
     700               8 :                     case TYPEFUNC_COMPOSITE_DOMAIN:
     701                 :                         /* got the expected result rowtype, now coerce it */
     702               8 :                         coerce_function_result_tuple(&estate, tupdesc);
     703                 :                         /* and check domain constraints */
     704                 :                         /* XXX allowing caching here would be good, too */
     705               8 :                         domain_check(estate.retval, false, resultTypeId,
     706                 :                                      NULL, NULL);
     707               4 :                         break;
     708              28 :                     case TYPEFUNC_RECORD:
     709                 : 
     710                 :                         /*
     711                 :                          * Failed to determine actual type of RECORD.  We
     712                 :                          * could raise an error here, but what this means in
     713                 :                          * practice is that the caller is expecting any old
     714                 :                          * generic rowtype, so we don't really need to be
     715                 :                          * restrictive.  Pass back the generated result as-is.
     716                 :                          */
     717              28 :                         estate.retval = SPI_datumTransfer(estate.retval,
     718                 :                                                           false,
     719                 :                                                           -1);
     720              28 :                         break;
     721 UBC           0 :                     default:
     722                 :                         /* shouldn't get here if retistuple is true ... */
     723               0 :                         elog(ERROR, "return type must be a row type");
     724                 :                         break;
     725                 :                 }
     726                 :             }
     727                 :         }
     728                 :         else
     729                 :         {
     730                 :             /* Scalar case: use exec_cast_value */
     731 CBC       26740 :             estate.retval = exec_cast_value(&estate,
     732                 :                                             estate.retval,
     733                 :                                             &fcinfo->isnull,
     734                 :                                             estate.rettype,
     735                 :                                             -1,
     736                 :                                             func->fn_rettype,
     737                 :                                             -1);
     738                 : 
     739                 :             /*
     740                 :              * If the function's return type isn't by value, copy the value
     741                 :              * into upper executor memory context.  However, if we have a R/W
     742                 :              * expanded datum, we can just transfer its ownership out to the
     743                 :              * upper executor context.
     744                 :              */
     745           26722 :             if (!fcinfo->isnull && !func->fn_retbyval)
     746            2589 :                 estate.retval = SPI_datumTransfer(estate.retval,
     747                 :                                                   false,
     748                 :                                                   func->fn_rettyplen);
     749                 :         }
     750                 :     }
     751                 :     else
     752                 :     {
     753                 :         /*
     754                 :          * We're returning a NULL, which normally requires no conversion work
     755                 :          * regardless of datatypes.  But, if we are casting it to a domain
     756                 :          * return type, we'd better check that the domain's constraints pass.
     757                 :          */
     758             208 :         if (func->fn_retisdomain)
     759               2 :             estate.retval = exec_cast_value(&estate,
     760                 :                                             estate.retval,
     761                 :                                             &fcinfo->isnull,
     762                 :                                             estate.rettype,
     763                 :                                             -1,
     764                 :                                             func->fn_rettype,
     765                 :                                             -1);
     766                 :     }
     767                 : 
     768           31804 :     estate.err_text = gettext_noop("during function exit");
     769                 : 
     770                 :     /*
     771                 :      * Let the instrumentation plugin peek at this function
     772                 :      */
     773           31804 :     if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_end)
     774 UBC           0 :         ((*plpgsql_plugin_ptr)->func_end) (&estate, func);
     775                 : 
     776                 :     /* Clean up any leftover temporary memory */
     777 CBC       31804 :     plpgsql_destroy_econtext(&estate);
     778           31804 :     exec_eval_cleanup(&estate);
     779                 :     /* stmt_mcontext will be destroyed when function's main context is */
     780                 : 
     781                 :     /*
     782                 :      * Pop the error context stack
     783                 :      */
     784           31804 :     error_context_stack = plerrcontext.previous;
     785                 : 
     786                 :     /*
     787                 :      * Return the function's result
     788                 :      */
     789           31804 :     return estate.retval;
     790                 : }
     791                 : 
     792                 : /*
     793                 :  * Helper for plpgsql_exec_function: coerce composite result to the specified
     794                 :  * tuple descriptor, and copy it out to upper executor memory.  This is split
     795                 :  * out mostly for cosmetic reasons --- the logic would be very deeply nested
     796                 :  * otherwise.
     797                 :  *
     798                 :  * estate->retval is updated in-place.
     799                 :  */
     800                 : static void
     801            3077 : coerce_function_result_tuple(PLpgSQL_execstate *estate, TupleDesc tupdesc)
     802                 : {
     803                 :     HeapTuple   rettup;
     804                 :     TupleDesc   retdesc;
     805                 :     TupleConversionMap *tupmap;
     806                 : 
     807                 :     /* We assume exec_stmt_return verified that result is composite */
     808            3077 :     Assert(type_is_rowtype(estate->rettype));
     809                 : 
     810                 :     /* We can special-case expanded records for speed */
     811            3077 :     if (VARATT_IS_EXTERNAL_EXPANDED(DatumGetPointer(estate->retval)))
     812              17 :     {
     813              23 :         ExpandedRecordHeader *erh = (ExpandedRecordHeader *) DatumGetEOHP(estate->retval);
     814                 : 
     815              23 :         Assert(erh->er_magic == ER_MAGIC);
     816                 : 
     817                 :         /* Extract record's TupleDesc */
     818              23 :         retdesc = expanded_record_get_tupdesc(erh);
     819                 : 
     820                 :         /* check rowtype compatibility */
     821              23 :         tupmap = convert_tuples_by_position(retdesc,
     822                 :                                             tupdesc,
     823                 :                                             gettext_noop("returned record type does not match expected record type"));
     824                 : 
     825                 :         /* it might need conversion */
     826              17 :         if (tupmap)
     827                 :         {
     828               1 :             rettup = expanded_record_get_tuple(erh);
     829               1 :             Assert(rettup);
     830               1 :             rettup = execute_attr_map_tuple(rettup, tupmap);
     831                 : 
     832                 :             /*
     833                 :              * Copy tuple to upper executor memory, as a tuple Datum.  Make
     834                 :              * sure it is labeled with the caller-supplied tuple type.
     835                 :              */
     836               1 :             estate->retval = PointerGetDatum(SPI_returntuple(rettup, tupdesc));
     837                 :             /* no need to free map, we're about to return anyway */
     838                 :         }
     839              16 :         else if (!(tupdesc->tdtypeid == erh->er_decltypeid ||
     840               7 :                    (tupdesc->tdtypeid == RECORDOID &&
     841 UBC           0 :                     !ExpandedRecordIsDomain(erh))))
     842 CBC           7 :         {
     843                 :             /*
     844                 :              * The expanded record has the right physical tupdesc, but the
     845                 :              * wrong type ID.  (Typically, the expanded record is RECORDOID
     846                 :              * but the function is declared to return a named composite type.
     847                 :              * As in exec_move_row_from_datum, we don't allow returning a
     848                 :              * composite-domain record from a function declared to return
     849                 :              * RECORD.)  So we must flatten the record to a tuple datum and
     850                 :              * overwrite its type fields with the right thing.  spi.c doesn't
     851                 :              * provide any easy way to deal with this case, so we end up
     852                 :              * duplicating the guts of datumCopy() :-(
     853                 :              */
     854                 :             Size        resultsize;
     855                 :             HeapTupleHeader tuphdr;
     856                 : 
     857               7 :             resultsize = EOH_get_flat_size(&erh->hdr);
     858               7 :             tuphdr = (HeapTupleHeader) SPI_palloc(resultsize);
     859               7 :             EOH_flatten_into(&erh->hdr, (void *) tuphdr, resultsize);
     860               7 :             HeapTupleHeaderSetTypeId(tuphdr, tupdesc->tdtypeid);
     861               7 :             HeapTupleHeaderSetTypMod(tuphdr, tupdesc->tdtypmod);
     862               7 :             estate->retval = PointerGetDatum(tuphdr);
     863                 :         }
     864                 :         else
     865                 :         {
     866                 :             /*
     867                 :              * We need only copy result into upper executor memory context.
     868                 :              * However, if we have a R/W expanded datum, we can just transfer
     869                 :              * its ownership out to the upper executor context.
     870                 :              */
     871               9 :             estate->retval = SPI_datumTransfer(estate->retval,
     872                 :                                                false,
     873                 :                                                -1);
     874                 :         }
     875                 :     }
     876                 :     else
     877                 :     {
     878                 :         /* Convert composite datum to a HeapTuple and TupleDesc */
     879                 :         HeapTupleData tmptup;
     880                 : 
     881            3054 :         retdesc = deconstruct_composite_datum(estate->retval, &tmptup);
     882            3054 :         rettup = &tmptup;
     883                 : 
     884                 :         /* check rowtype compatibility */
     885            3054 :         tupmap = convert_tuples_by_position(retdesc,
     886                 :                                             tupdesc,
     887                 :                                             gettext_noop("returned record type does not match expected record type"));
     888                 : 
     889                 :         /* it might need conversion */
     890            3045 :         if (tupmap)
     891               1 :             rettup = execute_attr_map_tuple(rettup, tupmap);
     892                 : 
     893                 :         /*
     894                 :          * Copy tuple to upper executor memory, as a tuple Datum.  Make sure
     895                 :          * it is labeled with the caller-supplied tuple type.
     896                 :          */
     897            3045 :         estate->retval = PointerGetDatum(SPI_returntuple(rettup, tupdesc));
     898                 : 
     899                 :         /* no need to free map, we're about to return anyway */
     900                 : 
     901            3045 :         ReleaseTupleDesc(retdesc);
     902                 :     }
     903            3062 : }
     904                 : 
     905                 : 
     906                 : /* ----------
     907                 :  * plpgsql_exec_trigger     Called by the call handler for
     908                 :  *              trigger execution.
     909                 :  * ----------
     910                 :  */
     911                 : HeapTuple
     912            7291 : plpgsql_exec_trigger(PLpgSQL_function *func,
     913                 :                      TriggerData *trigdata)
     914                 : {
     915                 :     PLpgSQL_execstate estate;
     916                 :     ErrorContextCallback plerrcontext;
     917                 :     int         rc;
     918                 :     TupleDesc   tupdesc;
     919                 :     PLpgSQL_rec *rec_new,
     920                 :                *rec_old;
     921                 :     HeapTuple   rettup;
     922                 : 
     923                 :     /*
     924                 :      * Setup the execution state
     925                 :      */
     926            7291 :     plpgsql_estate_setup(&estate, func, NULL, NULL, NULL);
     927            7291 :     estate.trigdata = trigdata;
     928                 : 
     929                 :     /*
     930                 :      * Setup error traceback support for ereport()
     931                 :      */
     932            7291 :     plerrcontext.callback = plpgsql_exec_error_callback;
     933            7291 :     plerrcontext.arg = &estate;
     934            7291 :     plerrcontext.previous = error_context_stack;
     935            7291 :     error_context_stack = &plerrcontext;
     936                 : 
     937                 :     /*
     938                 :      * Make local execution copies of all the datums
     939                 :      */
     940            7291 :     estate.err_text = gettext_noop("during initialization of execution state");
     941            7291 :     copy_plpgsql_datums(&estate, func);
     942                 : 
     943                 :     /*
     944                 :      * Put the OLD and NEW tuples into record variables
     945                 :      *
     946                 :      * We set up expanded records for both variables even though only one may
     947                 :      * have a value.  This allows record references to succeed in functions
     948                 :      * that are used for multiple trigger types.  For example, we might have a
     949                 :      * test like "if (TG_OP = 'INSERT' and NEW.foo = 'xyz')", which should
     950                 :      * work regardless of the current trigger type.  If a value is actually
     951                 :      * fetched from an unsupplied tuple, it will read as NULL.
     952                 :      */
     953            7291 :     tupdesc = RelationGetDescr(trigdata->tg_relation);
     954                 : 
     955            7291 :     rec_new = (PLpgSQL_rec *) (estate.datums[func->new_varno]);
     956            7291 :     rec_old = (PLpgSQL_rec *) (estate.datums[func->old_varno]);
     957                 : 
     958            7291 :     rec_new->erh = make_expanded_record_from_tupdesc(tupdesc,
     959                 :                                                      estate.datum_context);
     960            7291 :     rec_old->erh = make_expanded_record_from_exprecord(rec_new->erh,
     961                 :                                                        estate.datum_context);
     962                 : 
     963            7291 :     if (!TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
     964                 :     {
     965                 :         /*
     966                 :          * Per-statement triggers don't use OLD/NEW variables
     967                 :          */
     968                 :     }
     969            6614 :     else if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
     970                 :     {
     971            3341 :         expanded_record_set_tuple(rec_new->erh, trigdata->tg_trigtuple,
     972                 :                                   false, false);
     973                 :     }
     974            3273 :     else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
     975                 :     {
     976            3072 :         expanded_record_set_tuple(rec_new->erh, trigdata->tg_newtuple,
     977                 :                                   false, false);
     978            3072 :         expanded_record_set_tuple(rec_old->erh, trigdata->tg_trigtuple,
     979                 :                                   false, false);
     980                 : 
     981                 :         /*
     982                 :          * In BEFORE trigger, stored generated columns are not computed yet,
     983                 :          * so make them null in the NEW row.  (Only needed in UPDATE branch;
     984                 :          * in the INSERT case, they are already null, but in UPDATE, the field
     985                 :          * still contains the old value.)  Alternatively, we could construct a
     986                 :          * whole new row structure without the generated columns, but this way
     987                 :          * seems more efficient and potentially less confusing.
     988                 :          */
     989            3072 :         if (tupdesc->constr && tupdesc->constr->has_generated_stored &&
     990              21 :             TRIGGER_FIRED_BEFORE(trigdata->tg_event))
     991                 :         {
     992              45 :             for (int i = 0; i < tupdesc->natts; i++)
     993              30 :                 if (TupleDescAttr(tupdesc, i)->attgenerated == ATTRIBUTE_GENERATED_STORED)
     994              15 :                     expanded_record_set_field_internal(rec_new->erh,
     995                 :                                                        i + 1,
     996                 :                                                        (Datum) 0,
     997                 :                                                        true,    /* isnull */
     998                 :                                                        false, false);
     999                 :         }
    1000                 :     }
    1001             201 :     else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event))
    1002                 :     {
    1003             201 :         expanded_record_set_tuple(rec_old->erh, trigdata->tg_trigtuple,
    1004                 :                                   false, false);
    1005                 :     }
    1006                 :     else
    1007 UBC           0 :         elog(ERROR, "unrecognized trigger action: not INSERT, DELETE, or UPDATE");
    1008                 : 
    1009                 :     /* Make transition tables visible to this SPI connection */
    1010 CBC        7291 :     rc = SPI_register_trigger_data(trigdata);
    1011            7291 :     Assert(rc >= 0);
    1012                 : 
    1013            7291 :     estate.err_text = gettext_noop("during function entry");
    1014                 : 
    1015                 :     /*
    1016                 :      * Set the magic variable FOUND to false
    1017                 :      */
    1018            7291 :     exec_set_found(&estate, false);
    1019                 : 
    1020                 :     /*
    1021                 :      * Let the instrumentation plugin peek at this function
    1022                 :      */
    1023            7291 :     if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_beg)
    1024 UBC           0 :         ((*plpgsql_plugin_ptr)->func_beg) (&estate, func);
    1025                 : 
    1026                 :     /*
    1027                 :      * Now call the toplevel block of statements
    1028                 :      */
    1029 CBC        7291 :     estate.err_text = NULL;
    1030            7291 :     rc = exec_toplevel_block(&estate, func->action);
    1031            7196 :     if (rc != PLPGSQL_RC_RETURN)
    1032                 :     {
    1033 UBC           0 :         estate.err_text = NULL;
    1034               0 :         ereport(ERROR,
    1035                 :                 (errcode(ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT),
    1036                 :                  errmsg("control reached end of trigger procedure without RETURN")));
    1037                 :     }
    1038                 : 
    1039 CBC        7196 :     estate.err_text = gettext_noop("during function exit");
    1040                 : 
    1041            7196 :     if (estate.retisset)
    1042 UBC           0 :         ereport(ERROR,
    1043                 :                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    1044                 :                  errmsg("trigger procedure cannot return a set")));
    1045                 : 
    1046                 :     /*
    1047                 :      * Check that the returned tuple structure has the same attributes, the
    1048                 :      * relation that fired the trigger has. A per-statement trigger always
    1049                 :      * needs to return NULL, so we ignore any return value the function itself
    1050                 :      * produces (XXX: is this a good idea?)
    1051                 :      *
    1052                 :      * XXX This way it is possible, that the trigger returns a tuple where
    1053                 :      * attributes don't have the correct atttypmod's length. It's up to the
    1054                 :      * trigger's programmer to ensure that this doesn't happen. Jan
    1055                 :      */
    1056 CBC        7196 :     if (estate.retisnull || !TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
    1057            1238 :         rettup = NULL;
    1058                 :     else
    1059                 :     {
    1060                 :         TupleDesc   retdesc;
    1061                 :         TupleConversionMap *tupmap;
    1062                 : 
    1063                 :         /* We assume exec_stmt_return verified that result is composite */
    1064            5958 :         Assert(type_is_rowtype(estate.rettype));
    1065                 : 
    1066                 :         /* We can special-case expanded records for speed */
    1067            5958 :         if (VARATT_IS_EXTERNAL_EXPANDED(DatumGetPointer(estate.retval)))
    1068            5956 :         {
    1069            5956 :             ExpandedRecordHeader *erh = (ExpandedRecordHeader *) DatumGetEOHP(estate.retval);
    1070                 : 
    1071            5956 :             Assert(erh->er_magic == ER_MAGIC);
    1072                 : 
    1073                 :             /* Extract HeapTuple and TupleDesc */
    1074            5956 :             rettup = expanded_record_get_tuple(erh);
    1075            5956 :             Assert(rettup);
    1076            5956 :             retdesc = expanded_record_get_tupdesc(erh);
    1077                 : 
    1078            5956 :             if (retdesc != RelationGetDescr(trigdata->tg_relation))
    1079                 :             {
    1080                 :                 /* check rowtype compatibility */
    1081               2 :                 tupmap = convert_tuples_by_position(retdesc,
    1082               2 :                                                     RelationGetDescr(trigdata->tg_relation),
    1083                 :                                                     gettext_noop("returned row structure does not match the structure of the triggering table"));
    1084                 :                 /* it might need conversion */
    1085               2 :                 if (tupmap)
    1086               2 :                     rettup = execute_attr_map_tuple(rettup, tupmap);
    1087                 :                 /* no need to free map, we're about to return anyway */
    1088                 :             }
    1089                 : 
    1090                 :             /*
    1091                 :              * Copy tuple to upper executor memory.  But if user just did
    1092                 :              * "return new" or "return old" without changing anything, there's
    1093                 :              * no need to copy; we can return the original tuple (which will
    1094                 :              * save a few cycles in trigger.c as well as here).
    1095                 :              */
    1096            5956 :             if (rettup != trigdata->tg_newtuple &&
    1097            3772 :                 rettup != trigdata->tg_trigtuple)
    1098            1016 :                 rettup = SPI_copytuple(rettup);
    1099                 :         }
    1100                 :         else
    1101                 :         {
    1102                 :             /* Convert composite datum to a HeapTuple and TupleDesc */
    1103                 :             HeapTupleData tmptup;
    1104                 : 
    1105               2 :             retdesc = deconstruct_composite_datum(estate.retval, &tmptup);
    1106               2 :             rettup = &tmptup;
    1107                 : 
    1108                 :             /* check rowtype compatibility */
    1109               2 :             tupmap = convert_tuples_by_position(retdesc,
    1110               2 :                                                 RelationGetDescr(trigdata->tg_relation),
    1111                 :                                                 gettext_noop("returned row structure does not match the structure of the triggering table"));
    1112                 :             /* it might need conversion */
    1113               2 :             if (tupmap)
    1114               2 :                 rettup = execute_attr_map_tuple(rettup, tupmap);
    1115                 : 
    1116               2 :             ReleaseTupleDesc(retdesc);
    1117                 :             /* no need to free map, we're about to return anyway */
    1118                 : 
    1119                 :             /* Copy tuple to upper executor memory */
    1120               2 :             rettup = SPI_copytuple(rettup);
    1121                 :         }
    1122                 :     }
    1123                 : 
    1124                 :     /*
    1125                 :      * Let the instrumentation plugin peek at this function
    1126                 :      */
    1127            7196 :     if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_end)
    1128 UBC           0 :         ((*plpgsql_plugin_ptr)->func_end) (&estate, func);
    1129                 : 
    1130                 :     /* Clean up any leftover temporary memory */
    1131 CBC        7196 :     plpgsql_destroy_econtext(&estate);
    1132            7196 :     exec_eval_cleanup(&estate);
    1133                 :     /* stmt_mcontext will be destroyed when function's main context is */
    1134                 : 
    1135                 :     /*
    1136                 :      * Pop the error context stack
    1137                 :      */
    1138            7196 :     error_context_stack = plerrcontext.previous;
    1139                 : 
    1140                 :     /*
    1141                 :      * Return the trigger's result
    1142                 :      */
    1143            7196 :     return rettup;
    1144                 : }
    1145                 : 
    1146                 : /* ----------
    1147                 :  * plpgsql_exec_event_trigger       Called by the call handler for
    1148                 :  *              event trigger execution.
    1149                 :  * ----------
    1150                 :  */
    1151                 : void
    1152             523 : plpgsql_exec_event_trigger(PLpgSQL_function *func, EventTriggerData *trigdata)
    1153                 : {
    1154                 :     PLpgSQL_execstate estate;
    1155                 :     ErrorContextCallback plerrcontext;
    1156                 :     int         rc;
    1157                 : 
    1158                 :     /*
    1159                 :      * Setup the execution state
    1160                 :      */
    1161             523 :     plpgsql_estate_setup(&estate, func, NULL, NULL, NULL);
    1162             523 :     estate.evtrigdata = trigdata;
    1163                 : 
    1164                 :     /*
    1165                 :      * Setup error traceback support for ereport()
    1166                 :      */
    1167             523 :     plerrcontext.callback = plpgsql_exec_error_callback;
    1168             523 :     plerrcontext.arg = &estate;
    1169             523 :     plerrcontext.previous = error_context_stack;
    1170             523 :     error_context_stack = &plerrcontext;
    1171                 : 
    1172                 :     /*
    1173                 :      * Make local execution copies of all the datums
    1174                 :      */
    1175             523 :     estate.err_text = gettext_noop("during initialization of execution state");
    1176             523 :     copy_plpgsql_datums(&estate, func);
    1177                 : 
    1178                 :     /*
    1179                 :      * Let the instrumentation plugin peek at this function
    1180                 :      */
    1181             523 :     if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_beg)
    1182 UBC           0 :         ((*plpgsql_plugin_ptr)->func_beg) (&estate, func);
    1183                 : 
    1184                 :     /*
    1185                 :      * Now call the toplevel block of statements
    1186                 :      */
    1187 CBC         523 :     estate.err_text = NULL;
    1188             523 :     rc = exec_toplevel_block(&estate, func->action);
    1189             511 :     if (rc != PLPGSQL_RC_RETURN)
    1190                 :     {
    1191 UBC           0 :         estate.err_text = NULL;
    1192               0 :         ereport(ERROR,
    1193                 :                 (errcode(ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT),
    1194                 :                  errmsg("control reached end of trigger procedure without RETURN")));
    1195                 :     }
    1196                 : 
    1197 CBC         511 :     estate.err_text = gettext_noop("during function exit");
    1198                 : 
    1199                 :     /*
    1200                 :      * Let the instrumentation plugin peek at this function
    1201                 :      */
    1202             511 :     if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_end)
    1203 UBC           0 :         ((*plpgsql_plugin_ptr)->func_end) (&estate, func);
    1204                 : 
    1205                 :     /* Clean up any leftover temporary memory */
    1206 CBC         511 :     plpgsql_destroy_econtext(&estate);
    1207             511 :     exec_eval_cleanup(&estate);
    1208                 :     /* stmt_mcontext will be destroyed when function's main context is */
    1209                 : 
    1210                 :     /*
    1211                 :      * Pop the error context stack
    1212                 :      */
    1213             511 :     error_context_stack = plerrcontext.previous;
    1214             511 : }
    1215                 : 
    1216                 : /*
    1217                 :  * error context callback to let us supply a call-stack traceback
    1218                 :  */
    1219                 : static void
    1220           10490 : plpgsql_exec_error_callback(void *arg)
    1221                 : {
    1222           10490 :     PLpgSQL_execstate *estate = (PLpgSQL_execstate *) arg;
    1223                 :     int         err_lineno;
    1224                 : 
    1225                 :     /*
    1226                 :      * If err_var is set, report the variable's declaration line number.
    1227                 :      * Otherwise, if err_stmt is set, report the err_stmt's line number.  When
    1228                 :      * err_stmt is not set, we're in function entry/exit, or some such place
    1229                 :      * not attached to a specific line number.
    1230                 :      */
    1231           10490 :     if (estate->err_var != NULL)
    1232              30 :         err_lineno = estate->err_var->lineno;
    1233           10460 :     else if (estate->err_stmt != NULL)
    1234           10419 :         err_lineno = estate->err_stmt->lineno;
    1235                 :     else
    1236              41 :         err_lineno = 0;
    1237                 : 
    1238           10490 :     if (estate->err_text != NULL)
    1239                 :     {
    1240                 :         /*
    1241                 :          * We don't expend the cycles to run gettext() on err_text unless we
    1242                 :          * actually need it.  Therefore, places that set up err_text should
    1243                 :          * use gettext_noop() to ensure the strings get recorded in the
    1244                 :          * message dictionary.
    1245                 :          */
    1246              69 :         if (err_lineno > 0)
    1247                 :         {
    1248                 :             /*
    1249                 :              * translator: last %s is a phrase such as "during statement block
    1250                 :              * local variable initialization"
    1251                 :              */
    1252              31 :             errcontext("PL/pgSQL function %s line %d %s",
    1253              31 :                        estate->func->fn_signature,
    1254                 :                        err_lineno,
    1255                 :                        _(estate->err_text));
    1256                 :         }
    1257                 :         else
    1258                 :         {
    1259                 :             /*
    1260                 :              * translator: last %s is a phrase such as "while storing call
    1261                 :              * arguments into local variables"
    1262                 :              */
    1263              38 :             errcontext("PL/pgSQL function %s %s",
    1264              38 :                        estate->func->fn_signature,
    1265                 :                        _(estate->err_text));
    1266                 :         }
    1267                 :     }
    1268           10421 :     else if (estate->err_stmt != NULL && err_lineno > 0)
    1269                 :     {
    1270                 :         /* translator: last %s is a plpgsql statement type name */
    1271           10418 :         errcontext("PL/pgSQL function %s line %d at %s",
    1272           10418 :                    estate->func->fn_signature,
    1273                 :                    err_lineno,
    1274                 :                    plpgsql_stmt_typename(estate->err_stmt));
    1275                 :     }
    1276                 :     else
    1277               3 :         errcontext("PL/pgSQL function %s",
    1278               3 :                    estate->func->fn_signature);
    1279           10490 : }
    1280                 : 
    1281                 : 
    1282                 : /* ----------
    1283                 :  * Support function for initializing local execution variables
    1284                 :  * ----------
    1285                 :  */
    1286                 : static void
    1287           40078 : copy_plpgsql_datums(PLpgSQL_execstate *estate,
    1288                 :                     PLpgSQL_function *func)
    1289                 : {
    1290           40078 :     int         ndatums = estate->ndatums;
    1291                 :     PLpgSQL_datum **indatums;
    1292                 :     PLpgSQL_datum **outdatums;
    1293                 :     char       *workspace;
    1294                 :     char       *ws_next;
    1295                 :     int         i;
    1296                 : 
    1297                 :     /* Allocate local datum-pointer array */
    1298           40078 :     estate->datums = (PLpgSQL_datum **)
    1299           40078 :         palloc(sizeof(PLpgSQL_datum *) * ndatums);
    1300                 : 
    1301                 :     /*
    1302                 :      * To reduce palloc overhead, we make a single palloc request for all the
    1303                 :      * space needed for locally-instantiated datums.
    1304                 :      */
    1305           40078 :     workspace = palloc(func->copiable_size);
    1306           40078 :     ws_next = workspace;
    1307                 : 
    1308                 :     /* Fill datum-pointer array, copying datums into workspace as needed */
    1309           40078 :     indatums = func->datums;
    1310           40078 :     outdatums = estate->datums;
    1311          273463 :     for (i = 0; i < ndatums; i++)
    1312                 :     {
    1313          233385 :         PLpgSQL_datum *indatum = indatums[i];
    1314                 :         PLpgSQL_datum *outdatum;
    1315                 : 
    1316                 :         /* This must agree with plpgsql_finish_datums on what is copiable */
    1317          233385 :         switch (indatum->dtype)
    1318                 :         {
    1319          187243 :             case PLPGSQL_DTYPE_VAR:
    1320                 :             case PLPGSQL_DTYPE_PROMISE:
    1321          187243 :                 outdatum = (PLpgSQL_datum *) ws_next;
    1322          187243 :                 memcpy(outdatum, indatum, sizeof(PLpgSQL_var));
    1323          187243 :                 ws_next += MAXALIGN(sizeof(PLpgSQL_var));
    1324          187243 :                 break;
    1325                 : 
    1326           17269 :             case PLPGSQL_DTYPE_REC:
    1327           17269 :                 outdatum = (PLpgSQL_datum *) ws_next;
    1328           17269 :                 memcpy(outdatum, indatum, sizeof(PLpgSQL_rec));
    1329           17269 :                 ws_next += MAXALIGN(sizeof(PLpgSQL_rec));
    1330           17269 :                 break;
    1331                 : 
    1332           28873 :             case PLPGSQL_DTYPE_ROW:
    1333                 :             case PLPGSQL_DTYPE_RECFIELD:
    1334                 : 
    1335                 :                 /*
    1336                 :                  * These datum records are read-only at runtime, so no need to
    1337                 :                  * copy them (well, RECFIELD contains cached data, but we'd
    1338                 :                  * just as soon centralize the caching anyway).
    1339                 :                  */
    1340           28873 :                 outdatum = indatum;
    1341           28873 :                 break;
    1342                 : 
    1343 UBC           0 :             default:
    1344               0 :                 elog(ERROR, "unrecognized dtype: %d", indatum->dtype);
    1345                 :                 outdatum = NULL;    /* keep compiler quiet */
    1346                 :                 break;
    1347                 :         }
    1348                 : 
    1349 CBC      233385 :         outdatums[i] = outdatum;
    1350                 :     }
    1351                 : 
    1352           40078 :     Assert(ws_next == workspace + func->copiable_size);
    1353           40078 : }
    1354                 : 
    1355                 : /*
    1356                 :  * If the variable has an armed "promise", compute the promised value
    1357                 :  * and assign it to the variable.
    1358                 :  * The assignment automatically disarms the promise.
    1359                 :  */
    1360                 : static void
    1361           10456 : plpgsql_fulfill_promise(PLpgSQL_execstate *estate,
    1362                 :                         PLpgSQL_var *var)
    1363                 : {
    1364                 :     MemoryContext oldcontext;
    1365                 : 
    1366           10456 :     if (var->promise == PLPGSQL_PROMISE_NONE)
    1367            3082 :         return;                 /* nothing to do */
    1368                 : 
    1369                 :     /*
    1370                 :      * This will typically be invoked in a short-lived context such as the
    1371                 :      * mcontext.  We must create variable values in the estate's datum
    1372                 :      * context.  This quick-and-dirty solution risks leaking some additional
    1373                 :      * cruft there, but since any one promise is honored at most once per
    1374                 :      * function call, it's probably not worth being more careful.
    1375                 :      */
    1376            7374 :     oldcontext = MemoryContextSwitchTo(estate->datum_context);
    1377                 : 
    1378            7374 :     switch (var->promise)
    1379                 :     {
    1380             692 :         case PLPGSQL_PROMISE_TG_NAME:
    1381             692 :             if (estate->trigdata == NULL)
    1382 UBC           0 :                 elog(ERROR, "trigger promise is not in a trigger function");
    1383 CBC         692 :             assign_simple_var(estate, var,
    1384             692 :                               DirectFunctionCall1(namein,
    1385                 :                                                   CStringGetDatum(estate->trigdata->tg_trigger->tgname)),
    1386                 :                               false, true);
    1387             692 :             break;
    1388                 : 
    1389            1099 :         case PLPGSQL_PROMISE_TG_WHEN:
    1390            1099 :             if (estate->trigdata == NULL)
    1391 UBC           0 :                 elog(ERROR, "trigger promise is not in a trigger function");
    1392 CBC        1099 :             if (TRIGGER_FIRED_BEFORE(estate->trigdata->tg_event))
    1393             439 :                 assign_text_var(estate, var, "BEFORE");
    1394             660 :             else if (TRIGGER_FIRED_AFTER(estate->trigdata->tg_event))
    1395             630 :                 assign_text_var(estate, var, "AFTER");
    1396              30 :             else if (TRIGGER_FIRED_INSTEAD(estate->trigdata->tg_event))
    1397              30 :                 assign_text_var(estate, var, "INSTEAD OF");
    1398                 :             else
    1399 UBC           0 :                 elog(ERROR, "unrecognized trigger execution time: not BEFORE, AFTER, or INSTEAD OF");
    1400 CBC        1099 :             break;
    1401                 : 
    1402            1052 :         case PLPGSQL_PROMISE_TG_LEVEL:
    1403            1052 :             if (estate->trigdata == NULL)
    1404 UBC           0 :                 elog(ERROR, "trigger promise is not in a trigger function");
    1405 CBC        1052 :             if (TRIGGER_FIRED_FOR_ROW(estate->trigdata->tg_event))
    1406             674 :                 assign_text_var(estate, var, "ROW");
    1407             378 :             else if (TRIGGER_FIRED_FOR_STATEMENT(estate->trigdata->tg_event))
    1408             378 :                 assign_text_var(estate, var, "STATEMENT");
    1409                 :             else
    1410 UBC           0 :                 elog(ERROR, "unrecognized trigger event type: not ROW or STATEMENT");
    1411 CBC        1052 :             break;
    1412                 : 
    1413            2855 :         case PLPGSQL_PROMISE_TG_OP:
    1414            2855 :             if (estate->trigdata == NULL)
    1415 UBC           0 :                 elog(ERROR, "trigger promise is not in a trigger function");
    1416 CBC        2855 :             if (TRIGGER_FIRED_BY_INSERT(estate->trigdata->tg_event))
    1417            1380 :                 assign_text_var(estate, var, "INSERT");
    1418            1475 :             else if (TRIGGER_FIRED_BY_UPDATE(estate->trigdata->tg_event))
    1419            1282 :                 assign_text_var(estate, var, "UPDATE");
    1420             193 :             else if (TRIGGER_FIRED_BY_DELETE(estate->trigdata->tg_event))
    1421             185 :                 assign_text_var(estate, var, "DELETE");
    1422               8 :             else if (TRIGGER_FIRED_BY_TRUNCATE(estate->trigdata->tg_event))
    1423               8 :                 assign_text_var(estate, var, "TRUNCATE");
    1424                 :             else
    1425 UBC           0 :                 elog(ERROR, "unrecognized trigger action: not INSERT, DELETE, UPDATE, or TRUNCATE");
    1426 CBC        2855 :             break;
    1427                 : 
    1428              61 :         case PLPGSQL_PROMISE_TG_RELID:
    1429              61 :             if (estate->trigdata == NULL)
    1430 UBC           0 :                 elog(ERROR, "trigger promise is not in a trigger function");
    1431 CBC          61 :             assign_simple_var(estate, var,
    1432              61 :                               ObjectIdGetDatum(estate->trigdata->tg_relation->rd_id),
    1433                 :                               false, false);
    1434              61 :             break;
    1435                 : 
    1436             400 :         case PLPGSQL_PROMISE_TG_TABLE_NAME:
    1437             400 :             if (estate->trigdata == NULL)
    1438 UBC           0 :                 elog(ERROR, "trigger promise is not in a trigger function");
    1439 CBC         400 :             assign_simple_var(estate, var,
    1440             400 :                               DirectFunctionCall1(namein,
    1441                 :                                                   CStringGetDatum(RelationGetRelationName(estate->trigdata->tg_relation))),
    1442                 :                               false, true);
    1443             400 :             break;
    1444                 : 
    1445               9 :         case PLPGSQL_PROMISE_TG_TABLE_SCHEMA:
    1446               9 :             if (estate->trigdata == NULL)
    1447 UBC           0 :                 elog(ERROR, "trigger promise is not in a trigger function");
    1448 CBC           9 :             assign_simple_var(estate, var,
    1449               9 :                               DirectFunctionCall1(namein,
    1450                 :                                                   CStringGetDatum(get_namespace_name(RelationGetNamespace(estate->trigdata->tg_relation)))),
    1451                 :                               false, true);
    1452               9 :             break;
    1453                 : 
    1454             145 :         case PLPGSQL_PROMISE_TG_NARGS:
    1455             145 :             if (estate->trigdata == NULL)
    1456 UBC           0 :                 elog(ERROR, "trigger promise is not in a trigger function");
    1457 CBC         145 :             assign_simple_var(estate, var,
    1458             145 :                               Int16GetDatum(estate->trigdata->tg_trigger->tgnargs),
    1459                 :                               false, false);
    1460             145 :             break;
    1461                 : 
    1462             862 :         case PLPGSQL_PROMISE_TG_ARGV:
    1463             862 :             if (estate->trigdata == NULL)
    1464 UBC           0 :                 elog(ERROR, "trigger promise is not in a trigger function");
    1465 CBC         862 :             if (estate->trigdata->tg_trigger->tgnargs > 0)
    1466                 :             {
    1467                 :                 /*
    1468                 :                  * For historical reasons, tg_argv[] subscripts start at zero
    1469                 :                  * not one.  So we can't use construct_array().
    1470                 :                  */
    1471             850 :                 int         nelems = estate->trigdata->tg_trigger->tgnargs;
    1472                 :                 Datum      *elems;
    1473                 :                 int         dims[1];
    1474                 :                 int         lbs[1];
    1475                 :                 int         i;
    1476                 : 
    1477             850 :                 elems = palloc(sizeof(Datum) * nelems);
    1478            1770 :                 for (i = 0; i < nelems; i++)
    1479             920 :                     elems[i] = CStringGetTextDatum(estate->trigdata->tg_trigger->tgargs[i]);
    1480             850 :                 dims[0] = nelems;
    1481             850 :                 lbs[0] = 0;
    1482                 : 
    1483             850 :                 assign_simple_var(estate, var,
    1484             850 :                                   PointerGetDatum(construct_md_array(elems, NULL,
    1485                 :                                                                      1, dims, lbs,
    1486                 :                                                                      TEXTOID,
    1487                 :                                                                      -1, false, TYPALIGN_INT)),
    1488                 :                                   false, true);
    1489                 :             }
    1490                 :             else
    1491                 :             {
    1492              12 :                 assign_simple_var(estate, var, (Datum) 0, true, false);
    1493                 :             }
    1494             862 :             break;
    1495                 : 
    1496              86 :         case PLPGSQL_PROMISE_TG_EVENT:
    1497              86 :             if (estate->evtrigdata == NULL)
    1498 UBC           0 :                 elog(ERROR, "event trigger promise is not in an event trigger function");
    1499 CBC          86 :             assign_text_var(estate, var, estate->evtrigdata->event);
    1500              86 :             break;
    1501                 : 
    1502             113 :         case PLPGSQL_PROMISE_TG_TAG:
    1503             113 :             if (estate->evtrigdata == NULL)
    1504 UBC           0 :                 elog(ERROR, "event trigger promise is not in an event trigger function");
    1505 CBC         113 :             assign_text_var(estate, var, GetCommandTagName(estate->evtrigdata->tag));
    1506             113 :             break;
    1507                 : 
    1508 UBC           0 :         default:
    1509               0 :             elog(ERROR, "unrecognized promise type: %d", var->promise);
    1510                 :     }
    1511                 : 
    1512 CBC        7374 :     MemoryContextSwitchTo(oldcontext);
    1513                 : }
    1514                 : 
    1515                 : /*
    1516                 :  * Create a memory context for statement-lifespan variables, if we don't
    1517                 :  * have one already.  It will be a child of stmt_mcontext_parent, which is
    1518                 :  * either the function's main context or a pushed-down outer stmt_mcontext.
    1519                 :  */
    1520                 : static MemoryContext
    1521           24498 : get_stmt_mcontext(PLpgSQL_execstate *estate)
    1522                 : {
    1523           24498 :     if (estate->stmt_mcontext == NULL)
    1524                 :     {
    1525           10678 :         estate->stmt_mcontext =
    1526           10678 :             AllocSetContextCreate(estate->stmt_mcontext_parent,
    1527                 :                                   "PLpgSQL per-statement data",
    1528                 :                                   ALLOCSET_DEFAULT_SIZES);
    1529                 :     }
    1530           24498 :     return estate->stmt_mcontext;
    1531                 : }
    1532                 : 
    1533                 : /*
    1534                 :  * Push down the current stmt_mcontext so that called statements won't use it.
    1535                 :  * This is needed by statements that have statement-lifespan data and need to
    1536                 :  * preserve it across some inner statements.  The caller should eventually do
    1537                 :  * pop_stmt_mcontext().
    1538                 :  */
    1539                 : static void
    1540              45 : push_stmt_mcontext(PLpgSQL_execstate *estate)
    1541                 : {
    1542                 :     /* Should have done get_stmt_mcontext() first */
    1543              45 :     Assert(estate->stmt_mcontext != NULL);
    1544                 :     /* Assert we've not messed up the stack linkage */
    1545              45 :     Assert(MemoryContextGetParent(estate->stmt_mcontext) == estate->stmt_mcontext_parent);
    1546                 :     /* Push it down to become the parent of any nested stmt mcontext */
    1547              45 :     estate->stmt_mcontext_parent = estate->stmt_mcontext;
    1548                 :     /* And make it not available for use directly */
    1549              45 :     estate->stmt_mcontext = NULL;
    1550              45 : }
    1551                 : 
    1552                 : /*
    1553                 :  * Undo push_stmt_mcontext().  We assume this is done just before or after
    1554                 :  * resetting the caller's stmt_mcontext; since that action will also delete
    1555                 :  * any child contexts, there's no need to explicitly delete whatever context
    1556                 :  * might currently be estate->stmt_mcontext.
    1557                 :  */
    1558                 : static void
    1559            3041 : pop_stmt_mcontext(PLpgSQL_execstate *estate)
    1560                 : {
    1561                 :     /* We need only pop the stack */
    1562            3041 :     estate->stmt_mcontext = estate->stmt_mcontext_parent;
    1563            3041 :     estate->stmt_mcontext_parent = MemoryContextGetParent(estate->stmt_mcontext);
    1564            3041 : }
    1565                 : 
    1566                 : 
    1567                 : /*
    1568                 :  * Subroutine for exec_stmt_block: does any condition in the condition list
    1569                 :  * match the current exception?
    1570                 :  */
    1571                 : static bool
    1572            3035 : exception_matches_conditions(ErrorData *edata, PLpgSQL_condition *cond)
    1573                 : {
    1574            3351 :     for (; cond != NULL; cond = cond->next)
    1575                 :     {
    1576            3336 :         int         sqlerrstate = cond->sqlerrstate;
    1577                 : 
    1578                 :         /*
    1579                 :          * OTHERS matches everything *except* query-canceled and
    1580                 :          * assert-failure.  If you're foolish enough, you can match those
    1581                 :          * explicitly.
    1582                 :          */
    1583            3336 :         if (sqlerrstate == 0)
    1584                 :         {
    1585            2616 :             if (edata->sqlerrcode != ERRCODE_QUERY_CANCELED &&
    1586            2615 :                 edata->sqlerrcode != ERRCODE_ASSERT_FAILURE)
    1587            2612 :                 return true;
    1588                 :         }
    1589                 :         /* Exact match? */
    1590             720 :         else if (edata->sqlerrcode == sqlerrstate)
    1591             406 :             return true;
    1592                 :         /* Category match? */
    1593             314 :         else if (ERRCODE_IS_CATEGORY(sqlerrstate) &&
    1594               3 :                  ERRCODE_TO_CATEGORY(edata->sqlerrcode) == sqlerrstate)
    1595               2 :             return true;
    1596                 :     }
    1597              15 :     return false;
    1598                 : }
    1599                 : 
    1600                 : 
    1601                 : /* ----------
    1602                 :  * exec_toplevel_block          Execute the toplevel block
    1603                 :  *
    1604                 :  * This is intentionally equivalent to executing exec_stmts() with a
    1605                 :  * list consisting of the one statement.  One tiny difference is that
    1606                 :  * we do not bother to save the entry value of estate->err_stmt;
    1607                 :  * that's assumed to be NULL.
    1608                 :  * ----------
    1609                 :  */
    1610                 : static int
    1611           40078 : exec_toplevel_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
    1612                 : {
    1613                 :     int         rc;
    1614                 : 
    1615           40078 :     estate->err_stmt = (PLpgSQL_stmt *) block;
    1616                 : 
    1617                 :     /* Let the plugin know that we are about to execute this statement */
    1618           40078 :     if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->stmt_beg)
    1619 UBC           0 :         ((*plpgsql_plugin_ptr)->stmt_beg) (estate, (PLpgSQL_stmt *) block);
    1620                 : 
    1621 CBC       40078 :     CHECK_FOR_INTERRUPTS();
    1622                 : 
    1623           40078 :     rc = exec_stmt_block(estate, block);
    1624                 : 
    1625                 :     /* Let the plugin know that we have finished executing this statement */
    1626           39552 :     if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->stmt_end)
    1627 UBC           0 :         ((*plpgsql_plugin_ptr)->stmt_end) (estate, (PLpgSQL_stmt *) block);
    1628                 : 
    1629 CBC       39552 :     estate->err_stmt = NULL;
    1630                 : 
    1631           39552 :     return rc;
    1632                 : }
    1633                 : 
    1634                 : 
    1635                 : /* ----------
    1636                 :  * exec_stmt_block          Execute a block of statements
    1637                 :  * ----------
    1638                 :  */
    1639                 : static int
    1640           46245 : exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
    1641                 : {
    1642           46245 :     volatile int rc = -1;
    1643                 :     int         i;
    1644                 : 
    1645                 :     /*
    1646                 :      * First initialize all variables declared in this block
    1647                 :      */
    1648           46245 :     estate->err_text = gettext_noop("during statement block local variable initialization");
    1649                 : 
    1650           62171 :     for (i = 0; i < block->n_initvars; i++)
    1651                 :     {
    1652           15956 :         int         n = block->initvarnos[i];
    1653           15956 :         PLpgSQL_datum *datum = estate->datums[n];
    1654                 : 
    1655                 :         /*
    1656                 :          * The set of dtypes handled here must match plpgsql_add_initdatums().
    1657                 :          *
    1658                 :          * Note that we currently don't support promise datums within blocks,
    1659                 :          * only at a function's outermost scope, so we needn't handle those
    1660                 :          * here.
    1661                 :          *
    1662                 :          * Since RECFIELD isn't a supported case either, it's okay to cast the
    1663                 :          * PLpgSQL_datum to PLpgSQL_variable.
    1664                 :          */
    1665           15956 :         estate->err_var = (PLpgSQL_variable *) datum;
    1666                 : 
    1667           15956 :         switch (datum->dtype)
    1668                 :         {
    1669           13630 :             case PLPGSQL_DTYPE_VAR:
    1670                 :                 {
    1671           13630 :                     PLpgSQL_var *var = (PLpgSQL_var *) datum;
    1672                 : 
    1673                 :                     /*
    1674                 :                      * Free any old value, in case re-entering block, and
    1675                 :                      * initialize to NULL
    1676                 :                      */
    1677           13630 :                     assign_simple_var(estate, var, (Datum) 0, true, false);
    1678                 : 
    1679           13630 :                     if (var->default_val == NULL)
    1680                 :                     {
    1681                 :                         /*
    1682                 :                          * If needed, give the datatype a chance to reject
    1683                 :                          * NULLs, by assigning a NULL to the variable.  We
    1684                 :                          * claim the value is of type UNKNOWN, not the var's
    1685                 :                          * datatype, else coercion will be skipped.
    1686                 :                          */
    1687           11839 :                         if (var->datatype->typtype == TYPTYPE_DOMAIN)
    1688              55 :                             exec_assign_value(estate,
    1689                 :                                               (PLpgSQL_datum *) var,
    1690                 :                                               (Datum) 0,
    1691                 :                                               true,
    1692                 :                                               UNKNOWNOID,
    1693                 :                                               -1);
    1694                 : 
    1695                 :                         /* parser should have rejected NOT NULL */
    1696           11835 :                         Assert(!var->notnull);
    1697                 :                     }
    1698                 :                     else
    1699                 :                     {
    1700            1791 :                         exec_assign_expr(estate, (PLpgSQL_datum *) var,
    1701                 :                                          var->default_val);
    1702                 :                     }
    1703                 :                 }
    1704           13609 :                 break;
    1705                 : 
    1706            2326 :             case PLPGSQL_DTYPE_REC:
    1707                 :                 {
    1708            2326 :                     PLpgSQL_rec *rec = (PLpgSQL_rec *) datum;
    1709                 : 
    1710                 :                     /*
    1711                 :                      * Deletion of any existing object will be handled during
    1712                 :                      * the assignments below, and in some cases it's more
    1713                 :                      * efficient for us not to get rid of it beforehand.
    1714                 :                      */
    1715            2326 :                     if (rec->default_val == NULL)
    1716                 :                     {
    1717                 :                         /*
    1718                 :                          * If needed, give the datatype a chance to reject
    1719                 :                          * NULLs, by assigning a NULL to the variable.
    1720                 :                          */
    1721            2307 :                         exec_move_row(estate, (PLpgSQL_variable *) rec,
    1722                 :                                       NULL, NULL);
    1723                 : 
    1724                 :                         /* parser should have rejected NOT NULL */
    1725            2305 :                         Assert(!rec->notnull);
    1726                 :                     }
    1727                 :                     else
    1728                 :                     {
    1729              19 :                         exec_assign_expr(estate, (PLpgSQL_datum *) rec,
    1730                 :                                          rec->default_val);
    1731                 :                     }
    1732                 :                 }
    1733            2317 :                 break;
    1734                 : 
    1735 UBC           0 :             default:
    1736               0 :                 elog(ERROR, "unrecognized dtype: %d", datum->dtype);
    1737                 :         }
    1738                 :     }
    1739                 : 
    1740 CBC       46215 :     estate->err_var = NULL;
    1741                 : 
    1742           46215 :     if (block->exceptions)
    1743                 :     {
    1744                 :         /*
    1745                 :          * Execute the statements in the block's body inside a sub-transaction
    1746                 :          */
    1747            6078 :         MemoryContext oldcontext = CurrentMemoryContext;
    1748            6078 :         ResourceOwner oldowner = CurrentResourceOwner;
    1749            6078 :         ExprContext *old_eval_econtext = estate->eval_econtext;
    1750            6078 :         ErrorData  *save_cur_error = estate->cur_error;
    1751                 :         MemoryContext stmt_mcontext;
    1752                 : 
    1753            6078 :         estate->err_text = gettext_noop("during statement block entry");
    1754                 : 
    1755                 :         /*
    1756                 :          * We will need a stmt_mcontext to hold the error data if an error
    1757                 :          * occurs.  It seems best to force it to exist before entering the
    1758                 :          * subtransaction, so that we reduce the risk of out-of-memory during
    1759                 :          * error recovery, and because this greatly simplifies restoring the
    1760                 :          * stmt_mcontext stack to the correct state after an error.  We can
    1761                 :          * ameliorate the cost of this by allowing the called statements to
    1762                 :          * use this mcontext too; so we don't push it down here.
    1763                 :          */
    1764            6078 :         stmt_mcontext = get_stmt_mcontext(estate);
    1765                 : 
    1766            6078 :         BeginInternalSubTransaction(NULL);
    1767                 :         /* Want to run statements inside function's memory context */
    1768            6078 :         MemoryContextSwitchTo(oldcontext);
    1769                 : 
    1770            6078 :         PG_TRY();
    1771                 :         {
    1772                 :             /*
    1773                 :              * We need to run the block's statements with a new eval_econtext
    1774                 :              * that belongs to the current subtransaction; if we try to use
    1775                 :              * the outer econtext then ExprContext shutdown callbacks will be
    1776                 :              * called at the wrong times.
    1777                 :              */
    1778            6078 :             plpgsql_create_econtext(estate);
    1779                 : 
    1780            6078 :             estate->err_text = NULL;
    1781                 : 
    1782                 :             /* Run the block's statements */
    1783            6078 :             rc = exec_stmts(estate, block->body);
    1784                 : 
    1785            3051 :             estate->err_text = gettext_noop("during statement block exit");
    1786                 : 
    1787                 :             /*
    1788                 :              * If the block ended with RETURN, we may need to copy the return
    1789                 :              * value out of the subtransaction eval_context.  We can avoid a
    1790                 :              * physical copy if the value happens to be a R/W expanded object.
    1791                 :              */
    1792            3051 :             if (rc == PLPGSQL_RC_RETURN &&
    1793             862 :                 !estate->retisset &&
    1794             862 :                 !estate->retisnull)
    1795                 :             {
    1796                 :                 int16       resTypLen;
    1797                 :                 bool        resTypByVal;
    1798                 : 
    1799             862 :                 get_typlenbyval(estate->rettype, &resTypLen, &resTypByVal);
    1800             862 :                 estate->retval = datumTransfer(estate->retval,
    1801                 :                                                resTypByVal, resTypLen);
    1802                 :             }
    1803                 : 
    1804                 :             /* Commit the inner transaction, return to outer xact context */
    1805            3051 :             ReleaseCurrentSubTransaction();
    1806            3051 :             MemoryContextSwitchTo(oldcontext);
    1807            3051 :             CurrentResourceOwner = oldowner;
    1808                 : 
    1809                 :             /* Assert that the stmt_mcontext stack is unchanged */
    1810            3051 :             Assert(stmt_mcontext == estate->stmt_mcontext);
    1811                 : 
    1812                 :             /*
    1813                 :              * Revert to outer eval_econtext.  (The inner one was
    1814                 :              * automatically cleaned up during subxact exit.)
    1815                 :              */
    1816            3051 :             estate->eval_econtext = old_eval_econtext;
    1817                 :         }
    1818            3027 :         PG_CATCH();
    1819                 :         {
    1820                 :             ErrorData  *edata;
    1821                 :             ListCell   *e;
    1822                 : 
    1823            3027 :             estate->err_text = gettext_noop("during exception cleanup");
    1824                 : 
    1825                 :             /* Save error info in our stmt_mcontext */
    1826            3027 :             MemoryContextSwitchTo(stmt_mcontext);
    1827            3027 :             edata = CopyErrorData();
    1828            3027 :             FlushErrorState();
    1829                 : 
    1830                 :             /* Abort the inner transaction */
    1831            3027 :             RollbackAndReleaseCurrentSubTransaction();
    1832            3027 :             MemoryContextSwitchTo(oldcontext);
    1833            3027 :             CurrentResourceOwner = oldowner;
    1834                 : 
    1835                 :             /*
    1836                 :              * Set up the stmt_mcontext stack as though we had restored our
    1837                 :              * previous state and then done push_stmt_mcontext().  The push is
    1838                 :              * needed so that statements in the exception handler won't
    1839                 :              * clobber the error data that's in our stmt_mcontext.
    1840                 :              */
    1841            3027 :             estate->stmt_mcontext_parent = stmt_mcontext;
    1842            3027 :             estate->stmt_mcontext = NULL;
    1843                 : 
    1844                 :             /*
    1845                 :              * Now we can delete any nested stmt_mcontexts that might have
    1846                 :              * been created as children of ours.  (Note: we do not immediately
    1847                 :              * release any statement-lifespan data that might have been left
    1848                 :              * behind in stmt_mcontext itself.  We could attempt that by doing
    1849                 :              * a MemoryContextReset on it before collecting the error data
    1850                 :              * above, but it seems too risky to do any significant amount of
    1851                 :              * work before collecting the error.)
    1852                 :              */
    1853            3027 :             MemoryContextDeleteChildren(stmt_mcontext);
    1854                 : 
    1855                 :             /* Revert to outer eval_econtext */
    1856            3027 :             estate->eval_econtext = old_eval_econtext;
    1857                 : 
    1858                 :             /*
    1859                 :              * Must clean up the econtext too.  However, any tuple table made
    1860                 :              * in the subxact will have been thrown away by SPI during subxact
    1861                 :              * abort, so we don't need to (and mustn't try to) free the
    1862                 :              * eval_tuptable.
    1863                 :              */
    1864            3027 :             estate->eval_tuptable = NULL;
    1865            3027 :             exec_eval_cleanup(estate);
    1866                 : 
    1867                 :             /* Look for a matching exception handler */
    1868            3042 :             foreach(e, block->exceptions->exc_list)
    1869                 :             {
    1870            3035 :                 PLpgSQL_exception *exception = (PLpgSQL_exception *) lfirst(e);
    1871                 : 
    1872            3035 :                 if (exception_matches_conditions(edata, exception->conditions))
    1873                 :                 {
    1874                 :                     /*
    1875                 :                      * Initialize the magic SQLSTATE and SQLERRM variables for
    1876                 :                      * the exception block; this also frees values from any
    1877                 :                      * prior use of the same exception. We needn't do this
    1878                 :                      * until we have found a matching exception.
    1879                 :                      */
    1880                 :                     PLpgSQL_var *state_var;
    1881                 :                     PLpgSQL_var *errm_var;
    1882                 : 
    1883            3020 :                     state_var = (PLpgSQL_var *)
    1884            3020 :                         estate->datums[block->exceptions->sqlstate_varno];
    1885            3020 :                     errm_var = (PLpgSQL_var *)
    1886            3020 :                         estate->datums[block->exceptions->sqlerrm_varno];
    1887                 : 
    1888            3020 :                     assign_text_var(estate, state_var,
    1889            3020 :                                     unpack_sql_state(edata->sqlerrcode));
    1890            3020 :                     assign_text_var(estate, errm_var, edata->message);
    1891                 : 
    1892                 :                     /*
    1893                 :                      * Also set up cur_error so the error data is accessible
    1894                 :                      * inside the handler.
    1895                 :                      */
    1896            3020 :                     estate->cur_error = edata;
    1897                 : 
    1898            3020 :                     estate->err_text = NULL;
    1899                 : 
    1900            3020 :                     rc = exec_stmts(estate, exception->action);
    1901                 : 
    1902            3005 :                     break;
    1903                 :                 }
    1904                 :             }
    1905                 : 
    1906                 :             /*
    1907                 :              * Restore previous state of cur_error, whether or not we executed
    1908                 :              * a handler.  This is needed in case an error got thrown from
    1909                 :              * some inner block's exception handler.
    1910                 :              */
    1911            3012 :             estate->cur_error = save_cur_error;
    1912                 : 
    1913                 :             /* If no match found, re-throw the error */
    1914            3012 :             if (e == NULL)
    1915               7 :                 ReThrowError(edata);
    1916                 : 
    1917                 :             /* Restore stmt_mcontext stack and release the error data */
    1918            3005 :             pop_stmt_mcontext(estate);
    1919            3005 :             MemoryContextReset(stmt_mcontext);
    1920                 :         }
    1921            6056 :         PG_END_TRY();
    1922                 : 
    1923            6056 :         Assert(save_cur_error == estate->cur_error);
    1924                 :     }
    1925                 :     else
    1926                 :     {
    1927                 :         /*
    1928                 :          * Just execute the statements in the block's body
    1929                 :          */
    1930           40137 :         estate->err_text = NULL;
    1931                 : 
    1932           40137 :         rc = exec_stmts(estate, block->body);
    1933                 :     }
    1934                 : 
    1935           45687 :     estate->err_text = NULL;
    1936                 : 
    1937                 :     /*
    1938                 :      * Handle the return code.  This is intentionally different from
    1939                 :      * LOOP_RC_PROCESSING(): CONTINUE never matches a block, and EXIT matches
    1940                 :      * a block only if there is a label match.
    1941                 :      */
    1942           45687 :     switch (rc)
    1943                 :     {
    1944           45679 :         case PLPGSQL_RC_OK:
    1945                 :         case PLPGSQL_RC_RETURN:
    1946                 :         case PLPGSQL_RC_CONTINUE:
    1947           45679 :             return rc;
    1948                 : 
    1949               8 :         case PLPGSQL_RC_EXIT:
    1950               8 :             if (estate->exitlabel == NULL)
    1951               2 :                 return PLPGSQL_RC_EXIT;
    1952               6 :             if (block->label == NULL)
    1953               1 :                 return PLPGSQL_RC_EXIT;
    1954               5 :             if (strcmp(block->label, estate->exitlabel) != 0)
    1955               2 :                 return PLPGSQL_RC_EXIT;
    1956               3 :             estate->exitlabel = NULL;
    1957               3 :             return PLPGSQL_RC_OK;
    1958                 : 
    1959 UBC           0 :         default:
    1960               0 :             elog(ERROR, "unrecognized rc: %d", rc);
    1961                 :     }
    1962                 : 
    1963                 :     return PLPGSQL_RC_OK;
    1964                 : }
    1965                 : 
    1966                 : 
    1967                 : /* ----------
    1968                 :  * exec_stmts           Iterate over a list of statements
    1969                 :  *              as long as their return code is OK
    1970                 :  * ----------
    1971                 :  */
    1972                 : static int
    1973 CBC      129018 : exec_stmts(PLpgSQL_execstate *estate, List *stmts)
    1974                 : {
    1975          129018 :     PLpgSQL_stmt *save_estmt = estate->err_stmt;
    1976                 :     ListCell   *s;
    1977                 : 
    1978          129018 :     if (stmts == NIL)
    1979                 :     {
    1980                 :         /*
    1981                 :          * Ensure we do a CHECK_FOR_INTERRUPTS() even though there is no
    1982                 :          * statement.  This prevents hangup in a tight loop if, for instance,
    1983                 :          * there is a LOOP construct with an empty body.
    1984                 :          */
    1985           30691 :         CHECK_FOR_INTERRUPTS();
    1986           30691 :         return PLPGSQL_RC_OK;
    1987                 :     }
    1988                 : 
    1989          234790 :     foreach(s, stmts)
    1990                 :     {
    1991          185335 :         PLpgSQL_stmt *stmt = (PLpgSQL_stmt *) lfirst(s);
    1992                 :         int         rc;
    1993                 : 
    1994          185335 :         estate->err_stmt = stmt;
    1995                 : 
    1996                 :         /* Let the plugin know that we are about to execute this statement */
    1997          185335 :         if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->stmt_beg)
    1998 UBC           0 :             ((*plpgsql_plugin_ptr)->stmt_beg) (estate, stmt);
    1999                 : 
    2000 CBC      185335 :         CHECK_FOR_INTERRUPTS();
    2001                 : 
    2002          185335 :         switch (stmt->cmd_type)
    2003                 :         {
    2004            6167 :             case PLPGSQL_STMT_BLOCK:
    2005            6167 :                 rc = exec_stmt_block(estate, (PLpgSQL_stmt_block *) stmt);
    2006            6135 :                 break;
    2007                 : 
    2008           38036 :             case PLPGSQL_STMT_ASSIGN:
    2009           38036 :                 rc = exec_stmt_assign(estate, (PLpgSQL_stmt_assign *) stmt);
    2010           37915 :                 break;
    2011                 : 
    2012            1737 :             case PLPGSQL_STMT_PERFORM:
    2013            1737 :                 rc = exec_stmt_perform(estate, (PLpgSQL_stmt_perform *) stmt);
    2014            1036 :                 break;
    2015                 : 
    2016              53 :             case PLPGSQL_STMT_CALL:
    2017              53 :                 rc = exec_stmt_call(estate, (PLpgSQL_stmt_call *) stmt);
    2018              47 :                 break;
    2019                 : 
    2020              64 :             case PLPGSQL_STMT_GETDIAG:
    2021              64 :                 rc = exec_stmt_getdiag(estate, (PLpgSQL_stmt_getdiag *) stmt);
    2022              61 :                 break;
    2023                 : 
    2024           43413 :             case PLPGSQL_STMT_IF:
    2025           43413 :                 rc = exec_stmt_if(estate, (PLpgSQL_stmt_if *) stmt);
    2026           43314 :                 break;
    2027                 : 
    2028             111 :             case PLPGSQL_STMT_CASE:
    2029             111 :                 rc = exec_stmt_case(estate, (PLpgSQL_stmt_case *) stmt);
    2030             108 :                 break;
    2031                 : 
    2032              40 :             case PLPGSQL_STMT_LOOP:
    2033              40 :                 rc = exec_stmt_loop(estate, (PLpgSQL_stmt_loop *) stmt);
    2034              40 :                 break;
    2035                 : 
    2036             213 :             case PLPGSQL_STMT_WHILE:
    2037             213 :                 rc = exec_stmt_while(estate, (PLpgSQL_stmt_while *) stmt);
    2038             213 :                 break;
    2039                 : 
    2040            1954 :             case PLPGSQL_STMT_FORI:
    2041            1954 :                 rc = exec_stmt_fori(estate, (PLpgSQL_stmt_fori *) stmt);
    2042            1947 :                 break;
    2043                 : 
    2044            1128 :             case PLPGSQL_STMT_FORS:
    2045            1128 :                 rc = exec_stmt_fors(estate, (PLpgSQL_stmt_fors *) stmt);
    2046            1105 :                 break;
    2047                 : 
    2048              52 :             case PLPGSQL_STMT_FORC:
    2049              52 :                 rc = exec_stmt_forc(estate, (PLpgSQL_stmt_forc *) stmt);
    2050              52 :                 break;
    2051                 : 
    2052              45 :             case PLPGSQL_STMT_FOREACH_A:
    2053              45 :                 rc = exec_stmt_foreach_a(estate, (PLpgSQL_stmt_foreach_a *) stmt);
    2054              36 :                 break;
    2055                 : 
    2056             915 :             case PLPGSQL_STMT_EXIT:
    2057             915 :                 rc = exec_stmt_exit(estate, (PLpgSQL_stmt_exit *) stmt);
    2058             915 :                 break;
    2059                 : 
    2060           39589 :             case PLPGSQL_STMT_RETURN:
    2061           39589 :                 rc = exec_stmt_return(estate, (PLpgSQL_stmt_return *) stmt);
    2062           39549 :                 break;
    2063                 : 
    2064            2001 :             case PLPGSQL_STMT_RETURN_NEXT:
    2065            2001 :                 rc = exec_stmt_return_next(estate, (PLpgSQL_stmt_return_next *) stmt);
    2066            1999 :                 break;
    2067                 : 
    2068            1333 :             case PLPGSQL_STMT_RETURN_QUERY:
    2069            1333 :                 rc = exec_stmt_return_query(estate, (PLpgSQL_stmt_return_query *) stmt);
    2070            1327 :                 break;
    2071                 : 
    2072            6940 :             case PLPGSQL_STMT_RAISE:
    2073            6940 :                 rc = exec_stmt_raise(estate, (PLpgSQL_stmt_raise *) stmt);
    2074            6452 :                 break;
    2075                 : 
    2076            4357 :             case PLPGSQL_STMT_ASSERT:
    2077            4357 :                 rc = exec_stmt_assert(estate, (PLpgSQL_stmt_assert *) stmt);
    2078            4345 :                 break;
    2079                 : 
    2080           24992 :             case PLPGSQL_STMT_EXECSQL:
    2081           24992 :                 rc = exec_stmt_execsql(estate, (PLpgSQL_stmt_execsql *) stmt);
    2082           22972 :                 break;
    2083                 : 
    2084            5226 :             case PLPGSQL_STMT_DYNEXECUTE:
    2085            5226 :                 rc = exec_stmt_dynexecute(estate, (PLpgSQL_stmt_dynexecute *) stmt);
    2086            5158 :                 break;
    2087                 : 
    2088            4570 :             case PLPGSQL_STMT_DYNFORS:
    2089            4570 :                 rc = exec_stmt_dynfors(estate, (PLpgSQL_stmt_dynfors *) stmt);
    2090            4567 :                 break;
    2091                 : 
    2092              69 :             case PLPGSQL_STMT_OPEN:
    2093              69 :                 rc = exec_stmt_open(estate, (PLpgSQL_stmt_open *) stmt);
    2094              63 :                 break;
    2095                 : 
    2096             171 :             case PLPGSQL_STMT_FETCH:
    2097             171 :                 rc = exec_stmt_fetch(estate, (PLpgSQL_stmt_fetch *) stmt);
    2098             168 :                 break;
    2099                 : 
    2100              36 :             case PLPGSQL_STMT_CLOSE:
    2101              36 :                 rc = exec_stmt_close(estate, (PLpgSQL_stmt_close *) stmt);
    2102              36 :                 break;
    2103                 : 
    2104            2081 :             case PLPGSQL_STMT_COMMIT:
    2105            2081 :                 rc = exec_stmt_commit(estate, (PLpgSQL_stmt_commit *) stmt);
    2106            2070 :                 break;
    2107                 : 
    2108              42 :             case PLPGSQL_STMT_ROLLBACK:
    2109              42 :                 rc = exec_stmt_rollback(estate, (PLpgSQL_stmt_rollback *) stmt);
    2110              39 :                 break;
    2111                 : 
    2112 UBC           0 :             default:
    2113                 :                 /* point err_stmt to parent, since this one seems corrupt */
    2114               0 :                 estate->err_stmt = save_estmt;
    2115               0 :                 elog(ERROR, "unrecognized cmd_type: %d", stmt->cmd_type);
    2116                 :                 rc = -1;        /* keep compiler quiet */
    2117                 :         }
    2118                 : 
    2119                 :         /* Let the plugin know that we have finished executing this statement */
    2120 CBC      181669 :         if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->stmt_end)
    2121 UBC           0 :             ((*plpgsql_plugin_ptr)->stmt_end) (estate, stmt);
    2122                 : 
    2123 CBC      181669 :         if (rc != PLPGSQL_RC_OK)
    2124                 :         {
    2125           45206 :             estate->err_stmt = save_estmt;
    2126           45206 :             return rc;
    2127                 :         }
    2128                 :     }                           /* end of loop over statements */
    2129                 : 
    2130           49455 :     estate->err_stmt = save_estmt;
    2131           49455 :     return PLPGSQL_RC_OK;
    2132                 : }
    2133                 : 
    2134                 : 
    2135                 : /* ----------
    2136                 :  * exec_stmt_assign         Evaluate an expression and
    2137                 :  *                  put the result into a variable.
    2138                 :  * ----------
    2139                 :  */
    2140                 : static int
    2141           38036 : exec_stmt_assign(PLpgSQL_execstate *estate, PLpgSQL_stmt_assign *stmt)
    2142                 : {
    2143           38036 :     Assert(stmt->varno >= 0);
    2144                 : 
    2145           38036 :     exec_assign_expr(estate, estate->datums[stmt->varno], stmt->expr);
    2146                 : 
    2147           37915 :     return PLPGSQL_RC_OK;
    2148                 : }
    2149                 : 
    2150                 : /* ----------
    2151                 :  * exec_stmt_perform        Evaluate query and discard result (but set
    2152                 :  *                          FOUND depending on whether at least one row
    2153                 :  *                          was returned).
    2154                 :  * ----------
    2155                 :  */
    2156                 : static int
    2157            1737 : exec_stmt_perform(PLpgSQL_execstate *estate, PLpgSQL_stmt_perform *stmt)
    2158                 : {
    2159            1737 :     PLpgSQL_expr *expr = stmt->expr;
    2160                 : 
    2161            1737 :     (void) exec_run_select(estate, expr, 0, NULL);
    2162            1036 :     exec_set_found(estate, (estate->eval_processed != 0));
    2163            1036 :     exec_eval_cleanup(estate);
    2164                 : 
    2165            1036 :     return PLPGSQL_RC_OK;
    2166                 : }
    2167                 : 
    2168                 : /*
    2169                 :  * exec_stmt_call
    2170                 :  *
    2171                 :  * NOTE: this is used for both CALL and DO statements.
    2172                 :  */
    2173                 : static int
    2174              53 : exec_stmt_call(PLpgSQL_execstate *estate, PLpgSQL_stmt_call *stmt)
    2175                 : {
    2176              53 :     PLpgSQL_expr *expr = stmt->expr;
    2177                 :     LocalTransactionId before_lxid;
    2178                 :     LocalTransactionId after_lxid;
    2179                 :     ParamListInfo paramLI;
    2180                 :     SPIExecuteOptions options;
    2181                 :     int         rc;
    2182                 : 
    2183                 :     /*
    2184                 :      * Make a plan if we don't have one already.
    2185                 :      */
    2186              53 :     if (expr->plan == NULL)
    2187              42 :         exec_prepare_plan(estate, expr, 0);
    2188                 : 
    2189                 :     /*
    2190                 :      * A CALL or DO can never be a simple expression.
    2191                 :      */
    2192              53 :     Assert(!expr->expr_simple_expr);
    2193                 : 
    2194                 :     /*
    2195                 :      * Also construct a DTYPE_ROW datum representing the plpgsql variables
    2196                 :      * associated with the procedure's output arguments.  Then we can use
    2197                 :      * exec_move_row() to do the assignments.
    2198                 :      */
    2199              53 :     if (stmt->is_call && stmt->target == NULL)
    2200              41 :         stmt->target = make_callstmt_target(estate, expr);
    2201                 : 
    2202              48 :     paramLI = setup_param_list(estate, expr);
    2203                 : 
    2204              48 :     before_lxid = MyProc->lxid;
    2205                 : 
    2206                 :     /*
    2207                 :      * If we have a procedure-lifespan resowner, use that to hold the refcount
    2208                 :      * for the plan.  This avoids refcount leakage complaints if the called
    2209                 :      * procedure ends the current transaction.
    2210                 :      *
    2211                 :      * Also, tell SPI to allow non-atomic execution.
    2212                 :      */
    2213              48 :     memset(&options, 0, sizeof(options));
    2214              48 :     options.params = paramLI;
    2215              48 :     options.read_only = estate->readonly_func;
    2216              48 :     options.allow_nonatomic = true;
    2217              48 :     options.owner = estate->procedure_resowner;
    2218                 : 
    2219              48 :     rc = SPI_execute_plan_extended(expr->plan, &options);
    2220                 : 
    2221              47 :     if (rc < 0)
    2222 UBC           0 :         elog(ERROR, "SPI_execute_plan_extended failed executing query \"%s\": %s",
    2223                 :              expr->query, SPI_result_code_string(rc));
    2224                 : 
    2225 CBC          47 :     after_lxid = MyProc->lxid;
    2226                 : 
    2227              47 :     if (before_lxid != after_lxid)
    2228                 :     {
    2229                 :         /*
    2230                 :          * If we are in a new transaction after the call, we need to build new
    2231                 :          * simple-expression infrastructure.
    2232                 :          */
    2233               4 :         estate->simple_eval_estate = NULL;
    2234               4 :         estate->simple_eval_resowner = NULL;
    2235               4 :         plpgsql_create_econtext(estate);
    2236                 :     }
    2237                 : 
    2238                 :     /*
    2239                 :      * Check result rowcount; if there's one row, assign procedure's output
    2240                 :      * values back to the appropriate variables.
    2241                 :      */
    2242              47 :     if (SPI_processed == 1)
    2243                 :     {
    2244              37 :         SPITupleTable *tuptab = SPI_tuptable;
    2245                 : 
    2246              37 :         if (!stmt->is_call)
    2247 UBC           0 :             elog(ERROR, "DO statement returned a row");
    2248                 : 
    2249 CBC          37 :         exec_move_row(estate, stmt->target, tuptab->vals[0], tuptab->tupdesc);
    2250                 :     }
    2251              10 :     else if (SPI_processed > 1)
    2252 UBC           0 :         elog(ERROR, "procedure call returned more than one row");
    2253                 : 
    2254 CBC          47 :     exec_eval_cleanup(estate);
    2255              47 :     SPI_freetuptable(SPI_tuptable);
    2256                 : 
    2257              47 :     return PLPGSQL_RC_OK;
    2258                 : }
    2259                 : 
    2260                 : /*
    2261                 :  * We construct a DTYPE_ROW datum representing the plpgsql variables
    2262                 :  * associated with the procedure's output arguments.  Then we can use
    2263                 :  * exec_move_row() to do the assignments.
    2264                 :  */
    2265                 : static PLpgSQL_variable *
    2266              41 : make_callstmt_target(PLpgSQL_execstate *estate, PLpgSQL_expr *expr)
    2267                 : {
    2268                 :     List       *plansources;
    2269                 :     CachedPlanSource *plansource;
    2270                 :     CallStmt   *stmt;
    2271                 :     FuncExpr   *funcexpr;
    2272                 :     HeapTuple   func_tuple;
    2273                 :     Oid        *argtypes;
    2274                 :     char      **argnames;
    2275                 :     char       *argmodes;
    2276                 :     int         numargs;
    2277                 :     MemoryContext oldcontext;
    2278                 :     PLpgSQL_row *row;
    2279                 :     int         nfields;
    2280                 :     int         i;
    2281                 : 
    2282                 :     /* Use eval_mcontext for any cruft accumulated here */
    2283              41 :     oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
    2284                 : 
    2285                 :     /*
    2286                 :      * Get the parsed CallStmt, and look up the called procedure
    2287                 :      */
    2288              41 :     plansources = SPI_plan_get_plan_sources(expr->plan);
    2289              41 :     if (list_length(plansources) != 1)
    2290 UBC           0 :         elog(ERROR, "query for CALL statement is not a CallStmt");
    2291 CBC          41 :     plansource = (CachedPlanSource *) linitial(plansources);
    2292              41 :     if (list_length(plansource->query_list) != 1)
    2293 UBC           0 :         elog(ERROR, "query for CALL statement is not a CallStmt");
    2294 CBC          41 :     stmt = (CallStmt *) linitial_node(Query,
    2295                 :                                       plansource->query_list)->utilityStmt;
    2296              41 :     if (stmt == NULL || !IsA(stmt, CallStmt))
    2297 UBC           0 :         elog(ERROR, "query for CALL statement is not a CallStmt");
    2298                 : 
    2299 CBC          41 :     funcexpr = stmt->funcexpr;
    2300                 : 
    2301              41 :     func_tuple = SearchSysCache1(PROCOID,
    2302                 :                                  ObjectIdGetDatum(funcexpr->funcid));
    2303              41 :     if (!HeapTupleIsValid(func_tuple))
    2304 UBC           0 :         elog(ERROR, "cache lookup failed for function %u",
    2305                 :              funcexpr->funcid);
    2306                 : 
    2307                 :     /*
    2308                 :      * Get the argument names and modes, so that we can deliver on-point error
    2309                 :      * messages when something is wrong.
    2310                 :      */
    2311 CBC          41 :     numargs = get_func_arg_info(func_tuple, &argtypes, &argnames, &argmodes);
    2312                 : 
    2313              41 :     ReleaseSysCache(func_tuple);
    2314                 : 
    2315                 :     /*
    2316                 :      * Begin constructing row Datum; keep it in fn_cxt so it's adequately
    2317                 :      * long-lived.
    2318                 :      */
    2319              41 :     MemoryContextSwitchTo(estate->func->fn_cxt);
    2320                 : 
    2321              41 :     row = (PLpgSQL_row *) palloc0(sizeof(PLpgSQL_row));
    2322              41 :     row->dtype = PLPGSQL_DTYPE_ROW;
    2323              41 :     row->refname = "(unnamed row)";
    2324              41 :     row->lineno = -1;
    2325              41 :     row->varnos = (int *) palloc(numargs * sizeof(int));
    2326                 : 
    2327              41 :     MemoryContextSwitchTo(get_eval_mcontext(estate));
    2328                 : 
    2329                 :     /*
    2330                 :      * Examine procedure's argument list.  Each output arg position should be
    2331                 :      * an unadorned plpgsql variable (Datum), which we can insert into the row
    2332                 :      * Datum.
    2333                 :      */
    2334              41 :     nfields = 0;
    2335             132 :     for (i = 0; i < numargs; i++)
    2336                 :     {
    2337              96 :         if (argmodes &&
    2338              86 :             (argmodes[i] == PROARGMODE_INOUT ||
    2339              43 :              argmodes[i] == PROARGMODE_OUT))
    2340                 :         {
    2341              55 :             Node       *n = list_nth(stmt->outargs, nfields);
    2342                 : 
    2343              55 :             if (IsA(n, Param))
    2344                 :             {
    2345              51 :                 Param      *param = (Param *) n;
    2346                 :                 int         dno;
    2347                 : 
    2348                 :                 /* paramid is offset by 1 (see make_datum_param()) */
    2349              51 :                 dno = param->paramid - 1;
    2350                 :                 /* must check assignability now, because grammar can't */
    2351              51 :                 exec_check_assignable(estate, dno);
    2352              50 :                 row->varnos[nfields++] = dno;
    2353                 :             }
    2354                 :             else
    2355                 :             {
    2356                 :                 /* report error using parameter name, if available */
    2357               4 :                 if (argnames && argnames[i] && argnames[i][0])
    2358               4 :                     ereport(ERROR,
    2359                 :                             (errcode(ERRCODE_SYNTAX_ERROR),
    2360                 :                              errmsg("procedure parameter \"%s\" is an output parameter but corresponding argument is not writable",
    2361                 :                                     argnames[i])));
    2362                 :                 else
    2363 UBC           0 :                     ereport(ERROR,
    2364                 :                             (errcode(ERRCODE_SYNTAX_ERROR),
    2365                 :                              errmsg("procedure parameter %d is an output parameter but corresponding argument is not writable",
    2366                 :                                     i + 1)));
    2367                 :             }
    2368                 :         }
    2369                 :     }
    2370                 : 
    2371 CBC          36 :     Assert(nfields == list_length(stmt->outargs));
    2372                 : 
    2373              36 :     row->nfields = nfields;
    2374                 : 
    2375              36 :     MemoryContextSwitchTo(oldcontext);
    2376                 : 
    2377              36 :     return (PLpgSQL_variable *) row;
    2378                 : }
    2379                 : 
    2380                 : /* ----------
    2381                 :  * exec_stmt_getdiag                    Put internal PG information into
    2382                 :  *                                      specified variables.
    2383                 :  * ----------
    2384                 :  */
    2385                 : static int
    2386              64 : exec_stmt_getdiag(PLpgSQL_execstate *estate, PLpgSQL_stmt_getdiag *stmt)
    2387                 : {
    2388                 :     ListCell   *lc;
    2389                 : 
    2390                 :     /*
    2391                 :      * GET STACKED DIAGNOSTICS is only valid inside an exception handler.
    2392                 :      *
    2393                 :      * Note: we trust the grammar to have disallowed the relevant item kinds
    2394                 :      * if not is_stacked, otherwise we'd dump core below.
    2395                 :      */
    2396              64 :     if (stmt->is_stacked && estate->cur_error == NULL)
    2397               3 :         ereport(ERROR,
    2398                 :                 (errcode(ERRCODE_STACKED_DIAGNOSTICS_ACCESSED_WITHOUT_ACTIVE_HANDLER),
    2399                 :                  errmsg("GET STACKED DIAGNOSTICS cannot be used outside an exception handler")));
    2400                 : 
    2401             154 :     foreach(lc, stmt->diag_items)
    2402                 :     {
    2403              93 :         PLpgSQL_diag_item *diag_item = (PLpgSQL_diag_item *) lfirst(lc);
    2404              93 :         PLpgSQL_datum *var = estate->datums[diag_item->target];
    2405                 : 
    2406              93 :         switch (diag_item->kind)
    2407                 :         {
    2408              21 :             case PLPGSQL_GETDIAG_ROW_COUNT:
    2409              21 :                 exec_assign_value(estate, var,
    2410                 :                                   UInt64GetDatum(estate->eval_processed),
    2411                 :                                   false, INT8OID, -1);
    2412              21 :                 break;
    2413                 : 
    2414 GNC           6 :             case PLPGSQL_GETDIAG_ROUTINE_OID:
    2415               6 :                 exec_assign_value(estate, var,
    2416               6 :                                   ObjectIdGetDatum(estate->func->fn_oid),
    2417                 :                                   false, OIDOID, -1);
    2418               6 :                 break;
    2419                 : 
    2420 CBC           3 :             case PLPGSQL_GETDIAG_ERROR_CONTEXT:
    2421               3 :                 exec_assign_c_string(estate, var,
    2422               3 :                                      estate->cur_error->context);
    2423 GIC           3 :                 break;
    2424 ECB             : 
    2425 GIC           4 :             case PLPGSQL_GETDIAG_ERROR_DETAIL:
    2426 CBC           4 :                 exec_assign_c_string(estate, var,
    2427               4 :                                      estate->cur_error->detail);
    2428               4 :                 break;
    2429 ECB             : 
    2430 GIC           4 :             case PLPGSQL_GETDIAG_ERROR_HINT:
    2431 CBC           4 :                 exec_assign_c_string(estate, var,
    2432               4 :                                      estate->cur_error->hint);
    2433               4 :                 break;
    2434 ECB             : 
    2435 GIC           4 :             case PLPGSQL_GETDIAG_RETURNED_SQLSTATE:
    2436 CBC           4 :                 exec_assign_c_string(estate, var,
    2437               4 :                                      unpack_sql_state(estate->cur_error->sqlerrcode));
    2438               4 :                 break;
    2439 ECB             : 
    2440 GIC           4 :             case PLPGSQL_GETDIAG_COLUMN_NAME:
    2441 CBC           4 :                 exec_assign_c_string(estate, var,
    2442               4 :                                      estate->cur_error->column_name);
    2443               4 :                 break;
    2444 ECB             : 
    2445 GIC           4 :             case PLPGSQL_GETDIAG_CONSTRAINT_NAME:
    2446 CBC           4 :                 exec_assign_c_string(estate, var,
    2447               4 :                                      estate->cur_error->constraint_name);
    2448               4 :                 break;
    2449 ECB             : 
    2450 GIC           4 :             case PLPGSQL_GETDIAG_DATATYPE_NAME:
    2451 CBC           4 :                 exec_assign_c_string(estate, var,
    2452               4 :                                      estate->cur_error->datatype_name);
    2453               4 :                 break;
    2454 ECB             : 
    2455 GIC           7 :             case PLPGSQL_GETDIAG_MESSAGE_TEXT:
    2456 CBC           7 :                 exec_assign_c_string(estate, var,
    2457               7 :                                      estate->cur_error->message);
    2458               7 :                 break;
    2459 ECB             : 
    2460 GIC           4 :             case PLPGSQL_GETDIAG_TABLE_NAME:
    2461 CBC           4 :                 exec_assign_c_string(estate, var,
    2462               4 :                                      estate->cur_error->table_name);
    2463               4 :                 break;
    2464 ECB             : 
    2465 GIC           4 :             case PLPGSQL_GETDIAG_SCHEMA_NAME:
    2466 CBC           4 :                 exec_assign_c_string(estate, var,
    2467               4 :                                      estate->cur_error->schema_name);
    2468               4 :                 break;
    2469 ECB             : 
    2470 GIC          24 :             case PLPGSQL_GETDIAG_CONTEXT:
    2471 ECB             :                 {
    2472                 :                     char       *contextstackstr;
    2473                 :                     MemoryContext oldcontext;
    2474                 : 
    2475                 :                     /* Use eval_mcontext for short-lived string */
    2476 CBC          24 :                     oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
    2477 GIC          24 :                     contextstackstr = GetErrorContextStack();
    2478              24 :                     MemoryContextSwitchTo(oldcontext);
    2479                 : 
    2480              24 :                     exec_assign_c_string(estate, var, contextstackstr);
    2481                 :                 }
    2482 CBC          24 :                 break;
    2483 ECB             : 
    2484 LBC           0 :             default:
    2485 UIC           0 :                 elog(ERROR, "unrecognized diagnostic item kind: %d",
    2486 ECB             :                      diag_item->kind);
    2487                 :         }
    2488                 :     }
    2489                 : 
    2490 GBC          61 :     exec_eval_cleanup(estate);
    2491 EUB             : 
    2492 GIC          61 :     return PLPGSQL_RC_OK;
    2493                 : }
    2494                 : 
    2495                 : /* ----------
    2496 ECB             :  * exec_stmt_if             Evaluate a bool expression and
    2497                 :  *                  execute the true or false body
    2498                 :  *                  conditionally.
    2499                 :  * ----------
    2500                 :  */
    2501                 : static int
    2502 GIC       43413 : exec_stmt_if(PLpgSQL_execstate *estate, PLpgSQL_stmt_if *stmt)
    2503                 : {
    2504                 :     bool        value;
    2505                 :     bool        isnull;
    2506                 :     ListCell   *lc;
    2507                 : 
    2508 CBC       43413 :     value = exec_eval_boolean(estate, stmt->cond, &isnull);
    2509 GIC       43413 :     exec_eval_cleanup(estate);
    2510           43413 :     if (!isnull && value)
    2511            9285 :         return exec_stmts(estate, stmt->then_body);
    2512                 : 
    2513           34238 :     foreach(lc, stmt->elsif_list)
    2514 ECB             :     {
    2515 CBC         377 :         PLpgSQL_if_elsif *elif = (PLpgSQL_if_elsif *) lfirst(lc);
    2516 ECB             : 
    2517 CBC         377 :         value = exec_eval_boolean(estate, elif->cond, &isnull);
    2518 GIC         377 :         exec_eval_cleanup(estate);
    2519 CBC         377 :         if (!isnull && value)
    2520 GIC         267 :             return exec_stmts(estate, elif->stmts);
    2521 ECB             :     }
    2522                 : 
    2523 CBC       33861 :     return exec_stmts(estate, stmt->else_body);
    2524 ECB             : }
    2525                 : 
    2526                 : 
    2527                 : /*-----------
    2528                 :  * exec_stmt_case
    2529                 :  *-----------
    2530                 :  */
    2531                 : static int
    2532 GIC         111 : exec_stmt_case(PLpgSQL_execstate *estate, PLpgSQL_stmt_case *stmt)
    2533                 : {
    2534             111 :     PLpgSQL_var *t_var = NULL;
    2535                 :     bool        isnull;
    2536                 :     ListCell   *l;
    2537                 : 
    2538 CBC         111 :     if (stmt->t_expr != NULL)
    2539                 :     {
    2540 ECB             :         /* simple case */
    2541                 :         Datum       t_val;
    2542                 :         Oid         t_typoid;
    2543                 :         int32       t_typmod;
    2544                 : 
    2545 GIC         107 :         t_val = exec_eval_expr(estate, stmt->t_expr,
    2546                 :                                &isnull, &t_typoid, &t_typmod);
    2547                 : 
    2548             107 :         t_var = (PLpgSQL_var *) estate->datums[stmt->t_varno];
    2549                 : 
    2550                 :         /*
    2551 ECB             :          * When expected datatype is different from real, change it. Note that
    2552                 :          * what we're modifying here is an execution copy of the datum, so
    2553                 :          * this doesn't affect the originally stored function parse tree. (In
    2554                 :          * theory, if the expression datatype keeps changing during execution,
    2555                 :          * this could cause a function-lifespan memory leak.  Doesn't seem
    2556                 :          * worth worrying about though.)
    2557                 :          */
    2558 GIC         107 :         if (t_var->datatype->typoid != t_typoid ||
    2559              84 :             t_var->datatype->atttypmod != t_typmod)
    2560              23 :             t_var->datatype = plpgsql_build_datatype(t_typoid,
    2561                 :                                                      t_typmod,
    2562              23 :                                                      estate->func->fn_input_collation,
    2563                 :                                                      NULL);
    2564 ECB             : 
    2565                 :         /* now we can assign to the variable */
    2566 CBC         107 :         exec_assign_value(estate,
    2567                 :                           (PLpgSQL_datum *) t_var,
    2568 ECB             :                           t_val,
    2569                 :                           isnull,
    2570                 :                           t_typoid,
    2571                 :                           t_typmod);
    2572                 : 
    2573 GIC         107 :         exec_eval_cleanup(estate);
    2574                 :     }
    2575                 : 
    2576                 :     /* Now search for a successful WHEN clause */
    2577             209 :     foreach(l, stmt->case_when_list)
    2578                 :     {
    2579 CBC         204 :         PLpgSQL_case_when *cwt = (PLpgSQL_case_when *) lfirst(l);
    2580                 :         bool        value;
    2581                 : 
    2582 GIC         204 :         value = exec_eval_boolean(estate, cwt->expr, &isnull);
    2583 CBC         204 :         exec_eval_cleanup(estate);
    2584 GIC         204 :         if (!isnull && value)
    2585 ECB             :         {
    2586                 :             /* Found it */
    2587                 : 
    2588                 :             /* We can now discard any value we had for the temp variable */
    2589 CBC         106 :             if (t_var != NULL)
    2590             104 :                 assign_simple_var(estate, t_var, (Datum) 0, true, false);
    2591                 : 
    2592                 :             /* Evaluate the statement(s), and we're done */
    2593 GIC         106 :             return exec_stmts(estate, cwt->stmts);
    2594                 :         }
    2595 ECB             :     }
    2596                 : 
    2597                 :     /* We can now discard any value we had for the temp variable */
    2598 GIC           5 :     if (t_var != NULL)
    2599 CBC           3 :         assign_simple_var(estate, t_var, (Datum) 0, true, false);
    2600                 : 
    2601                 :     /* SQL2003 mandates this error if there was no ELSE clause */
    2602 GIC           5 :     if (!stmt->have_else)
    2603               3 :         ereport(ERROR,
    2604 ECB             :                 (errcode(ERRCODE_CASE_NOT_FOUND),
    2605                 :                  errmsg("case not found"),
    2606                 :                  errhint("CASE statement is missing ELSE part.")));
    2607                 : 
    2608                 :     /* Evaluate the ELSE statements, and we're done */
    2609 CBC           2 :     return exec_stmts(estate, stmt->else_stmts);
    2610                 : }
    2611                 : 
    2612                 : 
    2613                 : /* ----------
    2614                 :  * exec_stmt_loop           Loop over statements until
    2615 ECB             :  *                  an exit occurs.
    2616                 :  * ----------
    2617                 :  */
    2618                 : static int
    2619 GIC          40 : exec_stmt_loop(PLpgSQL_execstate *estate, PLpgSQL_stmt_loop *stmt)
    2620                 : {
    2621              40 :     int         rc = PLPGSQL_RC_OK;
    2622                 : 
    2623                 :     for (;;)
    2624                 :     {
    2625 CBC        1680 :         rc = exec_stmts(estate, stmt->body);
    2626                 : 
    2627            1680 :         LOOP_RC_PROCESSING(stmt->label, break);
    2628                 :     }
    2629                 : 
    2630 GIC          40 :     return rc;
    2631 ECB             : }
    2632                 : 
    2633                 : 
    2634                 : /* ----------
    2635                 :  * exec_stmt_while          Loop over statements as long
    2636                 :  *                  as an expression evaluates to
    2637                 :  *                  true or an exit occurs.
    2638                 :  * ----------
    2639                 :  */
    2640                 : static int
    2641 GIC         213 : exec_stmt_while(PLpgSQL_execstate *estate, PLpgSQL_stmt_while *stmt)
    2642                 : {
    2643             213 :     int         rc = PLPGSQL_RC_OK;
    2644                 : 
    2645                 :     for (;;)
    2646            1566 :     {
    2647 ECB             :         bool        value;
    2648                 :         bool        isnull;
    2649                 : 
    2650 GIC        1779 :         value = exec_eval_boolean(estate, stmt->cond, &isnull);
    2651            1779 :         exec_eval_cleanup(estate);
    2652 ECB             : 
    2653 GIC        1779 :         if (isnull || !value)
    2654                 :             break;
    2655                 : 
    2656 CBC        1576 :         rc = exec_stmts(estate, stmt->body);
    2657 ECB             : 
    2658 GIC        1576 :         LOOP_RC_PROCESSING(stmt->label, break);
    2659 ECB             :     }
    2660                 : 
    2661 GIC         213 :     return rc;
    2662 ECB             : }
    2663                 : 
    2664                 : 
    2665                 : /* ----------
    2666                 :  * exec_stmt_fori           Iterate an integer variable
    2667                 :  *                  from a lower to an upper value
    2668                 :  *                  incrementing or decrementing by the BY value
    2669                 :  * ----------
    2670                 :  */
    2671                 : static int
    2672 GIC        1954 : exec_stmt_fori(PLpgSQL_execstate *estate, PLpgSQL_stmt_fori *stmt)
    2673                 : {
    2674                 :     PLpgSQL_var *var;
    2675                 :     Datum       value;
    2676                 :     bool        isnull;
    2677                 :     Oid         valtype;
    2678 ECB             :     int32       valtypmod;
    2679                 :     int32       loop_value;
    2680                 :     int32       end_value;
    2681                 :     int32       step_value;
    2682 GIC        1954 :     bool        found = false;
    2683            1954 :     int         rc = PLPGSQL_RC_OK;
    2684                 : 
    2685            1954 :     var = (PLpgSQL_var *) (estate->datums[stmt->var->dno]);
    2686                 : 
    2687                 :     /*
    2688 ECB             :      * Get the value of the lower bound
    2689                 :      */
    2690 GIC        1954 :     value = exec_eval_expr(estate, stmt->lower,
    2691 ECB             :                            &isnull, &valtype, &valtypmod);
    2692 GIC        1954 :     value = exec_cast_value(estate, value, &isnull,
    2693                 :                             valtype, valtypmod,
    2694            1954 :                             var->datatype->typoid,
    2695            1954 :                             var->datatype->atttypmod);
    2696 CBC        1954 :     if (isnull)
    2697 UIC           0 :         ereport(ERROR,
    2698 ECB             :                 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
    2699                 :                  errmsg("lower bound of FOR loop cannot be null")));
    2700 CBC        1954 :     loop_value = DatumGetInt32(value);
    2701            1954 :     exec_eval_cleanup(estate);
    2702 ECB             : 
    2703 EUB             :     /*
    2704                 :      * Get the value of the upper bound
    2705                 :      */
    2706 CBC        1954 :     value = exec_eval_expr(estate, stmt->upper,
    2707 ECB             :                            &isnull, &valtype, &valtypmod);
    2708 GIC        1954 :     value = exec_cast_value(estate, value, &isnull,
    2709                 :                             valtype, valtypmod,
    2710            1954 :                             var->datatype->typoid,
    2711            1954 :                             var->datatype->atttypmod);
    2712 CBC        1954 :     if (isnull)
    2713 UIC           0 :         ereport(ERROR,
    2714 ECB             :                 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
    2715                 :                  errmsg("upper bound of FOR loop cannot be null")));
    2716 CBC        1954 :     end_value = DatumGetInt32(value);
    2717            1954 :     exec_eval_cleanup(estate);
    2718 ECB             : 
    2719 EUB             :     /*
    2720                 :      * Get the step value
    2721                 :      */
    2722 CBC        1954 :     if (stmt->step)
    2723 ECB             :     {
    2724 GIC           9 :         value = exec_eval_expr(estate, stmt->step,
    2725                 :                                &isnull, &valtype, &valtypmod);
    2726               9 :         value = exec_cast_value(estate, value, &isnull,
    2727                 :                                 valtype, valtypmod,
    2728 CBC           9 :                                 var->datatype->typoid,
    2729 GIC           9 :                                 var->datatype->atttypmod);
    2730 CBC           9 :         if (isnull)
    2731 UIC           0 :             ereport(ERROR,
    2732 ECB             :                     (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
    2733                 :                      errmsg("BY value of FOR loop cannot be null")));
    2734 CBC           9 :         step_value = DatumGetInt32(value);
    2735               9 :         exec_eval_cleanup(estate);
    2736               9 :         if (step_value <= 0)
    2737 GBC           3 :             ereport(ERROR,
    2738                 :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    2739                 :                      errmsg("BY value of FOR loop must be greater than zero")));
    2740 ECB             :     }
    2741                 :     else
    2742 CBC        1945 :         step_value = 1;
    2743 ECB             : 
    2744                 :     /*
    2745                 :      * Now do the loop
    2746                 :      */
    2747                 :     for (;;)
    2748                 :     {
    2749                 :         /*
    2750                 :          * Check against upper bound
    2751                 :          */
    2752 GIC       11869 :         if (stmt->reverse)
    2753                 :         {
    2754               8 :             if (loop_value < end_value)
    2755               1 :                 break;
    2756                 :         }
    2757                 :         else
    2758 ECB             :         {
    2759 GIC       11861 :             if (loop_value > end_value)
    2760 CBC        1936 :                 break;
    2761 ECB             :         }
    2762                 : 
    2763 GIC        9932 :         found = true;           /* looped at least once */
    2764                 : 
    2765 ECB             :         /*
    2766                 :          * Assign current value to loop var
    2767                 :          */
    2768 GIC        9932 :         assign_simple_var(estate, var, Int32GetDatum(loop_value), false, false);
    2769 ECB             : 
    2770                 :         /*
    2771                 :          * Execute the statements
    2772                 :          */
    2773 GIC        9932 :         rc = exec_stmts(estate, stmt->body);
    2774 ECB             : 
    2775 GIC        9928 :         LOOP_RC_PROCESSING(stmt->label, break);
    2776                 : 
    2777                 :         /*
    2778                 :          * Increase/decrease loop value, unless it would overflow, in which
    2779 ECB             :          * case exit the loop.
    2780                 :          */
    2781 CBC        9920 :         if (stmt->reverse)
    2782                 :         {
    2783 GIC           7 :             if (loop_value < (PG_INT32_MIN + step_value))
    2784               1 :                 break;
    2785               6 :             loop_value -= step_value;
    2786                 :         }
    2787 ECB             :         else
    2788                 :         {
    2789 CBC        9913 :             if (loop_value > (PG_INT32_MAX - step_value))
    2790               1 :                 break;
    2791            9912 :             loop_value += step_value;
    2792                 :         }
    2793                 :     }
    2794                 : 
    2795 ECB             :     /*
    2796                 :      * Set the FOUND variable to indicate the result of executing the loop
    2797                 :      * (namely, whether we looped one or more times). This must be set here so
    2798                 :      * that it does not interfere with the value of the FOUND variable inside
    2799                 :      * the loop processing itself.
    2800                 :      */
    2801 GIC        1947 :     exec_set_found(estate, found);
    2802                 : 
    2803            1947 :     return rc;
    2804                 : }
    2805                 : 
    2806                 : 
    2807 ECB             : /* ----------
    2808                 :  * exec_stmt_fors           Execute a query, assign each
    2809                 :  *                  tuple to a record or row and
    2810                 :  *                  execute a group of statements
    2811                 :  *                  for it.
    2812                 :  * ----------
    2813                 :  */
    2814                 : static int
    2815 GIC        1128 : exec_stmt_fors(PLpgSQL_execstate *estate, PLpgSQL_stmt_fors *stmt)
    2816                 : {
    2817                 :     Portal      portal;
    2818                 :     int         rc;
    2819                 : 
    2820                 :     /*
    2821 ECB             :      * Open the implicit cursor for the statement using exec_run_select
    2822                 :      */
    2823 GIC        1128 :     exec_run_select(estate, stmt->query, 0, &portal);
    2824                 : 
    2825                 :     /*
    2826                 :      * Execute the loop
    2827                 :      */
    2828            1122 :     rc = exec_for_query(estate, (PLpgSQL_stmt_forq *) stmt, portal, true);
    2829 ECB             : 
    2830                 :     /*
    2831                 :      * Close the implicit cursor
    2832                 :      */
    2833 GIC        1105 :     SPI_cursor_close(portal);
    2834 ECB             : 
    2835 GIC        1105 :     return rc;
    2836                 : }
    2837                 : 
    2838                 : 
    2839 ECB             : /* ----------
    2840                 :  * exec_stmt_forc           Execute a loop for each row from a cursor.
    2841                 :  * ----------
    2842                 :  */
    2843                 : static int
    2844 GIC          52 : exec_stmt_forc(PLpgSQL_execstate *estate, PLpgSQL_stmt_forc *stmt)
    2845                 : {
    2846                 :     PLpgSQL_var *curvar;
    2847              52 :     MemoryContext stmt_mcontext = NULL;
    2848              52 :     char       *curname = NULL;
    2849                 :     PLpgSQL_expr *query;
    2850 ECB             :     ParamListInfo paramLI;
    2851                 :     Portal      portal;
    2852                 :     int         rc;
    2853                 : 
    2854                 :     /* ----------
    2855                 :      * Get the cursor variable and if it has an assigned name, check
    2856                 :      * that it's not in use currently.
    2857                 :      * ----------
    2858                 :      */
    2859 GIC          52 :     curvar = (PLpgSQL_var *) (estate->datums[stmt->curvar]);
    2860              52 :     if (!curvar->isnull)
    2861                 :     {
    2862                 :         MemoryContext oldcontext;
    2863                 : 
    2864                 :         /* We only need stmt_mcontext to hold the cursor name string */
    2865 CBC          12 :         stmt_mcontext = get_stmt_mcontext(estate);
    2866              12 :         oldcontext = MemoryContextSwitchTo(stmt_mcontext);
    2867 GIC          12 :         curname = TextDatumGetCString(curvar->value);
    2868              12 :         MemoryContextSwitchTo(oldcontext);
    2869                 : 
    2870              12 :         if (SPI_cursor_find(curname) != NULL)
    2871 LBC           0 :             ereport(ERROR,
    2872 ECB             :                     (errcode(ERRCODE_DUPLICATE_CURSOR),
    2873                 :                      errmsg("cursor \"%s\" already in use", curname)));
    2874                 :     }
    2875                 : 
    2876                 :     /* ----------
    2877 EUB             :      * Open the cursor just like an OPEN command
    2878                 :      *
    2879                 :      * Note: parser should already have checked that statement supplies
    2880                 :      * args iff cursor needs them, but we check again to be safe.
    2881                 :      * ----------
    2882                 :      */
    2883 GIC          52 :     if (stmt->argquery != NULL)
    2884                 :     {
    2885                 :         /* ----------
    2886                 :          * OPEN CURSOR with args.  We fake a SELECT ... INTO ...
    2887                 :          * statement to evaluate the args and put 'em into the
    2888                 :          * internal row.
    2889 ECB             :          * ----------
    2890                 :          */
    2891                 :         PLpgSQL_stmt_execsql set_args;
    2892                 : 
    2893 GIC           6 :         if (curvar->cursor_explicit_argrow < 0)
    2894 UIC           0 :             ereport(ERROR,
    2895                 :                     (errcode(ERRCODE_SYNTAX_ERROR),
    2896                 :                      errmsg("arguments given for cursor without arguments")));
    2897                 : 
    2898 GIC           6 :         memset(&set_args, 0, sizeof(set_args));
    2899 CBC           6 :         set_args.cmd_type = PLPGSQL_STMT_EXECSQL;
    2900 GBC           6 :         set_args.lineno = stmt->lineno;
    2901 GIC           6 :         set_args.sqlstmt = stmt->argquery;
    2902               6 :         set_args.into = true;
    2903                 :         /* XXX historically this has not been STRICT */
    2904 CBC           6 :         set_args.target = (PLpgSQL_variable *)
    2905               6 :             (estate->datums[curvar->cursor_explicit_argrow]);
    2906 ECB             : 
    2907 CBC           6 :         if (exec_stmt_execsql(estate, &set_args) != PLPGSQL_RC_OK)
    2908 LBC           0 :             elog(ERROR, "open cursor failed during argument processing");
    2909                 :     }
    2910 ECB             :     else
    2911                 :     {
    2912 GIC          46 :         if (curvar->cursor_explicit_argrow >= 0)
    2913 LBC           0 :             ereport(ERROR,
    2914 EUB             :                     (errcode(ERRCODE_SYNTAX_ERROR),
    2915                 :                      errmsg("arguments required for cursor")));
    2916                 :     }
    2917                 : 
    2918 CBC          52 :     query = curvar->cursor_explicit_expr;
    2919 GBC          52 :     Assert(query);
    2920                 : 
    2921 GIC          52 :     if (query->plan == NULL)
    2922              16 :         exec_prepare_plan(estate, query, curvar->cursor_options);
    2923                 : 
    2924 ECB             :     /*
    2925                 :      * Set up ParamListInfo for this query
    2926                 :      */
    2927 CBC          52 :     paramLI = setup_param_list(estate, query);
    2928 ECB             : 
    2929                 :     /*
    2930                 :      * Open the cursor (the paramlist will get copied into the portal)
    2931                 :      */
    2932 GIC          52 :     portal = SPI_cursor_open_with_paramlist(curname, query->plan,
    2933 ECB             :                                             paramLI,
    2934 GIC          52 :                                             estate->readonly_func);
    2935              52 :     if (portal == NULL)
    2936 UIC           0 :         elog(ERROR, "could not open cursor: %s",
    2937                 :              SPI_result_code_string(SPI_result));
    2938 ECB             : 
    2939                 :     /*
    2940                 :      * If cursor variable was NULL, store the generated portal name in it,
    2941                 :      * after verifying it's okay to assign to.
    2942 EUB             :      */
    2943 GIC          52 :     if (curname == NULL)
    2944                 :     {
    2945              40 :         exec_check_assignable(estate, stmt->curvar);
    2946              40 :         assign_text_var(estate, curvar, portal->name);
    2947                 :     }
    2948                 : 
    2949 ECB             :     /*
    2950                 :      * Clean up before entering exec_for_query
    2951                 :      */
    2952 CBC          52 :     exec_eval_cleanup(estate);
    2953 GIC          52 :     if (stmt_mcontext)
    2954              12 :         MemoryContextReset(stmt_mcontext);
    2955                 : 
    2956                 :     /*
    2957                 :      * Execute the loop.  We can't prefetch because the cursor is accessible
    2958 ECB             :      * to the user, for instance via UPDATE WHERE CURRENT OF within the loop.
    2959                 :      */
    2960 CBC          52 :     rc = exec_for_query(estate, (PLpgSQL_stmt_forq *) stmt, portal, false);
    2961                 : 
    2962                 :     /* ----------
    2963                 :      * Close portal, and restore cursor variable if it was initially NULL.
    2964                 :      * ----------
    2965                 :      */
    2966              52 :     SPI_cursor_close(portal);
    2967                 : 
    2968 GIC          52 :     if (curname == NULL)
    2969              40 :         assign_simple_var(estate, curvar, (Datum) 0, true, false);
    2970                 : 
    2971              52 :     return rc;
    2972 ECB             : }
    2973                 : 
    2974                 : 
    2975                 : /* ----------
    2976                 :  * exec_stmt_foreach_a          Loop over elements or slices of an array
    2977                 :  *
    2978                 :  * When looping over elements, the loop variable is the same type that the
    2979                 :  * array stores (eg: integer), when looping through slices, the loop variable
    2980                 :  * is an array of size and dimensions to match the size of the slice.
    2981                 :  * ----------
    2982                 :  */
    2983                 : static int
    2984 GIC          45 : exec_stmt_foreach_a(PLpgSQL_execstate *estate, PLpgSQL_stmt_foreach_a *stmt)
    2985                 : {
    2986                 :     ArrayType  *arr;
    2987                 :     Oid         arrtype;
    2988                 :     int32       arrtypmod;
    2989                 :     PLpgSQL_datum *loop_var;
    2990 ECB             :     Oid         loop_var_elem_type;
    2991 GIC          45 :     bool        found = false;
    2992              45 :     int         rc = PLPGSQL_RC_OK;
    2993                 :     MemoryContext stmt_mcontext;
    2994                 :     MemoryContext oldcontext;
    2995                 :     ArrayIterator array_iterator;
    2996                 :     Oid         iterator_result_type;
    2997 ECB             :     int32       iterator_result_typmod;
    2998                 :     Datum       value;
    2999                 :     bool        isnull;
    3000                 : 
    3001                 :     /* get the value of the array expression */
    3002 GIC          45 :     value = exec_eval_expr(estate, stmt->expr, &isnull, &arrtype, &arrtypmod);
    3003              45 :     if (isnull)
    3004 UIC           0 :         ereport(ERROR,
    3005                 :                 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
    3006                 :                  errmsg("FOREACH expression must not be null")));
    3007                 : 
    3008 ECB             :     /*
    3009                 :      * Do as much as possible of the code below in stmt_mcontext, to avoid any
    3010 EUB             :      * leaks from called subroutines.  We need a private stmt_mcontext since
    3011                 :      * we'll be calling arbitrary statement code.
    3012                 :      */
    3013 GIC          45 :     stmt_mcontext = get_stmt_mcontext(estate);
    3014              45 :     push_stmt_mcontext(estate);
    3015              45 :     oldcontext = MemoryContextSwitchTo(stmt_mcontext);
    3016                 : 
    3017                 :     /* check the type of the expression - must be an array */
    3018              45 :     if (!OidIsValid(get_element_type(arrtype)))
    3019 LBC           0 :         ereport(ERROR,
    3020 ECB             :                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    3021                 :                  errmsg("FOREACH expression must yield an array, not type %s",
    3022                 :                         format_type_be(arrtype))));
    3023                 : 
    3024                 :     /*
    3025 EUB             :      * We must copy the array into stmt_mcontext, else it will disappear in
    3026                 :      * exec_eval_cleanup.  This is annoying, but cleanup will certainly happen
    3027                 :      * while running the loop body, so we have little choice.
    3028                 :      */
    3029 GIC          45 :     arr = DatumGetArrayTypePCopy(value);
    3030                 : 
    3031                 :     /* Clean up any leftover temporary memory */
    3032              45 :     exec_eval_cleanup(estate);
    3033                 : 
    3034                 :     /* Slice dimension must be less than or equal to array dimension */
    3035 CBC          45 :     if (stmt->slice < 0 || stmt->slice > ARR_NDIM(arr))
    3036 GIC           3 :         ereport(ERROR,
    3037                 :                 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
    3038 ECB             :                  errmsg("slice dimension (%d) is out of the valid range 0..%d",
    3039                 :                         stmt->slice, ARR_NDIM(arr))));
    3040                 : 
    3041                 :     /* Set up the loop variable and see if it is of an array type */
    3042 CBC          42 :     loop_var = estate->datums[stmt->varno];
    3043 GIC          42 :     if (loop_var->dtype == PLPGSQL_DTYPE_REC ||
    3044              36 :         loop_var->dtype == PLPGSQL_DTYPE_ROW)
    3045                 :     {
    3046                 :         /*
    3047                 :          * Record/row variable is certainly not of array type, and might not
    3048 ECB             :          * be initialized at all yet, so don't try to get its type
    3049                 :          */
    3050 CBC          12 :         loop_var_elem_type = InvalidOid;
    3051                 :     }
    3052                 :     else
    3053 GIC          30 :         loop_var_elem_type = get_element_type(plpgsql_exec_get_datum_type(estate,
    3054                 :                                                                           loop_var));
    3055                 : 
    3056 ECB             :     /*
    3057                 :      * Sanity-check the loop variable type.  We don't try very hard here, and
    3058                 :      * should not be too picky since it's possible that exec_assign_value can
    3059                 :      * coerce values of different types.  But it seems worthwhile to complain
    3060                 :      * if the array-ness of the loop variable is not right.
    3061                 :      */
    3062 GIC          42 :     if (stmt->slice > 0 && loop_var_elem_type == InvalidOid)
    3063               6 :         ereport(ERROR,
    3064                 :                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    3065                 :                  errmsg("FOREACH ... SLICE loop variable must be of an array type")));
    3066              36 :     if (stmt->slice == 0 && loop_var_elem_type != InvalidOid)
    3067 UIC           0 :         ereport(ERROR,
    3068 ECB             :                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    3069                 :                  errmsg("FOREACH loop variable must not be of an array type")));
    3070                 : 
    3071                 :     /* Create an iterator to step through the array */
    3072 CBC          36 :     array_iterator = array_create_iterator(arr, stmt->slice, NULL);
    3073 EUB             : 
    3074                 :     /* Identify iterator result type */
    3075 GIC          36 :     if (stmt->slice > 0)
    3076                 :     {
    3077                 :         /* When slicing, nominal type of result is same as array type */
    3078 CBC          18 :         iterator_result_type = arrtype;
    3079 GIC          18 :         iterator_result_typmod = arrtypmod;
    3080                 :     }
    3081 ECB             :     else
    3082                 :     {
    3083                 :         /* Without slicing, results are individual array elements */
    3084 CBC          18 :         iterator_result_type = ARR_ELEMTYPE(arr);
    3085              18 :         iterator_result_typmod = arrtypmod;
    3086                 :     }
    3087                 : 
    3088                 :     /* Iterate over the array elements or slices */
    3089 GIC         129 :     while (array_iterate(array_iterator, &value, &isnull))
    3090 ECB             :     {
    3091 CBC          93 :         found = true;           /* looped at least once */
    3092                 : 
    3093                 :         /* exec_assign_value and exec_stmts must run in the main context */
    3094 GIC          93 :         MemoryContextSwitchTo(oldcontext);
    3095 ECB             : 
    3096                 :         /* Assign current element/slice to the loop variable */
    3097 CBC          93 :         exec_assign_value(estate, loop_var, value, isnull,
    3098                 :                           iterator_result_type, iterator_result_typmod);
    3099                 : 
    3100 ECB             :         /* In slice case, value is temporary; must free it to avoid leakage */
    3101 GIC          93 :         if (stmt->slice > 0)
    3102              27 :             pfree(DatumGetPointer(value));
    3103 ECB             : 
    3104                 :         /*
    3105                 :          * Execute the statements
    3106                 :          */
    3107 CBC          93 :         rc = exec_stmts(estate, stmt->body);
    3108 ECB             : 
    3109 GIC          93 :         LOOP_RC_PROCESSING(stmt->label, break);
    3110                 : 
    3111              93 :         MemoryContextSwitchTo(stmt_mcontext);
    3112                 :     }
    3113 ECB             : 
    3114                 :     /* Restore memory context state */
    3115 CBC          36 :     MemoryContextSwitchTo(oldcontext);
    3116 GIC          36 :     pop_stmt_mcontext(estate);
    3117 ECB             : 
    3118                 :     /* Release temporary memory, including the array value */
    3119 GIC          36 :     MemoryContextReset(stmt_mcontext);
    3120                 : 
    3121 ECB             :     /*
    3122                 :      * Set the FOUND variable to indicate the result of executing the loop
    3123                 :      * (namely, whether we looped one or more times). This must be set here so
    3124                 :      * that it does not interfere with the value of the FOUND variable inside
    3125                 :      * the loop processing itself.
    3126                 :      */
    3127 GIC          36 :     exec_set_found(estate, found);
    3128                 : 
    3129              36 :     return rc;
    3130                 : }
    3131                 : 
    3132                 : 
    3133 ECB             : /* ----------
    3134                 :  * exec_stmt_exit           Implements EXIT and CONTINUE
    3135                 :  *
    3136                 :  * This begins the process of exiting / restarting a loop.
    3137                 :  * ----------
    3138                 :  */
    3139                 : static int
    3140 GIC         915 : exec_stmt_exit(PLpgSQL_execstate *estate, PLpgSQL_stmt_exit *stmt)
    3141                 : {
    3142                 :     /*
    3143                 :      * If the exit / continue has a condition, evaluate it
    3144                 :      */
    3145             915 :     if (stmt->cond != NULL)
    3146 ECB             :     {
    3147                 :         bool        value;
    3148                 :         bool        isnull;
    3149                 : 
    3150 GIC         767 :         value = exec_eval_boolean(estate, stmt->cond, &isnull);
    3151 CBC         767 :         exec_eval_cleanup(estate);
    3152 GIC         767 :         if (isnull || value == false)
    3153             709 :             return PLPGSQL_RC_OK;
    3154                 :     }
    3155                 : 
    3156 CBC         206 :     estate->exitlabel = stmt->label;
    3157             206 :     if (stmt->is_exit)
    3158              41 :         return PLPGSQL_RC_EXIT;
    3159 ECB             :     else
    3160 GIC         165 :         return PLPGSQL_RC_CONTINUE;
    3161                 : }
    3162 ECB             : 
    3163                 : 
    3164                 : /* ----------
    3165                 :  * exec_stmt_return         Evaluate an expression and start
    3166                 :  *                  returning from the function.
    3167                 :  *
    3168                 :  * Note: The result may be in the eval_mcontext.  Therefore, we must not
    3169                 :  * do exec_eval_cleanup while unwinding the control stack.
    3170                 :  * ----------
    3171                 :  */
    3172                 : static int
    3173 GIC       39589 : exec_stmt_return(PLpgSQL_execstate *estate, PLpgSQL_stmt_return *stmt)
    3174                 : {
    3175                 :     /*
    3176                 :      * If processing a set-returning PL/pgSQL function, the final RETURN
    3177                 :      * indicates that the function is finished producing tuples.  The rest of
    3178                 :      * the work will be done at the top level.
    3179 ECB             :      */
    3180 GIC       39589 :     if (estate->retisset)
    3181            1680 :         return PLPGSQL_RC_RETURN;
    3182                 : 
    3183                 :     /* initialize for null result */
    3184           37909 :     estate->retval = (Datum) 0;
    3185           37909 :     estate->retisnull = true;
    3186 CBC       37909 :     estate->rettype = InvalidOid;
    3187 ECB             : 
    3188                 :     /*
    3189                 :      * Special case path when the RETURN expression is a simple variable
    3190                 :      * reference; in particular, this path is always taken in functions with
    3191                 :      * one or more OUT parameters.
    3192                 :      *
    3193                 :      * This special case is especially efficient for returning variables that
    3194                 :      * have R/W expanded values: we can put the R/W pointer directly into
    3195                 :      * estate->retval, leading to transferring the value to the caller's
    3196                 :      * context cheaply.  If we went through exec_eval_expr we'd end up with a
    3197                 :      * R/O pointer.  It's okay to skip MakeExpandedObjectReadOnly here since
    3198                 :      * we know we won't need the variable's value within the function anymore.
    3199                 :      */
    3200 GIC       37909 :     if (stmt->retvarno >= 0)
    3201                 :     {
    3202           28484 :         PLpgSQL_datum *retvar = estate->datums[stmt->retvarno];
    3203                 : 
    3204           28484 :         switch (retvar->dtype)
    3205                 :         {
    3206 LBC           0 :             case PLPGSQL_DTYPE_PROMISE:
    3207                 :                 /* fulfill promise if needed, then handle like regular var */
    3208               0 :                 plpgsql_fulfill_promise(estate, (PLpgSQL_var *) retvar);
    3209                 : 
    3210 ECB             :                 /* FALL THRU */
    3211                 : 
    3212 GBC       19231 :             case PLPGSQL_DTYPE_VAR:
    3213                 :                 {
    3214           19231 :                     PLpgSQL_var *var = (PLpgSQL_var *) retvar;
    3215                 : 
    3216 GIC       19231 :                     estate->retval = var->value;
    3217           19231 :                     estate->retisnull = var->isnull;
    3218 CBC       19231 :                     estate->rettype = var->datatype->typoid;
    3219                 : 
    3220 ECB             :                     /*
    3221                 :                      * A PLpgSQL_var could not be of composite type, so
    3222                 :                      * conversion must fail if retistuple.  We throw a custom
    3223                 :                      * error mainly for consistency with historical behavior.
    3224                 :                      * For the same reason, we don't throw error if the result
    3225                 :                      * is NULL.  (Note that plpgsql_exec_trigger assumes that
    3226                 :                      * any non-null result has been verified to be composite.)
    3227                 :                      */
    3228 GIC       19231 :                     if (estate->retistuple && !estate->retisnull)
    3229               3 :                         ereport(ERROR,
    3230                 :                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    3231                 :                                  errmsg("cannot return non-composite value from function returning composite type")));
    3232                 :                 }
    3233           19228 :                 break;
    3234 ECB             : 
    3235 CBC        6218 :             case PLPGSQL_DTYPE_REC:
    3236                 :                 {
    3237 GIC        6218 :                     PLpgSQL_rec *rec = (PLpgSQL_rec *) retvar;
    3238                 : 
    3239 ECB             :                     /* If record is empty, we return NULL not a row of nulls */
    3240 GIC        6218 :                     if (rec->erh && !ExpandedRecordIsEmpty(rec->erh))
    3241 ECB             :                     {
    3242 GIC        6095 :                         estate->retval = ExpandedRecordGetDatum(rec->erh);
    3243 CBC        6095 :                         estate->retisnull = false;
    3244 GIC        6095 :                         estate->rettype = rec->rectypeid;
    3245                 :                     }
    3246 ECB             :                 }
    3247 GIC        6218 :                 break;
    3248 ECB             : 
    3249 CBC        3035 :             case PLPGSQL_DTYPE_ROW:
    3250 ECB             :                 {
    3251 GIC        3035 :                     PLpgSQL_row *row = (PLpgSQL_row *) retvar;
    3252                 :                     int32       rettypmod;
    3253 ECB             : 
    3254                 :                     /* We get here if there are multiple OUT parameters */
    3255 CBC        3035 :                     exec_eval_datum(estate,
    3256                 :                                     (PLpgSQL_datum *) row,
    3257 ECB             :                                     &estate->rettype,
    3258                 :                                     &rettypmod,
    3259                 :                                     &estate->retval,
    3260                 :                                     &estate->retisnull);
    3261                 :                 }
    3262 GIC        3035 :                 break;
    3263                 : 
    3264 UIC           0 :             default:
    3265               0 :                 elog(ERROR, "unrecognized dtype: %d", retvar->dtype);
    3266                 :         }
    3267                 : 
    3268 CBC       28481 :         return PLPGSQL_RC_RETURN;
    3269                 :     }
    3270 EUB             : 
    3271 GBC        9425 :     if (stmt->expr != NULL)
    3272                 :     {
    3273                 :         int32       rettypmod;
    3274 ECB             : 
    3275 GIC        7451 :         estate->retval = exec_eval_expr(estate, stmt->expr,
    3276                 :                                         &(estate->retisnull),
    3277 ECB             :                                         &(estate->rettype),
    3278                 :                                         &rettypmod);
    3279                 : 
    3280                 :         /*
    3281                 :          * As in the DTYPE_VAR case above, throw a custom error if a non-null,
    3282                 :          * non-composite value is returned in a function returning tuple.
    3283                 :          */
    3284 GIC        7417 :         if (estate->retistuple && !estate->retisnull &&
    3285              49 :             !type_is_rowtype(estate->rettype))
    3286               3 :             ereport(ERROR,
    3287                 :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    3288                 :                      errmsg("cannot return non-composite value from function returning composite type")));
    3289                 : 
    3290 CBC        7414 :         return PLPGSQL_RC_RETURN;
    3291 ECB             :     }
    3292                 : 
    3293                 :     /*
    3294                 :      * Special hack for function returning VOID: instead of NULL, return a
    3295                 :      * non-null VOID value.  This is of dubious importance but is kept for
    3296                 :      * backwards compatibility.  We don't do it for procedures, though.
    3297                 :      */
    3298 GIC        1974 :     if (estate->fn_rettype == VOIDOID &&
    3299            1974 :         estate->func->fn_prokind != PROKIND_PROCEDURE)
    3300                 :     {
    3301            1949 :         estate->retval = (Datum) 0;
    3302            1949 :         estate->retisnull = false;
    3303            1949 :         estate->rettype = VOIDOID;
    3304 ECB             :     }
    3305                 : 
    3306 GIC        1974 :     return PLPGSQL_RC_RETURN;
    3307 ECB             : }
    3308                 : 
    3309                 : /* ----------
    3310                 :  * exec_stmt_return_next        Evaluate an expression and add it to the
    3311                 :  *                              list of tuples returned by the current
    3312                 :  *                              SRF.
    3313                 :  * ----------
    3314                 :  */
    3315                 : static int
    3316 GIC        2001 : exec_stmt_return_next(PLpgSQL_execstate *estate,
    3317                 :                       PLpgSQL_stmt_return_next *stmt)
    3318                 : {
    3319                 :     TupleDesc   tupdesc;
    3320                 :     int         natts;
    3321                 :     HeapTuple   tuple;
    3322 ECB             :     MemoryContext oldcontext;
    3323                 : 
    3324 GIC        2001 :     if (!estate->retisset)
    3325 UIC           0 :         ereport(ERROR,
    3326                 :                 (errcode(ERRCODE_SYNTAX_ERROR),
    3327                 :                  errmsg("cannot use RETURN NEXT in a non-SETOF function")));
    3328                 : 
    3329 GIC        2001 :     if (estate->tuple_store == NULL)
    3330 CBC         373 :         exec_init_tuple_store(estate);
    3331 EUB             : 
    3332                 :     /* tuple_store_desc will be filled by exec_init_tuple_store */
    3333 GIC        2001 :     tupdesc = estate->tuple_store_desc;
    3334            2001 :     natts = tupdesc->natts;
    3335 ECB             : 
    3336                 :     /*
    3337                 :      * Special case path when the RETURN NEXT expression is a simple variable
    3338                 :      * reference; in particular, this path is always taken in functions with
    3339                 :      * one or more OUT parameters.
    3340                 :      *
    3341                 :      * Unlike exec_stmt_return, there's no special win here for R/W expanded
    3342                 :      * values, since they'll have to get flattened to go into the tuplestore.
    3343                 :      * Indeed, we'd better make them R/O to avoid any risk of the casting step
    3344                 :      * changing them in-place.
    3345                 :      */
    3346 GIC        2001 :     if (stmt->retvarno >= 0)
    3347                 :     {
    3348            1728 :         PLpgSQL_datum *retvar = estate->datums[stmt->retvarno];
    3349                 : 
    3350            1728 :         switch (retvar->dtype)
    3351                 :         {
    3352 LBC           0 :             case PLPGSQL_DTYPE_PROMISE:
    3353                 :                 /* fulfill promise if needed, then handle like regular var */
    3354               0 :                 plpgsql_fulfill_promise(estate, (PLpgSQL_var *) retvar);
    3355                 : 
    3356 ECB             :                 /* FALL THRU */
    3357                 : 
    3358 GBC        1553 :             case PLPGSQL_DTYPE_VAR:
    3359                 :                 {
    3360            1553 :                     PLpgSQL_var *var = (PLpgSQL_var *) retvar;
    3361 GIC        1553 :                     Datum       retval = var->value;
    3362            1553 :                     bool        isNull = var->isnull;
    3363            1553 :                     Form_pg_attribute attr = TupleDescAttr(tupdesc, 0);
    3364 ECB             : 
    3365 GIC        1553 :                     if (natts != 1)
    3366 LBC           0 :                         ereport(ERROR,
    3367 ECB             :                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    3368                 :                                  errmsg("wrong result type supplied in RETURN NEXT")));
    3369                 : 
    3370                 :                     /* let's be very paranoid about the cast step */
    3371 CBC        1553 :                     retval = MakeExpandedObjectReadOnly(retval,
    3372 EUB             :                                                         isNull,
    3373                 :                                                         var->datatype->typlen);
    3374                 : 
    3375                 :                     /* coerce type if needed */
    3376 GIC        3106 :                     retval = exec_cast_value(estate,
    3377 ECB             :                                              retval,
    3378                 :                                              &isNull,
    3379 GIC        1553 :                                              var->datatype->typoid,
    3380            1553 :                                              var->datatype->atttypmod,
    3381                 :                                              attr->atttypid,
    3382 ECB             :                                              attr->atttypmod);
    3383                 : 
    3384 GIC        1553 :                     tuplestore_putvalues(estate->tuple_store, tupdesc,
    3385 ECB             :                                          &retval, &isNull);
    3386                 :                 }
    3387 GIC        1553 :                 break;
    3388                 : 
    3389             103 :             case PLPGSQL_DTYPE_REC:
    3390 ECB             :                 {
    3391 GIC         103 :                     PLpgSQL_rec *rec = (PLpgSQL_rec *) retvar;
    3392                 :                     TupleDesc   rec_tupdesc;
    3393 ECB             :                     TupleConversionMap *tupmap;
    3394                 : 
    3395                 :                     /* If rec is null, try to convert it to a row of nulls */
    3396 GIC         103 :                     if (rec->erh == NULL)
    3397 CBC           2 :                         instantiate_empty_record_variable(estate, rec);
    3398 GIC         102 :                     if (ExpandedRecordIsEmpty(rec->erh))
    3399               1 :                         deconstruct_expanded_record(rec->erh);
    3400                 : 
    3401                 :                     /* Use eval_mcontext for tuple conversion work */
    3402 CBC         102 :                     oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
    3403             102 :                     rec_tupdesc = expanded_record_get_tupdesc(rec->erh);
    3404             102 :                     tupmap = convert_tuples_by_position(rec_tupdesc,
    3405 ECB             :                                                         tupdesc,
    3406                 :                                                         gettext_noop("wrong record type supplied in RETURN NEXT"));
    3407 GIC         102 :                     tuple = expanded_record_get_tuple(rec->erh);
    3408 CBC         102 :                     if (tupmap)
    3409              22 :                         tuple = execute_attr_map_tuple(tuple, tupmap);
    3410             102 :                     tuplestore_puttuple(estate->tuple_store, tuple);
    3411 GIC         102 :                     MemoryContextSwitchTo(oldcontext);
    3412                 :                 }
    3413 CBC         102 :                 break;
    3414 ECB             : 
    3415 CBC          72 :             case PLPGSQL_DTYPE_ROW:
    3416 ECB             :                 {
    3417 CBC          72 :                     PLpgSQL_row *row = (PLpgSQL_row *) retvar;
    3418                 : 
    3419 ECB             :                     /* We get here if there are multiple OUT parameters */
    3420                 : 
    3421                 :                     /* Use eval_mcontext for tuple conversion work */
    3422 GIC          72 :                     oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
    3423 CBC          72 :                     tuple = make_tuple_from_row(estate, row, tupdesc);
    3424 GIC          72 :                     if (tuple == NULL)  /* should not happen */
    3425 UIC           0 :                         ereport(ERROR,
    3426                 :                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    3427                 :                                  errmsg("wrong record type supplied in RETURN NEXT")));
    3428 CBC          72 :                     tuplestore_puttuple(estate->tuple_store, tuple);
    3429              72 :                     MemoryContextSwitchTo(oldcontext);
    3430 ECB             :                 }
    3431 GBC          72 :                 break;
    3432                 : 
    3433 UIC           0 :             default:
    3434 LBC           0 :                 elog(ERROR, "unrecognized dtype: %d", retvar->dtype);
    3435 ECB             :                 break;
    3436                 :         }
    3437                 :     }
    3438 GIC         273 :     else if (stmt->expr)
    3439 EUB             :     {
    3440                 :         Datum       retval;
    3441                 :         bool        isNull;
    3442                 :         Oid         rettype;
    3443                 :         int32       rettypmod;
    3444 ECB             : 
    3445 GIC         273 :         retval = exec_eval_expr(estate,
    3446                 :                                 stmt->expr,
    3447                 :                                 &isNull,
    3448                 :                                 &rettype,
    3449                 :                                 &rettypmod);
    3450                 : 
    3451 CBC         273 :         if (estate->retistuple)
    3452                 :         {
    3453                 :             /* Expression should be of RECORD or composite type */
    3454 GIC         243 :             if (!isNull)
    3455                 :             {
    3456                 :                 HeapTupleData tmptup;
    3457 ECB             :                 TupleDesc   retvaldesc;
    3458                 :                 TupleConversionMap *tupmap;
    3459                 : 
    3460 CBC         240 :                 if (!type_is_rowtype(rettype))
    3461 UIC           0 :                     ereport(ERROR,
    3462                 :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    3463                 :                              errmsg("cannot return non-composite value from function returning composite type")));
    3464                 : 
    3465                 :                 /* Use eval_mcontext for tuple conversion work */
    3466 CBC         240 :                 oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
    3467 GBC         240 :                 retvaldesc = deconstruct_composite_datum(retval, &tmptup);
    3468 GIC         240 :                 tuple = &tmptup;
    3469             240 :                 tupmap = convert_tuples_by_position(retvaldesc, tupdesc,
    3470                 :                                                     gettext_noop("returned record type does not match expected record type"));
    3471             239 :                 if (tupmap)
    3472 CBC           1 :                     tuple = execute_attr_map_tuple(tuple, tupmap);
    3473             239 :                 tuplestore_puttuple(estate->tuple_store, tuple);
    3474             239 :                 ReleaseTupleDesc(retvaldesc);
    3475             239 :                 MemoryContextSwitchTo(oldcontext);
    3476                 :             }
    3477 ECB             :             else
    3478                 :             {
    3479                 :                 /* Composite NULL --- store a row of nulls */
    3480                 :                 Datum      *nulldatums;
    3481                 :                 bool       *nullflags;
    3482                 : 
    3483                 :                 nulldatums = (Datum *)
    3484 GIC           3 :                     eval_mcontext_alloc0(estate, natts * sizeof(Datum));
    3485                 :                 nullflags = (bool *)
    3486               3 :                     eval_mcontext_alloc(estate, natts * sizeof(bool));
    3487               3 :                 memset(nullflags, true, natts * sizeof(bool));
    3488               3 :                 tuplestore_putvalues(estate->tuple_store, tupdesc,
    3489                 :                                      nulldatums, nullflags);
    3490 ECB             :             }
    3491                 :         }
    3492                 :         else
    3493                 :         {
    3494 CBC          30 :             Form_pg_attribute attr = TupleDescAttr(tupdesc, 0);
    3495                 : 
    3496                 :             /* Simple scalar result */
    3497 GIC          30 :             if (natts != 1)
    3498 UIC           0 :                 ereport(ERROR,
    3499                 :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    3500 ECB             :                          errmsg("wrong result type supplied in RETURN NEXT")));
    3501                 : 
    3502                 :             /* coerce type if needed */
    3503 CBC          30 :             retval = exec_cast_value(estate,
    3504 EUB             :                                      retval,
    3505                 :                                      &isNull,
    3506                 :                                      rettype,
    3507                 :                                      rettypmod,
    3508                 :                                      attr->atttypid,
    3509 ECB             :                                      attr->atttypmod);
    3510                 : 
    3511 GIC          30 :             tuplestore_putvalues(estate->tuple_store, tupdesc,
    3512                 :                                  &retval, &isNull);
    3513                 :         }
    3514                 :     }
    3515                 :     else
    3516                 :     {
    3517 LBC           0 :         ereport(ERROR,
    3518                 :                 (errcode(ERRCODE_SYNTAX_ERROR),
    3519                 :                  errmsg("RETURN NEXT must have a parameter")));
    3520                 :     }
    3521                 : 
    3522 GIC        1999 :     exec_eval_cleanup(estate);
    3523 EUB             : 
    3524 GIC        1999 :     return PLPGSQL_RC_OK;
    3525                 : }
    3526                 : 
    3527                 : /* ----------
    3528 ECB             :  * exec_stmt_return_query       Evaluate a query and add it to the
    3529                 :  *                              list of tuples returned by the current
    3530                 :  *                              SRF.
    3531                 :  * ----------
    3532                 :  */
    3533                 : static int
    3534 GIC        1333 : exec_stmt_return_query(PLpgSQL_execstate *estate,
    3535                 :                        PLpgSQL_stmt_return_query *stmt)
    3536                 : {
    3537                 :     int64       tcount;
    3538                 :     DestReceiver *treceiver;
    3539                 :     int         rc;
    3540 ECB             :     uint64      processed;
    3541 GIC        1333 :     MemoryContext stmt_mcontext = get_stmt_mcontext(estate);
    3542                 :     MemoryContext oldcontext;
    3543                 : 
    3544            1333 :     if (!estate->retisset)
    3545 UIC           0 :         ereport(ERROR,
    3546                 :                 (errcode(ERRCODE_SYNTAX_ERROR),
    3547 ECB             :                  errmsg("cannot use RETURN QUERY in a non-SETOF function")));
    3548                 : 
    3549 GIC        1333 :     if (estate->tuple_store == NULL)
    3550 CBC        1306 :         exec_init_tuple_store(estate);
    3551 EUB             :     /* There might be some tuples in the tuplestore already */
    3552 GIC        1333 :     tcount = tuplestore_tuple_count(estate->tuple_store);
    3553                 : 
    3554                 :     /*
    3555 ECB             :      * Set up DestReceiver to transfer results directly to tuplestore,
    3556                 :      * converting rowtype if necessary.  DestReceiver lives in mcontext.
    3557                 :      */
    3558 CBC        1333 :     oldcontext = MemoryContextSwitchTo(stmt_mcontext);
    3559 GIC        1333 :     treceiver = CreateDestReceiver(DestTuplestore);
    3560            1333 :     SetTuplestoreDestReceiverParams(treceiver,
    3561                 :                                     estate->tuple_store,
    3562                 :                                     estate->tuple_store_cxt,
    3563                 :                                     false,
    3564 ECB             :                                     estate->tuple_store_desc,
    3565                 :                                     gettext_noop("structure of query does not match function result type"));
    3566 CBC        1333 :     MemoryContextSwitchTo(oldcontext);
    3567                 : 
    3568 GIC        1333 :     if (stmt->query != NULL)
    3569                 :     {
    3570                 :         /* static query */
    3571            1204 :         PLpgSQL_expr *expr = stmt->query;
    3572 ECB             :         ParamListInfo paramLI;
    3573                 :         SPIExecuteOptions options;
    3574                 : 
    3575                 :         /*
    3576                 :          * On the first call for this expression generate the plan.
    3577                 :          */
    3578 GIC        1204 :         if (expr->plan == NULL)
    3579              31 :             exec_prepare_plan(estate, expr, CURSOR_OPT_PARALLEL_OK);
    3580                 : 
    3581                 :         /*
    3582                 :          * Set up ParamListInfo to pass to executor
    3583                 :          */
    3584 CBC        1204 :         paramLI = setup_param_list(estate, expr);
    3585 ECB             : 
    3586                 :         /*
    3587                 :          * Execute the query
    3588                 :          */
    3589 GIC        1204 :         memset(&options, 0, sizeof(options));
    3590 CBC        1204 :         options.params = paramLI;
    3591 GIC        1204 :         options.read_only = estate->readonly_func;
    3592            1204 :         options.must_return_tuples = true;
    3593            1204 :         options.dest = treceiver;
    3594                 : 
    3595 CBC        1204 :         rc = SPI_execute_plan_extended(expr->plan, &options);
    3596            1201 :         if (rc < 0)
    3597 LBC           0 :             elog(ERROR, "SPI_execute_plan_extended failed executing query \"%s\": %s",
    3598 ECB             :                  expr->query, SPI_result_code_string(rc));
    3599                 :     }
    3600                 :     else
    3601                 :     {
    3602                 :         /* RETURN QUERY EXECUTE */
    3603 EUB             :         Datum       query;
    3604                 :         bool        isnull;
    3605                 :         Oid         restype;
    3606                 :         int32       restypmod;
    3607                 :         char       *querystr;
    3608                 :         SPIExecuteOptions options;
    3609                 : 
    3610                 :         /*
    3611                 :          * Evaluate the string expression after the EXECUTE keyword. Its
    3612                 :          * result is the querystring we have to execute.
    3613                 :          */
    3614 GIC         129 :         Assert(stmt->dynquery != NULL);
    3615             129 :         query = exec_eval_expr(estate, stmt->dynquery,
    3616                 :                                &isnull, &restype, &restypmod);
    3617             129 :         if (isnull)
    3618 UIC           0 :             ereport(ERROR,
    3619                 :                     (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
    3620 ECB             :                      errmsg("query string argument of EXECUTE is null")));
    3621                 : 
    3622                 :         /* Get the C-String representation */
    3623 CBC         129 :         querystr = convert_value_to_string(estate, query, restype);
    3624 EUB             : 
    3625                 :         /* copy it into the stmt_mcontext before we clean up */
    3626 GIC         129 :         querystr = MemoryContextStrdup(stmt_mcontext, querystr);
    3627                 : 
    3628             129 :         exec_eval_cleanup(estate);
    3629 ECB             : 
    3630                 :         /* Execute query, passing params if necessary */
    3631 GIC         129 :         memset(&options, 0, sizeof(options));
    3632 CBC         129 :         options.params = exec_eval_using_params(estate,
    3633                 :                                                 stmt->params);
    3634             129 :         options.read_only = estate->readonly_func;
    3635 GIC         129 :         options.must_return_tuples = true;
    3636             129 :         options.dest = treceiver;
    3637 ECB             : 
    3638 CBC         129 :         rc = SPI_execute_extended(querystr, &options);
    3639 GIC         126 :         if (rc < 0)
    3640 LBC           0 :             elog(ERROR, "SPI_execute_extended failed executing query \"%s\": %s",
    3641 ECB             :                  querystr, SPI_result_code_string(rc));
    3642                 :     }
    3643                 : 
    3644                 :     /* Clean up */
    3645 CBC        1327 :     treceiver->rDestroy(treceiver);
    3646 GBC        1327 :     exec_eval_cleanup(estate);
    3647 GIC        1327 :     MemoryContextReset(stmt_mcontext);
    3648                 : 
    3649                 :     /* Count how many tuples we got */
    3650            1327 :     processed = tuplestore_tuple_count(estate->tuple_store) - tcount;
    3651 ECB             : 
    3652 CBC        1327 :     estate->eval_processed = processed;
    3653            1327 :     exec_set_found(estate, processed != 0);
    3654                 : 
    3655 GIC        1327 :     return PLPGSQL_RC_OK;
    3656 ECB             : }
    3657                 : 
    3658                 : static void
    3659 CBC        1679 : exec_init_tuple_store(PLpgSQL_execstate *estate)
    3660                 : {
    3661            1679 :     ReturnSetInfo *rsi = estate->rsi;
    3662                 :     MemoryContext oldcxt;
    3663                 :     ResourceOwner oldowner;
    3664                 : 
    3665 ECB             :     /*
    3666                 :      * Check caller can handle a set result in the way we want
    3667                 :      */
    3668 GIC        1679 :     if (!rsi || !IsA(rsi, ReturnSetInfo))
    3669 UIC           0 :         ereport(ERROR,
    3670                 :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    3671                 :                  errmsg("set-valued function called in context that cannot accept a set")));
    3672                 : 
    3673 GIC        1679 :     if (!(rsi->allowedModes & SFRM_Materialize) ||
    3674 CBC        1679 :         rsi->expectedDesc == NULL)
    3675 UBC           0 :         ereport(ERROR,
    3676                 :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    3677                 :                  errmsg("materialize mode required, but it is not allowed in this context")));
    3678                 : 
    3679 ECB             :     /*
    3680                 :      * Switch to the right memory context and resource owner for storing the
    3681 EUB             :      * tuplestore for return set. If we're within a subtransaction opened for
    3682                 :      * an exception-block, for example, we must still create the tuplestore in
    3683                 :      * the resource owner that was active when this function was entered, and
    3684                 :      * not in the subtransaction resource owner.
    3685                 :      */
    3686 GIC        1679 :     oldcxt = MemoryContextSwitchTo(estate->tuple_store_cxt);
    3687            1679 :     oldowner = CurrentResourceOwner;
    3688            1679 :     CurrentResourceOwner = estate->tuple_store_owner;
    3689                 : 
    3690            1679 :     estate->tuple_store =
    3691            1679 :         tuplestore_begin_heap(rsi->allowedModes & SFRM_Materialize_Random,
    3692 ECB             :                               false, work_mem);
    3693                 : 
    3694 CBC        1679 :     CurrentResourceOwner = oldowner;
    3695 GIC        1679 :     MemoryContextSwitchTo(oldcxt);
    3696 ECB             : 
    3697 CBC        1679 :     estate->tuple_store_desc = rsi->expectedDesc;
    3698 GIC        1679 : }
    3699                 : 
    3700 ECB             : #define SET_RAISE_OPTION_TEXT(opt, name) \
    3701                 : do { \
    3702                 :     if (opt) \
    3703                 :         ereport(ERROR, \
    3704                 :                 (errcode(ERRCODE_SYNTAX_ERROR), \
    3705                 :                  errmsg("RAISE option already specified: %s", \
    3706                 :                         name))); \
    3707                 :     opt = MemoryContextStrdup(stmt_mcontext, extval); \
    3708                 : } while (0)
    3709                 : 
    3710                 : /* ----------
    3711                 :  * exec_stmt_raise          Build a message and throw it with elog()
    3712                 :  * ----------
    3713                 :  */
    3714                 : static int
    3715 GIC        6940 : exec_stmt_raise(PLpgSQL_execstate *estate, PLpgSQL_stmt_raise *stmt)
    3716                 : {
    3717            6940 :     int         err_code = 0;
    3718            6940 :     char       *condname = NULL;
    3719            6940 :     char       *err_message = NULL;
    3720            6940 :     char       *err_detail = NULL;
    3721 CBC        6940 :     char       *err_hint = NULL;
    3722 GIC        6940 :     char       *err_column = NULL;
    3723 CBC        6940 :     char       *err_constraint = NULL;
    3724            6940 :     char       *err_datatype = NULL;
    3725            6940 :     char       *err_table = NULL;
    3726            6940 :     char       *err_schema = NULL;
    3727 ECB             :     MemoryContext stmt_mcontext;
    3728                 :     ListCell   *lc;
    3729                 : 
    3730                 :     /* RAISE with no parameters: re-throw current exception */
    3731 CBC        6940 :     if (stmt->condname == NULL && stmt->message == NULL &&
    3732              27 :         stmt->options == NIL)
    3733                 :     {
    3734 GIC          18 :         if (estate->cur_error != NULL)
    3735              15 :             ReThrowError(estate->cur_error);
    3736                 :         /* oops, we're not inside a handler */
    3737 CBC           3 :         ereport(ERROR,
    3738 ECB             :                 (errcode(ERRCODE_STACKED_DIAGNOSTICS_ACCESSED_WITHOUT_ACTIVE_HANDLER),
    3739                 :                  errmsg("RAISE without parameters cannot be used outside an exception handler")));
    3740                 :     }
    3741                 : 
    3742                 :     /* We'll need to accumulate the various strings in stmt_mcontext */
    3743 CBC        6922 :     stmt_mcontext = get_stmt_mcontext(estate);
    3744                 : 
    3745 GIC        6922 :     if (stmt->condname)
    3746                 :     {
    3747             329 :         err_code = plpgsql_recognize_err_condition(stmt->condname, true);
    3748             329 :         condname = MemoryContextStrdup(stmt_mcontext, stmt->condname);
    3749 ECB             :     }
    3750                 : 
    3751 CBC        6922 :     if (stmt->message)
    3752                 :     {
    3753 ECB             :         StringInfoData ds;
    3754                 :         ListCell   *current_param;
    3755                 :         char       *cp;
    3756                 :         MemoryContext oldcontext;
    3757                 : 
    3758                 :         /* build string in stmt_mcontext */
    3759 GIC        6584 :         oldcontext = MemoryContextSwitchTo(stmt_mcontext);
    3760            6584 :         initStringInfo(&ds);
    3761            6584 :         MemoryContextSwitchTo(oldcontext);
    3762                 : 
    3763            6584 :         current_param = list_head(stmt->params);
    3764                 : 
    3765 CBC      130455 :         for (cp = stmt->message; *cp; cp++)
    3766 ECB             :         {
    3767                 :             /*
    3768                 :              * Occurrences of a single % are replaced by the next parameter's
    3769                 :              * external representation. Double %'s are converted to one %.
    3770                 :              */
    3771 CBC      123884 :             if (cp[0] == '%')
    3772                 :             {
    3773                 :                 Oid         paramtypeid;
    3774                 :                 int32       paramtypmod;
    3775                 :                 Datum       paramvalue;
    3776                 :                 bool        paramisnull;
    3777 ECB             :                 char       *extval;
    3778                 : 
    3779 GIC       16937 :                 if (cp[1] == '%')
    3780                 :                 {
    3781               3 :                     appendStringInfoChar(&ds, '%');
    3782               3 :                     cp++;
    3783               3 :                     continue;
    3784                 :                 }
    3785 ECB             : 
    3786                 :                 /* should have been checked at compile time */
    3787 CBC       16934 :                 if (current_param == NULL)
    3788 LBC           0 :                     elog(ERROR, "unexpected RAISE parameter list length");
    3789 ECB             : 
    3790 GIC       16934 :                 paramvalue = exec_eval_expr(estate,
    3791           16934 :                                             (PLpgSQL_expr *) lfirst(current_param),
    3792                 :                                             &paramisnull,
    3793 ECB             :                                             &paramtypeid,
    3794 EUB             :                                             &paramtypmod);
    3795                 : 
    3796 CBC       16921 :                 if (paramisnull)
    3797             175 :                     extval = "<NULL>";
    3798                 :                 else
    3799 GIC       16746 :                     extval = convert_value_to_string(estate,
    3800                 :                                                      paramvalue,
    3801                 :                                                      paramtypeid);
    3802 CBC       16921 :                 appendStringInfoString(&ds, extval);
    3803           16921 :                 current_param = lnext(stmt->params, current_param);
    3804 GIC       16921 :                 exec_eval_cleanup(estate);
    3805 ECB             :             }
    3806                 :             else
    3807 GIC      106947 :                 appendStringInfoChar(&ds, cp[0]);
    3808 ECB             :         }
    3809                 : 
    3810                 :         /* should have been checked at compile time */
    3811 GIC        6571 :         if (current_param != NULL)
    3812 UIC           0 :             elog(ERROR, "unexpected RAISE parameter list length");
    3813 ECB             : 
    3814 GIC        6571 :         err_message = ds.data;
    3815                 :     }
    3816                 : 
    3817 CBC        7294 :     foreach(lc, stmt->options)
    3818 EUB             :     {
    3819 GIC         391 :         PLpgSQL_raise_option *opt = (PLpgSQL_raise_option *) lfirst(lc);
    3820 ECB             :         Datum       optionvalue;
    3821                 :         bool        optionisnull;
    3822                 :         Oid         optiontypeid;
    3823                 :         int32       optiontypmod;
    3824                 :         char       *extval;
    3825                 : 
    3826 GIC         391 :         optionvalue = exec_eval_expr(estate, opt->expr,
    3827                 :                                      &optionisnull,
    3828                 :                                      &optiontypeid,
    3829                 :                                      &optiontypmod);
    3830             391 :         if (optionisnull)
    3831 UIC           0 :             ereport(ERROR,
    3832 ECB             :                     (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
    3833                 :                      errmsg("RAISE statement option cannot be null")));
    3834                 : 
    3835 GIC         391 :         extval = convert_value_to_string(estate, optionvalue, optiontypeid);
    3836 ECB             : 
    3837 GBC         391 :         switch (opt->opt_type)
    3838                 :         {
    3839 GIC          21 :             case PLPGSQL_RAISEOPTION_ERRCODE:
    3840              21 :                 if (err_code)
    3841 CBC           3 :                     ereport(ERROR,
    3842                 :                             (errcode(ERRCODE_SYNTAX_ERROR),
    3843 ECB             :                              errmsg("RAISE option already specified: %s",
    3844                 :                                     "ERRCODE")));
    3845 CBC          18 :                 err_code = plpgsql_recognize_err_condition(extval, true);
    3846              18 :                 condname = MemoryContextStrdup(stmt_mcontext, extval);
    3847              18 :                 break;
    3848 GIC         320 :             case PLPGSQL_RAISEOPTION_MESSAGE:
    3849             320 :                 SET_RAISE_OPTION_TEXT(err_message, "MESSAGE");
    3850             317 :                 break;
    3851 CBC          23 :             case PLPGSQL_RAISEOPTION_DETAIL:
    3852              23 :                 SET_RAISE_OPTION_TEXT(err_detail, "DETAIL");
    3853              23 :                 break;
    3854               7 :             case PLPGSQL_RAISEOPTION_HINT:
    3855               7 :                 SET_RAISE_OPTION_TEXT(err_hint, "HINT");
    3856               7 :                 break;
    3857               4 :             case PLPGSQL_RAISEOPTION_COLUMN:
    3858               4 :                 SET_RAISE_OPTION_TEXT(err_column, "COLUMN");
    3859               4 :                 break;
    3860               4 :             case PLPGSQL_RAISEOPTION_CONSTRAINT:
    3861               4 :                 SET_RAISE_OPTION_TEXT(err_constraint, "CONSTRAINT");
    3862               4 :                 break;
    3863               4 :             case PLPGSQL_RAISEOPTION_DATATYPE:
    3864               4 :                 SET_RAISE_OPTION_TEXT(err_datatype, "DATATYPE");
    3865               4 :                 break;
    3866               4 :             case PLPGSQL_RAISEOPTION_TABLE:
    3867               4 :                 SET_RAISE_OPTION_TEXT(err_table, "TABLE");
    3868               4 :                 break;
    3869               4 :             case PLPGSQL_RAISEOPTION_SCHEMA:
    3870               4 :                 SET_RAISE_OPTION_TEXT(err_schema, "SCHEMA");
    3871               4 :                 break;
    3872 LBC           0 :             default:
    3873               0 :                 elog(ERROR, "unrecognized raise option: %d", opt->opt_type);
    3874 ECB             :         }
    3875                 : 
    3876 CBC         385 :         exec_eval_cleanup(estate);
    3877 ECB             :     }
    3878 EUB             : 
    3879                 :     /* Default code if nothing specified */
    3880 GIC        6903 :     if (err_code == 0 && stmt->elog_level >= ERROR)
    3881             110 :         err_code = ERRCODE_RAISE_EXCEPTION;
    3882 ECB             : 
    3883                 :     /* Default error message if nothing specified */
    3884 GIC        6903 :     if (err_message == NULL)
    3885                 :     {
    3886 CBC          21 :         if (condname)
    3887 ECB             :         {
    3888 GIC          18 :             err_message = condname;
    3889              18 :             condname = NULL;
    3890 ECB             :         }
    3891                 :         else
    3892 CBC           3 :             err_message = MemoryContextStrdup(stmt_mcontext,
    3893 GIC           3 :                                               unpack_sql_state(err_code));
    3894 ECB             :     }
    3895                 : 
    3896                 :     /*
    3897                 :      * Throw the error (may or may not come back)
    3898                 :      */
    3899 CBC        6903 :     ereport(stmt->elog_level,
    3900                 :             (err_code ? errcode(err_code) : 0,
    3901                 :              errmsg_internal("%s", err_message),
    3902                 :              (err_detail != NULL) ? errdetail_internal("%s", err_detail) : 0,
    3903                 :              (err_hint != NULL) ? errhint("%s", err_hint) : 0,
    3904                 :              (err_column != NULL) ?
    3905 ECB             :              err_generic_string(PG_DIAG_COLUMN_NAME, err_column) : 0,
    3906                 :              (err_constraint != NULL) ?
    3907                 :              err_generic_string(PG_DIAG_CONSTRAINT_NAME, err_constraint) : 0,
    3908                 :              (err_datatype != NULL) ?
    3909                 :              err_generic_string(PG_DIAG_DATATYPE_NAME, err_datatype) : 0,
    3910                 :              (err_table != NULL) ?
    3911                 :              err_generic_string(PG_DIAG_TABLE_NAME, err_table) : 0,
    3912                 :              (err_schema != NULL) ?
    3913                 :              err_generic_string(PG_DIAG_SCHEMA_NAME, err_schema) : 0));
    3914                 : 
    3915                 :     /* Clean up transient strings */
    3916 GIC        6452 :     MemoryContextReset(stmt_mcontext);
    3917                 : 
    3918            6452 :     return PLPGSQL_RC_OK;
    3919                 : }
    3920                 : 
    3921                 : /* ----------
    3922 ECB             :  * exec_stmt_assert         Assert statement
    3923                 :  * ----------
    3924                 :  */
    3925                 : static int
    3926 GIC        4357 : exec_stmt_assert(PLpgSQL_execstate *estate, PLpgSQL_stmt_assert *stmt)
    3927                 : {
    3928                 :     bool        value;
    3929                 :     bool        isnull;
    3930                 : 
    3931                 :     /* do nothing when asserts are not enabled */
    3932 CBC        4357 :     if (!plpgsql_check_asserts)
    3933 GIC           3 :         return PLPGSQL_RC_OK;
    3934                 : 
    3935            4354 :     value = exec_eval_boolean(estate, stmt->cond, &isnull);
    3936            4354 :     exec_eval_cleanup(estate);
    3937                 : 
    3938 CBC        4354 :     if (isnull || !value)
    3939 ECB             :     {
    3940 GIC          12 :         char       *message = NULL;
    3941 ECB             : 
    3942 CBC          12 :         if (stmt->message != NULL)
    3943                 :         {
    3944 ECB             :             Datum       val;
    3945                 :             Oid         typeid;
    3946                 :             int32       typmod;
    3947                 : 
    3948 CBC           6 :             val = exec_eval_expr(estate, stmt->message,
    3949                 :                                  &isnull, &typeid, &typmod);
    3950 GIC           6 :             if (!isnull)
    3951               6 :                 message = convert_value_to_string(estate, val, typeid);
    3952                 :             /* we mustn't do exec_eval_cleanup here */
    3953                 :         }
    3954 ECB             : 
    3955 GIC          12 :         ereport(ERROR,
    3956 ECB             :                 (errcode(ERRCODE_ASSERT_FAILURE),
    3957                 :                  message ? errmsg_internal("%s", message) :
    3958                 :                  errmsg("assertion failed")));
    3959                 :     }
    3960                 : 
    3961 CBC        4342 :     return PLPGSQL_RC_OK;
    3962                 : }
    3963                 : 
    3964                 : /* ----------
    3965                 :  * Initialize a mostly empty execution state
    3966                 :  * ----------
    3967 ECB             :  */
    3968                 : static void
    3969 GIC       40078 : plpgsql_estate_setup(PLpgSQL_execstate *estate,
    3970                 :                      PLpgSQL_function *func,
    3971                 :                      ReturnSetInfo *rsi,
    3972                 :                      EState *simple_eval_estate,
    3973                 :                      ResourceOwner simple_eval_resowner)
    3974                 : {
    3975 ECB             :     HASHCTL     ctl;
    3976                 : 
    3977                 :     /* this link will be restored at exit from plpgsql_call_handler */
    3978 GIC       40078 :     func->cur_estate = estate;
    3979                 : 
    3980           40078 :     estate->func = func;
    3981           40078 :     estate->trigdata = NULL;
    3982           40078 :     estate->evtrigdata = NULL;
    3983                 : 
    3984 CBC       40078 :     estate->retval = (Datum) 0;
    3985 GIC       40078 :     estate->retisnull = true;
    3986 CBC       40078 :     estate->rettype = InvalidOid;
    3987 ECB             : 
    3988 CBC       40078 :     estate->fn_rettype = func->fn_rettype;
    3989 GIC       40078 :     estate->retistuple = func->fn_retistuple;
    3990 CBC       40078 :     estate->retisset = func->fn_retset;
    3991 ECB             : 
    3992 CBC       40078 :     estate->readonly_func = func->fn_readonly;
    3993 GIC       40078 :     estate->atomic = true;
    3994 ECB             : 
    3995 CBC       40078 :     estate->exitlabel = NULL;
    3996           40078 :     estate->cur_error = NULL;
    3997                 : 
    3998           40078 :     estate->tuple_store = NULL;
    3999           40078 :     estate->tuple_store_desc = NULL;
    4000 GIC       40078 :     if (rsi)
    4001 ECB             :     {
    4002 CBC        1836 :         estate->tuple_store_cxt = rsi->econtext->ecxt_per_query_memory;
    4003 GIC        1836 :         estate->tuple_store_owner = CurrentResourceOwner;
    4004 ECB             :     }
    4005                 :     else
    4006                 :     {
    4007 GIC       38242 :         estate->tuple_store_cxt = NULL;
    4008 CBC       38242 :         estate->tuple_store_owner = NULL;
    4009 ECB             :     }
    4010 GIC       40078 :     estate->rsi = rsi;
    4011                 : 
    4012           40078 :     estate->found_varno = func->found_varno;
    4013 CBC       40078 :     estate->ndatums = func->ndatums;
    4014           40078 :     estate->datums = NULL;
    4015                 :     /* the datums array will be filled by copy_plpgsql_datums() */
    4016           40078 :     estate->datum_context = CurrentMemoryContext;
    4017                 : 
    4018 ECB             :     /* initialize our ParamListInfo with appropriate hook functions */
    4019 CBC       40078 :     estate->paramLI = makeParamList(0);
    4020           40078 :     estate->paramLI->paramFetch = plpgsql_param_fetch;
    4021 GIC       40078 :     estate->paramLI->paramFetchArg = (void *) estate;
    4022 CBC       40078 :     estate->paramLI->paramCompile = plpgsql_param_compile;
    4023 GIC       40078 :     estate->paramLI->paramCompileArg = NULL;  /* not needed */
    4024           40078 :     estate->paramLI->parserSetup = (ParserSetupHook) plpgsql_parser_setup;
    4025 CBC       40078 :     estate->paramLI->parserSetupArg = NULL; /* filled during use */
    4026           40078 :     estate->paramLI->numParams = estate->ndatums;
    4027 ECB             : 
    4028                 :     /* set up for use of appropriate simple-expression EState and cast hash */
    4029 CBC       40078 :     if (simple_eval_estate)
    4030 ECB             :     {
    4031 CBC         450 :         estate->simple_eval_estate = simple_eval_estate;
    4032 ECB             :         /* Private cast hash just lives in function's main context */
    4033 GIC         450 :         ctl.keysize = sizeof(plpgsql_CastHashKey);
    4034             450 :         ctl.entrysize = sizeof(plpgsql_CastHashEntry);
    4035 CBC         450 :         ctl.hcxt = CurrentMemoryContext;
    4036 GIC         450 :         estate->cast_hash = hash_create("PLpgSQL private cast cache",
    4037 ECB             :                                         16, /* start small and extend */
    4038                 :                                         &ctl,
    4039                 :                                         HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
    4040 CBC         450 :         estate->cast_hash_context = CurrentMemoryContext;
    4041 ECB             :     }
    4042                 :     else
    4043                 :     {
    4044 GIC       39628 :         estate->simple_eval_estate = shared_simple_eval_estate;
    4045                 :         /* Create the session-wide cast-info hash table if we didn't already */
    4046 CBC       39628 :         if (shared_cast_hash == NULL)
    4047                 :         {
    4048 GIC         268 :             shared_cast_context = AllocSetContextCreate(TopMemoryContext,
    4049                 :                                                         "PLpgSQL cast info",
    4050 ECB             :                                                         ALLOCSET_DEFAULT_SIZES);
    4051 GIC         268 :             ctl.keysize = sizeof(plpgsql_CastHashKey);
    4052 CBC         268 :             ctl.entrysize = sizeof(plpgsql_CastHashEntry);
    4053 GIC         268 :             ctl.hcxt = shared_cast_context;
    4054 CBC         268 :             shared_cast_hash = hash_create("PLpgSQL cast cache",
    4055                 :                                            16,  /* start small and extend */
    4056                 :                                            &ctl,
    4057 ECB             :                                            HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
    4058                 :         }
    4059 CBC       39628 :         estate->cast_hash = shared_cast_hash;
    4060           39628 :         estate->cast_hash_context = shared_cast_context;
    4061                 :     }
    4062                 :     /* likewise for the simple-expression resource owner */
    4063 GIC       40078 :     if (simple_eval_resowner)
    4064             450 :         estate->simple_eval_resowner = simple_eval_resowner;
    4065 ECB             :     else
    4066 CBC       39628 :         estate->simple_eval_resowner = shared_simple_eval_resowner;
    4067                 : 
    4068                 :     /* if there's a procedure resowner, it'll be filled in later */
    4069           40078 :     estate->procedure_resowner = NULL;
    4070 ECB             : 
    4071                 :     /*
    4072                 :      * We start with no stmt_mcontext; one will be created only if needed.
    4073                 :      * That context will be a direct child of the function's main execution
    4074                 :      * context.  Additional stmt_mcontexts might be created as children of it.
    4075                 :      */
    4076 GIC       40078 :     estate->stmt_mcontext = NULL;
    4077           40078 :     estate->stmt_mcontext_parent = CurrentMemoryContext;
    4078                 : 
    4079           40078 :     estate->eval_tuptable = NULL;
    4080           40078 :     estate->eval_processed = 0;
    4081           40078 :     estate->eval_econtext = NULL;
    4082 ECB             : 
    4083 CBC       40078 :     estate->err_stmt = NULL;
    4084 GIC       40078 :     estate->err_var = NULL;
    4085 CBC       40078 :     estate->err_text = NULL;
    4086 ECB             : 
    4087 CBC       40078 :     estate->plugin_info = NULL;
    4088                 : 
    4089 ECB             :     /*
    4090                 :      * Create an EState and ExprContext for evaluation of simple expressions.
    4091                 :      */
    4092 GIC       40078 :     plpgsql_create_econtext(estate);
    4093 ECB             : 
    4094                 :     /*
    4095                 :      * Let the plugin, if any, see this function before we initialize local
    4096                 :      * PL/pgSQL variables.  Note that we also give the plugin a few function
    4097                 :      * pointers, so it can call back into PL/pgSQL for doing things like
    4098                 :      * variable assignments and stack traces.
    4099                 :      */
    4100 GIC       40078 :     if (*plpgsql_plugin_ptr)
    4101                 :     {
    4102 UIC           0 :         (*plpgsql_plugin_ptr)->error_callback = plpgsql_exec_error_callback;
    4103               0 :         (*plpgsql_plugin_ptr)->assign_expr = exec_assign_expr;
    4104               0 :         (*plpgsql_plugin_ptr)->assign_value = exec_assign_value;
    4105               0 :         (*plpgsql_plugin_ptr)->eval_datum = exec_eval_datum;
    4106 LBC           0 :         (*plpgsql_plugin_ptr)->cast_value = exec_cast_value;
    4107                 : 
    4108 UBC           0 :         if ((*plpgsql_plugin_ptr)->func_setup)
    4109               0 :             ((*plpgsql_plugin_ptr)->func_setup) (estate, func);
    4110 EUB             :     }
    4111 GBC       40078 : }
    4112 EUB             : 
    4113                 : /* ----------
    4114                 :  * Release temporary memory used by expression/subselect evaluation
    4115                 :  *
    4116                 :  * NB: the result of the evaluation is no longer valid after this is done,
    4117 ECB             :  * unless it is a pass-by-value datatype.
    4118                 :  * ----------
    4119                 :  */
    4120                 : static void
    4121 GIC      203064 : exec_eval_cleanup(PLpgSQL_execstate *estate)
    4122                 : {
    4123                 :     /* Clear result of a full SPI_execute */
    4124          203064 :     if (estate->eval_tuptable != NULL)
    4125            3354 :         SPI_freetuptable(estate->eval_tuptable);
    4126          203064 :     estate->eval_tuptable = NULL;
    4127 ECB             : 
    4128                 :     /*
    4129                 :      * Clear result of exec_eval_simple_expr (but keep the econtext).  This
    4130                 :      * also clears any short-lived allocations done via get_eval_mcontext.
    4131                 :      */
    4132 CBC      203064 :     if (estate->eval_econtext != NULL)
    4133 GIC      163553 :         ResetExprContext(estate->eval_econtext);
    4134          203064 : }
    4135                 : 
    4136                 : 
    4137                 : /* ----------
    4138 ECB             :  * Generate a prepared plan
    4139                 :  *
    4140                 :  * CAUTION: it is possible for this function to throw an error after it has
    4141                 :  * built a SPIPlan and saved it in expr->plan.  Therefore, be wary of doing
    4142                 :  * additional things contingent on expr->plan being NULL.  That is, given
    4143                 :  * code like
    4144                 :  *
    4145                 :  *  if (query->plan == NULL)
    4146                 :  *  {
    4147                 :  *      // okay to put setup code here
    4148                 :  *      exec_prepare_plan(estate, query, ...);
    4149                 :  *      // NOT okay to put more logic here
    4150                 :  *  }
    4151                 :  *
    4152                 :  * extra steps at the end are unsafe because they will not be executed when
    4153                 :  * re-executing the calling statement, if exec_prepare_plan failed the first
    4154                 :  * time.  This is annoyingly error-prone, but the alternatives are worse.
    4155                 :  * ----------
    4156                 :  */
    4157                 : static void
    4158 GIC       11590 : exec_prepare_plan(PLpgSQL_execstate *estate,
    4159                 :                   PLpgSQL_expr *expr, int cursorOptions)
    4160                 : {
    4161                 :     SPIPlanPtr  plan;
    4162                 :     SPIPrepareOptions options;
    4163                 : 
    4164 ECB             :     /*
    4165                 :      * The grammar can't conveniently set expr->func while building the parse
    4166                 :      * tree, so make sure it's set before parser hooks need it.
    4167                 :      */
    4168 GIC       11590 :     expr->func = estate->func;
    4169                 : 
    4170                 :     /*
    4171                 :      * Generate and save the plan
    4172                 :      */
    4173           11590 :     memset(&options, 0, sizeof(options));
    4174 CBC       11590 :     options.parserSetup = (ParserSetupHook) plpgsql_parser_setup;
    4175 GIC       11590 :     options.parserSetupArg = (void *) expr;
    4176           11590 :     options.parseMode = expr->parseMode;
    4177           11590 :     options.cursorOptions = cursorOptions;
    4178           11590 :     plan = SPI_prepare_extended(expr->query, &options);
    4179 CBC       11547 :     if (plan == NULL)
    4180 LBC           0 :         elog(ERROR, "SPI_prepare_extended failed for \"%s\": %s",
    4181 ECB             :              expr->query, SPI_result_code_string(SPI_result));
    4182                 : 
    4183 CBC       11547 :     SPI_keepplan(plan);
    4184           11547 :     expr->plan = plan;
    4185 ECB             : 
    4186 EUB             :     /* Check to see if it's a simple expression */
    4187 GIC       11547 :     exec_simple_check_plan(estate, expr);
    4188           11531 : }
    4189 ECB             : 
    4190                 : 
    4191                 : /* ----------
    4192                 :  * exec_stmt_execsql            Execute an SQL statement (possibly with INTO).
    4193                 :  *
    4194                 :  * Note: some callers rely on this not touching stmt_mcontext.  If it ever
    4195                 :  * needs to use that, fix those callers to push/pop stmt_mcontext.
    4196                 :  * ----------
    4197                 :  */
    4198                 : static int
    4199 GIC       25022 : exec_stmt_execsql(PLpgSQL_execstate *estate,
    4200                 :                   PLpgSQL_stmt_execsql *stmt)
    4201                 : {
    4202                 :     ParamListInfo paramLI;
    4203                 :     long        tcount;
    4204                 :     int         rc;
    4205 CBC       25022 :     PLpgSQL_expr *expr = stmt->sqlstmt;
    4206 GIC       25022 :     int         too_many_rows_level = 0;
    4207                 : 
    4208           25022 :     if (plpgsql_extra_errors & PLPGSQL_XCHECK_TOOMANYROWS)
    4209               3 :         too_many_rows_level = ERROR;
    4210           25019 :     else if (plpgsql_extra_warnings & PLPGSQL_XCHECK_TOOMANYROWS)
    4211 CBC           3 :         too_many_rows_level = WARNING;
    4212 ECB             : 
    4213                 :     /*
    4214                 :      * On the first call for this statement generate the plan, and detect
    4215                 :      * whether the statement is INSERT/UPDATE/DELETE/MERGE
    4216                 :      */
    4217 CBC       25022 :     if (expr->plan == NULL)
    4218 GIC         839 :         exec_prepare_plan(estate, expr, CURSOR_OPT_PARALLEL_OK);
    4219                 : 
    4220           25017 :     if (!stmt->mod_stmt_set)
    4221                 :     {
    4222                 :         ListCell   *l;
    4223 ECB             : 
    4224 CBC         842 :         stmt->mod_stmt = false;
    4225 GIC        1378 :         foreach(l, SPI_plan_get_plan_sources(expr->plan))
    4226 ECB             :         {
    4227 GIC         842 :             CachedPlanSource *plansource = (CachedPlanSource *) lfirst(l);
    4228                 : 
    4229                 :             /*
    4230 ECB             :              * We could look at the raw_parse_tree, but it seems simpler to
    4231                 :              * check the command tag.  Note we should *not* look at the Query
    4232                 :              * tree(s), since those are the result of rewriting and could have
    4233                 :              * been transmogrified into something else entirely.
    4234                 :              */
    4235 GIC         842 :             if (plansource->commandTag == CMDTAG_INSERT ||
    4236             669 :                 plansource->commandTag == CMDTAG_UPDATE ||
    4237             583 :                 plansource->commandTag == CMDTAG_DELETE ||
    4238             548 :                 plansource->commandTag == CMDTAG_MERGE)
    4239                 :             {
    4240             306 :                 stmt->mod_stmt = true;
    4241 CBC         306 :                 break;
    4242 ECB             :             }
    4243                 :         }
    4244 CBC         842 :         stmt->mod_stmt_set = true;
    4245                 :     }
    4246 ECB             : 
    4247                 :     /*
    4248                 :      * Set up ParamListInfo to pass to executor
    4249                 :      */
    4250 CBC       25017 :     paramLI = setup_param_list(estate, expr);
    4251                 : 
    4252                 :     /*
    4253                 :      * If we have INTO, then we only need one row back ... but if we have INTO
    4254                 :      * STRICT or extra check too_many_rows, ask for two rows, so that we can
    4255                 :      * verify the statement returns only one.  INSERT/UPDATE/DELETE are always
    4256 ECB             :      * treated strictly. Without INTO, just run the statement to completion
    4257                 :      * (tcount = 0).
    4258                 :      *
    4259                 :      * We could just ask for two rows always when using INTO, but there are
    4260                 :      * some cases where demanding the extra row costs significant time, eg by
    4261                 :      * forcing completion of a sequential scan.  So don't do it unless we need
    4262                 :      * to enforce strictness.
    4263                 :      */
    4264 GIC       25017 :     if (stmt->into)
    4265                 :     {
    4266            7369 :         if (stmt->strict || stmt->mod_stmt || too_many_rows_level)
    4267             570 :             tcount = 2;
    4268                 :         else
    4269            6799 :             tcount = 1;
    4270 ECB             :     }
    4271                 :     else
    4272 CBC       17648 :         tcount = 0;
    4273 ECB             : 
    4274                 :     /*
    4275                 :      * Execute the plan
    4276                 :      */
    4277 GIC       25017 :     rc = SPI_execute_plan_with_paramlist(expr->plan, paramLI,
    4278 CBC       25017 :                                          estate->readonly_func, tcount);
    4279                 : 
    4280                 :     /*
    4281                 :      * Check for error, and set FOUND if appropriate (for historical reasons
    4282                 :      * we set FOUND only for certain query types).  Also Assert that we
    4283 ECB             :      * identified the statement type the same as SPI did.
    4284                 :      */
    4285 GIC       23044 :     switch (rc)
    4286                 :     {
    4287            4959 :         case SPI_OK_SELECT:
    4288            4959 :             Assert(!stmt->mod_stmt);
    4289            4959 :             exec_set_found(estate, (SPI_processed != 0));
    4290            4959 :             break;
    4291 ECB             : 
    4292 GIC       12689 :         case SPI_OK_INSERT:
    4293 ECB             :         case SPI_OK_UPDATE:
    4294                 :         case SPI_OK_DELETE:
    4295                 :         case SPI_OK_INSERT_RETURNING:
    4296                 :         case SPI_OK_UPDATE_RETURNING:
    4297                 :         case SPI_OK_DELETE_RETURNING:
    4298                 :         case SPI_OK_MERGE:
    4299 GIC       12689 :             Assert(stmt->mod_stmt);
    4300           12689 :             exec_set_found(estate, (SPI_processed != 0));
    4301           12689 :             break;
    4302                 : 
    4303            5393 :         case SPI_OK_SELINTO:
    4304                 :         case SPI_OK_UTILITY:
    4305 CBC        5393 :             Assert(!stmt->mod_stmt);
    4306            5393 :             break;
    4307 ECB             : 
    4308 UIC           0 :         case SPI_OK_REWRITTEN:
    4309 ECB             : 
    4310                 :             /*
    4311                 :              * The command was rewritten into another kind of command. It's
    4312                 :              * not clear what FOUND would mean in that case (and SPI doesn't
    4313                 :              * return the row count either), so just set it to false.  Note
    4314 EUB             :              * that we can't assert anything about mod_stmt here.
    4315                 :              */
    4316 UIC           0 :             exec_set_found(estate, false);
    4317               0 :             break;
    4318                 : 
    4319                 :             /* Some SPI errors deserve specific error messages */
    4320 GIC           2 :         case SPI_ERROR_COPY:
    4321               2 :             ereport(ERROR,
    4322 EUB             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4323                 :                      errmsg("cannot COPY to/from client in PL/pgSQL")));
    4324                 :             break;
    4325                 : 
    4326 CBC           1 :         case SPI_ERROR_TRANSACTION:
    4327               1 :             ereport(ERROR,
    4328                 :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4329                 :                      errmsg("unsupported transaction command in PL/pgSQL")));
    4330                 :             break;
    4331                 : 
    4332 LBC           0 :         default:
    4333               0 :             elog(ERROR, "SPI_execute_plan_with_paramlist failed executing query \"%s\": %s",
    4334                 :                  expr->query, SPI_result_code_string(rc));
    4335                 :             break;
    4336                 :     }
    4337                 : 
    4338 EUB             :     /* All variants should save result info for GET DIAGNOSTICS */
    4339 GBC       23041 :     estate->eval_processed = SPI_processed;
    4340                 : 
    4341                 :     /* Process INTO if present */
    4342 GIC       23041 :     if (stmt->into)
    4343                 :     {
    4344            5428 :         SPITupleTable *tuptab = SPI_tuptable;
    4345 CBC        5428 :         uint64      n = SPI_processed;
    4346                 :         PLpgSQL_variable *target;
    4347                 : 
    4348 ECB             :         /* If the statement did not return a tuple table, complain */
    4349 GIC        5428 :         if (tuptab == NULL)
    4350 LBC           0 :             ereport(ERROR,
    4351 ECB             :                     (errcode(ERRCODE_SYNTAX_ERROR),
    4352                 :                      errmsg("INTO used with a command that cannot return data")));
    4353                 : 
    4354                 :         /* Fetch target's datum entry */
    4355 CBC        5428 :         target = (PLpgSQL_variable *) estate->datums[stmt->target->dno];
    4356 EUB             : 
    4357                 :         /*
    4358                 :          * If SELECT ... INTO specified STRICT, and the query didn't find
    4359                 :          * exactly one row, throw an error.  If STRICT was not specified, then
    4360                 :          * allow the query to find any number of rows.
    4361 ECB             :          */
    4362 GIC        5428 :         if (n == 0)
    4363                 :         {
    4364              31 :             if (stmt->strict)
    4365                 :             {
    4366                 :                 char       *errdetail;
    4367                 : 
    4368 CBC           9 :                 if (estate->func->print_strict_params)
    4369 GIC           6 :                     errdetail = format_expr_params(estate, expr);
    4370 ECB             :                 else
    4371 GIC           3 :                     errdetail = NULL;
    4372                 : 
    4373               9 :                 ereport(ERROR,
    4374 ECB             :                         (errcode(ERRCODE_NO_DATA_FOUND),
    4375                 :                          errmsg("query returned no rows"),
    4376                 :                          errdetail ? errdetail_internal("parameters: %s", errdetail) : 0));
    4377                 :             }
    4378                 :             /* set the target to NULL(s) */
    4379 CBC          22 :             exec_move_row(estate, target, NULL, tuptab->tupdesc);
    4380                 :         }
    4381                 :         else
    4382                 :         {
    4383 GIC        5397 :             if (n > 1 && (stmt->strict || stmt->mod_stmt || too_many_rows_level))
    4384                 :             {
    4385 ECB             :                 char       *errdetail;
    4386                 :                 int         errlevel;
    4387                 : 
    4388 GIC          24 :                 if (estate->func->print_strict_params)
    4389 CBC           9 :                     errdetail = format_expr_params(estate, expr);
    4390                 :                 else
    4391 GIC          15 :                     errdetail = NULL;
    4392                 : 
    4393              24 :                 errlevel = (stmt->strict || stmt->mod_stmt) ? ERROR : too_many_rows_level;
    4394 ECB             : 
    4395 CBC          24 :                 ereport(errlevel,
    4396                 :                         (errcode(ERRCODE_TOO_MANY_ROWS),
    4397 ECB             :                          errmsg("query returned more than one row"),
    4398                 :                          errdetail ? errdetail_internal("parameters: %s", errdetail) : 0,
    4399                 :                          errhint("Make sure the query returns a single row, or use LIMIT 1.")));
    4400                 :             }
    4401                 :             /* Put the first result row into the target */
    4402 GIC        5376 :             exec_move_row(estate, target, tuptab->vals[0], tuptab->tupdesc);
    4403                 :         }
    4404                 : 
    4405                 :         /* Clean up */
    4406            5386 :         exec_eval_cleanup(estate);
    4407            5386 :         SPI_freetuptable(SPI_tuptable);
    4408 ECB             :     }
    4409                 :     else
    4410                 :     {
    4411                 :         /* If the statement returned a tuple table, complain */
    4412 CBC       17613 :         if (SPI_tuptable != NULL)
    4413 LBC           0 :             ereport(ERROR,
    4414                 :                     (errcode(ERRCODE_SYNTAX_ERROR),
    4415                 :                      errmsg("query has no destination for result data"),
    4416                 :                      (rc == SPI_OK_SELECT) ? errhint("If you want to discard the results of a SELECT, use PERFORM instead.") : 0));
    4417                 :     }
    4418 ECB             : 
    4419 GBC       22999 :     return PLPGSQL_RC_OK;
    4420                 : }
    4421                 : 
    4422                 : 
    4423                 : /* ----------
    4424                 :  * exec_stmt_dynexecute         Execute a dynamic SQL query
    4425 ECB             :  *                  (possibly with INTO).
    4426                 :  * ----------
    4427                 :  */
    4428                 : static int
    4429 GIC        5226 : exec_stmt_dynexecute(PLpgSQL_execstate *estate,
    4430                 :                      PLpgSQL_stmt_dynexecute *stmt)
    4431                 : {
    4432                 :     Datum       query;
    4433                 :     bool        isnull;
    4434                 :     Oid         restype;
    4435 ECB             :     int32       restypmod;
    4436                 :     char       *querystr;
    4437                 :     int         exec_res;
    4438                 :     ParamListInfo paramLI;
    4439                 :     SPIExecuteOptions options;
    4440 GIC        5226 :     MemoryContext stmt_mcontext = get_stmt_mcontext(estate);
    4441                 : 
    4442                 :     /*
    4443                 :      * First we evaluate the string expression after the EXECUTE keyword. Its
    4444                 :      * result is the querystring we have to execute.
    4445                 :      */
    4446 CBC        5226 :     query = exec_eval_expr(estate, stmt->query, &isnull, &restype, &restypmod);
    4447 GIC        5226 :     if (isnull)
    4448 UIC           0 :         ereport(ERROR,
    4449                 :                 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
    4450                 :                  errmsg("query string argument of EXECUTE is null")));
    4451                 : 
    4452 ECB             :     /* Get the C-String representation */
    4453 CBC        5226 :     querystr = convert_value_to_string(estate, query, restype);
    4454 EUB             : 
    4455                 :     /* copy it into the stmt_mcontext before we clean up */
    4456 GIC        5226 :     querystr = MemoryContextStrdup(stmt_mcontext, querystr);
    4457                 : 
    4458            5226 :     exec_eval_cleanup(estate);
    4459 ECB             : 
    4460                 :     /*
    4461                 :      * Execute the query without preparing a saved plan.
    4462                 :      */
    4463 GIC        5226 :     paramLI = exec_eval_using_params(estate, stmt->params);
    4464 ECB             : 
    4465 GIC        5226 :     memset(&options, 0, sizeof(options));
    4466            5226 :     options.params = paramLI;
    4467            5226 :     options.read_only = estate->readonly_func;
    4468                 : 
    4469 CBC        5226 :     exec_res = SPI_execute_extended(querystr, &options);
    4470                 : 
    4471            5176 :     switch (exec_res)
    4472 ECB             :     {
    4473 CBC        5173 :         case SPI_OK_SELECT:
    4474                 :         case SPI_OK_INSERT:
    4475 ECB             :         case SPI_OK_UPDATE:
    4476                 :         case SPI_OK_DELETE:
    4477                 :         case SPI_OK_INSERT_RETURNING:
    4478                 :         case SPI_OK_UPDATE_RETURNING:
    4479                 :         case SPI_OK_DELETE_RETURNING:
    4480                 :         case SPI_OK_MERGE:
    4481                 :         case SPI_OK_UTILITY:
    4482                 :         case SPI_OK_REWRITTEN:
    4483 GIC        5173 :             break;
    4484                 : 
    4485 UIC           0 :         case 0:
    4486                 : 
    4487                 :             /*
    4488                 :              * Also allow a zero return, which implies the querystring
    4489 ECB             :              * contained no commands.
    4490                 :              */
    4491 UBC           0 :             break;
    4492                 : 
    4493 UIC           0 :         case SPI_OK_SELINTO:
    4494                 : 
    4495                 :             /*
    4496                 :              * We want to disallow SELECT INTO for now, because its behavior
    4497 EUB             :              * is not consistent with SELECT INTO in a normal plpgsql context.
    4498                 :              * (We need to reimplement EXECUTE to parse the string as a
    4499                 :              * plpgsql command, not just feed it to SPI_execute.)  This is not
    4500                 :              * a functional limitation because CREATE TABLE AS is allowed.
    4501                 :              */
    4502 UIC           0 :             ereport(ERROR,
    4503                 :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4504                 :                      errmsg("EXECUTE of SELECT ... INTO is not implemented"),
    4505                 :                      errhint("You might want to use EXECUTE ... INTO or EXECUTE CREATE TABLE ... AS instead.")));
    4506                 :             break;
    4507                 : 
    4508 EUB             :             /* Some SPI errors deserve specific error messages */
    4509 GIC           2 :         case SPI_ERROR_COPY:
    4510               2 :             ereport(ERROR,
    4511                 :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4512                 :                      errmsg("cannot COPY to/from client in PL/pgSQL")));
    4513                 :             break;
    4514                 : 
    4515 CBC           1 :         case SPI_ERROR_TRANSACTION:
    4516               1 :             ereport(ERROR,
    4517                 :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4518                 :                      errmsg("EXECUTE of transaction commands is not implemented")));
    4519                 :             break;
    4520                 : 
    4521 LBC           0 :         default:
    4522               0 :             elog(ERROR, "SPI_execute_extended failed executing query \"%s\": %s",
    4523                 :                  querystr, SPI_result_code_string(exec_res));
    4524                 :             break;
    4525                 :     }
    4526                 : 
    4527 EUB             :     /* Save result info for GET DIAGNOSTICS */
    4528 GBC        5173 :     estate->eval_processed = SPI_processed;
    4529                 : 
    4530                 :     /* Process INTO if present */
    4531 GIC        5173 :     if (stmt->into)
    4532                 :     {
    4533            2918 :         SPITupleTable *tuptab = SPI_tuptable;
    4534 CBC        2918 :         uint64      n = SPI_processed;
    4535                 :         PLpgSQL_variable *target;
    4536                 : 
    4537 ECB             :         /* If the statement did not return a tuple table, complain */
    4538 GIC        2918 :         if (tuptab == NULL)
    4539 LBC           0 :             ereport(ERROR,
    4540 ECB             :                     (errcode(ERRCODE_SYNTAX_ERROR),
    4541                 :                      errmsg("INTO used with a command that cannot return data")));
    4542                 : 
    4543                 :         /* Fetch target's datum entry */
    4544 CBC        2918 :         target = (PLpgSQL_variable *) estate->datums[stmt->target->dno];
    4545 EUB             : 
    4546                 :         /*
    4547                 :          * If SELECT ... INTO specified STRICT, and the query didn't find
    4548                 :          * exactly one row, throw an error.  If STRICT was not specified, then
    4549                 :          * allow the query to find any number of rows.
    4550 ECB             :          */
    4551 GIC        2918 :         if (n == 0)
    4552                 :         {
    4553               6 :             if (stmt->strict)
    4554                 :             {
    4555                 :                 char       *errdetail;
    4556                 : 
    4557 CBC           6 :                 if (estate->func->print_strict_params)
    4558 GIC           3 :                     errdetail = format_preparedparamsdata(estate, paramLI);
    4559 ECB             :                 else
    4560 GIC           3 :                     errdetail = NULL;
    4561                 : 
    4562               6 :                 ereport(ERROR,
    4563 ECB             :                         (errcode(ERRCODE_NO_DATA_FOUND),
    4564                 :                          errmsg("query returned no rows"),
    4565                 :                          errdetail ? errdetail_internal("parameters: %s", errdetail) : 0));
    4566                 :             }
    4567                 :             /* set the target to NULL(s) */
    4568 LBC           0 :             exec_move_row(estate, target, NULL, tuptab->tupdesc);
    4569                 :         }
    4570                 :         else
    4571                 :         {
    4572 GIC        2912 :             if (n > 1 && stmt->strict)
    4573                 :             {
    4574 EUB             :                 char       *errdetail;
    4575                 : 
    4576 GIC           9 :                 if (estate->func->print_strict_params)
    4577               6 :                     errdetail = format_preparedparamsdata(estate, paramLI);
    4578 ECB             :                 else
    4579 GIC           3 :                     errdetail = NULL;
    4580                 : 
    4581               9 :                 ereport(ERROR,
    4582 ECB             :                         (errcode(ERRCODE_TOO_MANY_ROWS),
    4583                 :                          errmsg("query returned more than one row"),
    4584                 :                          errdetail ? errdetail_internal("parameters: %s", errdetail) : 0));
    4585                 :             }
    4586                 : 
    4587                 :             /* Put the first result row into the target */
    4588 GIC        2903 :             exec_move_row(estate, target, tuptab->vals[0], tuptab->tupdesc);
    4589                 :         }
    4590                 :         /* clean up after exec_move_row() */
    4591            2903 :         exec_eval_cleanup(estate);
    4592                 :     }
    4593                 :     else
    4594 ECB             :     {
    4595                 :         /*
    4596                 :          * It might be a good idea to raise an error if the query returned
    4597                 :          * tuples that are being ignored, but historically we have not done
    4598                 :          * that.
    4599                 :          */
    4600                 :     }
    4601                 : 
    4602                 :     /* Release any result from SPI_execute, as well as transient data */
    4603 GIC        5158 :     SPI_freetuptable(SPI_tuptable);
    4604            5158 :     MemoryContextReset(stmt_mcontext);
    4605                 : 
    4606            5158 :     return PLPGSQL_RC_OK;
    4607                 : }
    4608                 : 
    4609 ECB             : 
    4610                 : /* ----------
    4611                 :  * exec_stmt_dynfors            Execute a dynamic query, assign each
    4612                 :  *                  tuple to a record or row and
    4613                 :  *                  execute a group of statements
    4614                 :  *                  for it.
    4615                 :  * ----------
    4616                 :  */
    4617                 : static int
    4618 GIC        4570 : exec_stmt_dynfors(PLpgSQL_execstate *estate, PLpgSQL_stmt_dynfors *stmt)
    4619                 : {
    4620                 :     Portal      portal;
    4621                 :     int         rc;
    4622                 : 
    4623            4570 :     portal = exec_dynquery_with_params(estate, stmt->query, stmt->params,
    4624 ECB             :                                        NULL, CURSOR_OPT_NO_SCROLL);
    4625                 : 
    4626                 :     /*
    4627                 :      * Execute the loop
    4628                 :      */
    4629 CBC        4570 :     rc = exec_for_query(estate, (PLpgSQL_stmt_forq *) stmt, portal, true);
    4630                 : 
    4631                 :     /*
    4632                 :      * Close the implicit cursor
    4633                 :      */
    4634 GIC        4567 :     SPI_cursor_close(portal);
    4635 ECB             : 
    4636 GIC        4567 :     return rc;
    4637                 : }
    4638                 : 
    4639                 : 
    4640 ECB             : /* ----------
    4641                 :  * exec_stmt_open           Execute an OPEN cursor statement
    4642                 :  * ----------
    4643                 :  */
    4644                 : static int
    4645 GIC          69 : exec_stmt_open(PLpgSQL_execstate *estate, PLpgSQL_stmt_open *stmt)
    4646                 : {
    4647                 :     PLpgSQL_var *curvar;
    4648              69 :     MemoryContext stmt_mcontext = NULL;
    4649              69 :     char       *curname = NULL;
    4650                 :     PLpgSQL_expr *query;
    4651 ECB             :     Portal      portal;
    4652                 :     ParamListInfo paramLI;
    4653                 : 
    4654                 :     /* ----------
    4655                 :      * Get the cursor variable and if it has an assigned name, check
    4656                 :      * that it's not in use currently.
    4657                 :      * ----------
    4658                 :      */
    4659 GIC          69 :     curvar = (PLpgSQL_var *) (estate->datums[stmt->curvar]);
    4660              69 :     if (!curvar->isnull)
    4661                 :     {
    4662                 :         MemoryContext oldcontext;
    4663                 : 
    4664                 :         /* We only need stmt_mcontext to hold the cursor name string */
    4665 CBC          12 :         stmt_mcontext = get_stmt_mcontext(estate);
    4666              12 :         oldcontext = MemoryContextSwitchTo(stmt_mcontext);
    4667 GIC          12 :         curname = TextDatumGetCString(curvar->value);
    4668              12 :         MemoryContextSwitchTo(oldcontext);
    4669                 : 
    4670              12 :         if (SPI_cursor_find(curname) != NULL)
    4671 LBC           0 :             ereport(ERROR,
    4672 ECB             :                     (errcode(ERRCODE_DUPLICATE_CURSOR),
    4673                 :                      errmsg("cursor \"%s\" already in use", curname)));
    4674                 :     }
    4675                 : 
    4676                 :     /* ----------
    4677 EUB             :      * Process the OPEN according to it's type.
    4678                 :      * ----------
    4679                 :      */
    4680 GIC          69 :     if (stmt->query != NULL)
    4681                 :     {
    4682                 :         /* ----------
    4683                 :          * This is an OPEN refcursor FOR SELECT ...
    4684                 :          *
    4685                 :          * We just make sure the query is planned. The real work is
    4686 ECB             :          * done downstairs.
    4687                 :          * ----------
    4688                 :          */
    4689 GIC          24 :         query = stmt->query;
    4690              24 :         if (query->plan == NULL)
    4691              18 :             exec_prepare_plan(estate, query, stmt->cursor_options);
    4692                 :     }
    4693              45 :     else if (stmt->dynquery != NULL)
    4694                 :     {
    4695 ECB             :         /* ----------
    4696                 :          * This is an OPEN refcursor FOR EXECUTE ...
    4697                 :          * ----------
    4698                 :          */
    4699 CBC           9 :         portal = exec_dynquery_with_params(estate,
    4700                 :                                            stmt->dynquery,
    4701                 :                                            stmt->params,
    4702                 :                                            curname,
    4703                 :                                            stmt->cursor_options);
    4704                 : 
    4705 ECB             :         /*
    4706                 :          * If cursor variable was NULL, store the generated portal name in it,
    4707                 :          * after verifying it's okay to assign to.
    4708                 :          *
    4709                 :          * Note: exec_dynquery_with_params already reset the stmt_mcontext, so
    4710                 :          * curname is a dangling pointer here; but testing it for nullness is
    4711                 :          * OK.
    4712                 :          */
    4713 GIC           9 :         if (curname == NULL)
    4714                 :         {
    4715               9 :             exec_check_assignable(estate, stmt->curvar);
    4716               9 :             assign_text_var(estate, curvar, portal->name);
    4717                 :         }
    4718                 : 
    4719 CBC           9 :         return PLPGSQL_RC_OK;
    4720                 :     }
    4721 ECB             :     else
    4722                 :     {
    4723                 :         /* ----------
    4724                 :          * This is an OPEN cursor
    4725                 :          *
    4726                 :          * Note: parser should already have checked that statement supplies
    4727                 :          * args iff cursor needs them, but we check again to be safe.
    4728                 :          * ----------
    4729                 :          */
    4730 GIC          36 :         if (stmt->argquery != NULL)
    4731                 :         {
    4732                 :             /* ----------
    4733                 :              * OPEN CURSOR with args.  We fake a SELECT ... INTO ...
    4734                 :              * statement to evaluate the args and put 'em into the
    4735                 :              * internal row.
    4736 ECB             :              * ----------
    4737                 :              */
    4738                 :             PLpgSQL_stmt_execsql set_args;
    4739                 : 
    4740 GIC          24 :             if (curvar->cursor_explicit_argrow < 0)
    4741 UIC           0 :                 ereport(ERROR,
    4742                 :                         (errcode(ERRCODE_SYNTAX_ERROR),
    4743                 :                          errmsg("arguments given for cursor without arguments")));
    4744                 : 
    4745 GIC          24 :             memset(&set_args, 0, sizeof(set_args));
    4746 CBC          24 :             set_args.cmd_type = PLPGSQL_STMT_EXECSQL;
    4747 GBC          24 :             set_args.lineno = stmt->lineno;
    4748 GIC          24 :             set_args.sqlstmt = stmt->argquery;
    4749              24 :             set_args.into = true;
    4750                 :             /* XXX historically this has not been STRICT */
    4751 CBC          24 :             set_args.target = (PLpgSQL_variable *)
    4752              24 :                 (estate->datums[curvar->cursor_explicit_argrow]);
    4753 ECB             : 
    4754 CBC          24 :             if (exec_stmt_execsql(estate, &set_args) != PLPGSQL_RC_OK)
    4755 LBC           0 :                 elog(ERROR, "open cursor failed during argument processing");
    4756                 :         }
    4757 ECB             :         else
    4758                 :         {
    4759 GIC          12 :             if (curvar->cursor_explicit_argrow >= 0)
    4760 LBC           0 :                 ereport(ERROR,
    4761 EUB             :                         (errcode(ERRCODE_SYNTAX_ERROR),
    4762                 :                          errmsg("arguments required for cursor")));
    4763                 :         }
    4764                 : 
    4765 CBC          33 :         query = curvar->cursor_explicit_expr;
    4766 GBC          33 :         if (query->plan == NULL)
    4767 GIC          27 :             exec_prepare_plan(estate, query, curvar->cursor_options);
    4768                 :     }
    4769                 : 
    4770                 :     /*
    4771 ECB             :      * Set up ParamListInfo for this query
    4772                 :      */
    4773 CBC          57 :     paramLI = setup_param_list(estate, query);
    4774                 : 
    4775                 :     /*
    4776                 :      * Open the cursor (the paramlist will get copied into the portal)
    4777                 :      */
    4778 GIC          57 :     portal = SPI_cursor_open_with_paramlist(curname, query->plan,
    4779 ECB             :                                             paramLI,
    4780 GIC          57 :                                             estate->readonly_func);
    4781              57 :     if (portal == NULL)
    4782 UIC           0 :         elog(ERROR, "could not open cursor: %s",
    4783                 :              SPI_result_code_string(SPI_result));
    4784 ECB             : 
    4785                 :     /*
    4786                 :      * If cursor variable was NULL, store the generated portal name in it,
    4787                 :      * after verifying it's okay to assign to.
    4788 EUB             :      */
    4789 GIC          57 :     if (curname == NULL)
    4790                 :     {
    4791              45 :         exec_check_assignable(estate, stmt->curvar);
    4792              42 :         assign_text_var(estate, curvar, portal->name);
    4793                 :     }
    4794                 : 
    4795 ECB             :     /* If we had any transient data, clean it up */
    4796 GIC          54 :     exec_eval_cleanup(estate);
    4797 CBC          54 :     if (stmt_mcontext)
    4798              12 :         MemoryContextReset(stmt_mcontext);
    4799                 : 
    4800 GIC          54 :     return PLPGSQL_RC_OK;
    4801                 : }
    4802 ECB             : 
    4803                 : 
    4804                 : /* ----------
    4805                 :  * exec_stmt_fetch          Fetch from a cursor into a target, or just
    4806                 :  *                          move the current position of the cursor
    4807                 :  * ----------
    4808                 :  */
    4809                 : static int
    4810 GIC         171 : exec_stmt_fetch(PLpgSQL_execstate *estate, PLpgSQL_stmt_fetch *stmt)
    4811                 : {
    4812                 :     PLpgSQL_var *curvar;
    4813             171 :     long        how_many = stmt->how_many;
    4814                 :     SPITupleTable *tuptab;
    4815                 :     Portal      portal;
    4816 ECB             :     char       *curname;
    4817                 :     uint64      n;
    4818                 :     MemoryContext oldcontext;
    4819                 : 
    4820                 :     /* ----------
    4821                 :      * Get the portal of the cursor by name
    4822                 :      * ----------
    4823                 :      */
    4824 GIC         171 :     curvar = (PLpgSQL_var *) (estate->datums[stmt->curvar]);
    4825             171 :     if (curvar->isnull)
    4826 UIC           0 :         ereport(ERROR,
    4827                 :                 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
    4828                 :                  errmsg("cursor variable \"%s\" is null", curvar->refname)));
    4829                 : 
    4830 ECB             :     /* Use eval_mcontext for short-lived string */
    4831 CBC         171 :     oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
    4832 GBC         171 :     curname = TextDatumGetCString(curvar->value);
    4833 GIC         171 :     MemoryContextSwitchTo(oldcontext);
    4834                 : 
    4835             171 :     portal = SPI_cursor_find(curname);
    4836             171 :     if (portal == NULL)
    4837 LBC           0 :         ereport(ERROR,
    4838 ECB             :                 (errcode(ERRCODE_UNDEFINED_CURSOR),
    4839                 :                  errmsg("cursor \"%s\" does not exist", curname)));
    4840                 : 
    4841                 :     /* Calculate position for FETCH_RELATIVE or FETCH_ABSOLUTE */
    4842 CBC         171 :     if (stmt->expr)
    4843 EUB             :     {
    4844                 :         bool        isnull;
    4845                 : 
    4846                 :         /* XXX should be doing this in LONG not INT width */
    4847 GIC          33 :         how_many = exec_eval_integer(estate, stmt->expr, &isnull);
    4848 ECB             : 
    4849 GIC          33 :         if (isnull)
    4850 UIC           0 :             ereport(ERROR,
    4851                 :                     (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
    4852                 :                      errmsg("relative or absolute cursor position is null")));
    4853 ECB             : 
    4854 GIC          33 :         exec_eval_cleanup(estate);
    4855 ECB             :     }
    4856 EUB             : 
    4857 GIC         171 :     if (!stmt->is_move)
    4858                 :     {
    4859                 :         PLpgSQL_variable *target;
    4860 ECB             : 
    4861                 :         /* ----------
    4862                 :          * Fetch 1 tuple from the cursor
    4863                 :          * ----------
    4864                 :          */
    4865 GIC         150 :         SPI_scroll_cursor_fetch(portal, stmt->direction, how_many);
    4866             147 :         tuptab = SPI_tuptable;
    4867             147 :         n = SPI_processed;
    4868                 : 
    4869                 :         /* ----------
    4870                 :          * Set the target appropriately.
    4871 ECB             :          * ----------
    4872                 :          */
    4873 CBC         147 :         target = (PLpgSQL_variable *) estate->datums[stmt->target->dno];
    4874 GIC         147 :         if (n == 0)
    4875              24 :             exec_move_row(estate, target, NULL, tuptab->tupdesc);
    4876                 :         else
    4877             123 :             exec_move_row(estate, target, tuptab->vals[0], tuptab->tupdesc);
    4878                 : 
    4879 CBC         147 :         exec_eval_cleanup(estate);
    4880             147 :         SPI_freetuptable(tuptab);
    4881 ECB             :     }
    4882                 :     else
    4883                 :     {
    4884                 :         /* Move the cursor */
    4885 CBC          21 :         SPI_scroll_cursor_move(portal, stmt->direction, how_many);
    4886              21 :         n = SPI_processed;
    4887                 :     }
    4888                 : 
    4889                 :     /* Set the ROW_COUNT and the global FOUND variable appropriately. */
    4890 GIC         168 :     estate->eval_processed = n;
    4891 CBC         168 :     exec_set_found(estate, n != 0);
    4892 ECB             : 
    4893 GIC         168 :     return PLPGSQL_RC_OK;
    4894                 : }
    4895                 : 
    4896 ECB             : /* ----------
    4897                 :  * exec_stmt_close          Close a cursor
    4898                 :  * ----------
    4899                 :  */
    4900                 : static int
    4901 GIC          36 : exec_stmt_close(PLpgSQL_execstate *estate, PLpgSQL_stmt_close *stmt)
    4902                 : {
    4903                 :     PLpgSQL_var *curvar;
    4904                 :     Portal      portal;
    4905                 :     char       *curname;
    4906                 :     MemoryContext oldcontext;
    4907 ECB             : 
    4908                 :     /* ----------
    4909                 :      * Get the portal of the cursor by name
    4910                 :      * ----------
    4911                 :      */
    4912 GIC          36 :     curvar = (PLpgSQL_var *) (estate->datums[stmt->curvar]);
    4913              36 :     if (curvar->isnull)
    4914 UIC           0 :         ereport(ERROR,
    4915                 :                 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
    4916                 :                  errmsg("cursor variable \"%s\" is null", curvar->refname)));
    4917                 : 
    4918 ECB             :     /* Use eval_mcontext for short-lived string */
    4919 CBC          36 :     oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
    4920 GBC          36 :     curname = TextDatumGetCString(curvar->value);
    4921 GIC          36 :     MemoryContextSwitchTo(oldcontext);
    4922                 : 
    4923              36 :     portal = SPI_cursor_find(curname);
    4924              36 :     if (portal == NULL)
    4925 LBC           0 :         ereport(ERROR,
    4926 ECB             :                 (errcode(ERRCODE_UNDEFINED_CURSOR),
    4927                 :                  errmsg("cursor \"%s\" does not exist", curname)));
    4928                 : 
    4929                 :     /* ----------
    4930                 :      * And close it.
    4931 EUB             :      * ----------
    4932                 :      */
    4933 GIC          36 :     SPI_cursor_close(portal);
    4934                 : 
    4935              36 :     return PLPGSQL_RC_OK;
    4936                 : }
    4937                 : 
    4938                 : /*
    4939 ECB             :  * exec_stmt_commit
    4940                 :  *
    4941                 :  * Commit the transaction.
    4942                 :  */
    4943                 : static int
    4944 GIC        2081 : exec_stmt_commit(PLpgSQL_execstate *estate, PLpgSQL_stmt_commit *stmt)
    4945                 : {
    4946            2081 :     if (stmt->chain)
    4947               2 :         SPI_commit_and_chain();
    4948                 :     else
    4949            2079 :         SPI_commit();
    4950 ECB             : 
    4951                 :     /*
    4952                 :      * We need to build new simple-expression infrastructure, since the old
    4953                 :      * data structures are gone.
    4954                 :      */
    4955 CBC        2070 :     estate->simple_eval_estate = NULL;
    4956 GIC        2070 :     estate->simple_eval_resowner = NULL;
    4957            2070 :     plpgsql_create_econtext(estate);
    4958                 : 
    4959            2070 :     return PLPGSQL_RC_OK;
    4960                 : }
    4961 ECB             : 
    4962                 : /*
    4963                 :  * exec_stmt_rollback
    4964                 :  *
    4965                 :  * Abort the transaction.
    4966                 :  */
    4967                 : static int
    4968 GIC          42 : exec_stmt_rollback(PLpgSQL_execstate *estate, PLpgSQL_stmt_rollback *stmt)
    4969                 : {
    4970              42 :     if (stmt->chain)
    4971               2 :         SPI_rollback_and_chain();
    4972                 :     else
    4973              40 :         SPI_rollback();
    4974 ECB             : 
    4975                 :     /*
    4976                 :      * We need to build new simple-expression infrastructure, since the old
    4977                 :      * data structures are gone.
    4978                 :      */
    4979 CBC          39 :     estate->simple_eval_estate = NULL;
    4980 GIC          39 :     estate->simple_eval_resowner = NULL;
    4981              39 :     plpgsql_create_econtext(estate);
    4982                 : 
    4983              39 :     return PLPGSQL_RC_OK;
    4984                 : }
    4985 ECB             : 
    4986                 : /* ----------
    4987                 :  * exec_assign_expr         Put an expression's result into a variable.
    4988                 :  * ----------
    4989                 :  */
    4990                 : static void
    4991 GIC       39846 : exec_assign_expr(PLpgSQL_execstate *estate, PLpgSQL_datum *target,
    4992                 :                  PLpgSQL_expr *expr)
    4993                 : {
    4994                 :     Datum       value;
    4995                 :     bool        isnull;
    4996                 :     Oid         valtype;
    4997 ECB             :     int32       valtypmod;
    4998                 : 
    4999                 :     /*
    5000                 :      * If first time through, create a plan for this expression.
    5001                 :      */
    5002 GIC       39846 :     if (expr->plan == NULL)
    5003                 :     {
    5004                 :         /*
    5005                 :          * Mark the expression as being an assignment source, if target is a
    5006                 :          * simple variable.  (This is a bit messy, but it seems cleaner than
    5007                 :          * modifying the API of exec_prepare_plan for the purpose.  We need to
    5008 ECB             :          * stash the target dno into the expr anyway, so that it will be
    5009                 :          * available if we have to replan.)
    5010                 :          */
    5011 GIC        2138 :         if (target->dtype == PLPGSQL_DTYPE_VAR)
    5012            1679 :             expr->target_param = target->dno;
    5013                 :         else
    5014             459 :             expr->target_param = -1; /* should be that already */
    5015                 : 
    5016            2138 :         exec_prepare_plan(estate, expr, 0);
    5017 ECB             :     }
    5018                 : 
    5019 GIC       39826 :     value = exec_eval_expr(estate, expr, &isnull, &valtype, &valtypmod);
    5020 CBC       39733 :     exec_assign_value(estate, target, value, isnull, valtype, valtypmod);
    5021 GIC       39701 :     exec_eval_cleanup(estate);
    5022 CBC       39701 : }
    5023                 : 
    5024                 : 
    5025 ECB             : /* ----------
    5026                 :  * exec_assign_c_string     Put a C string into a text variable.
    5027                 :  *
    5028                 :  * We take a NULL pointer as signifying empty string, not SQL null.
    5029                 :  *
    5030                 :  * As with the underlying exec_assign_value, caller is expected to do
    5031                 :  * exec_eval_cleanup later.
    5032                 :  * ----------
    5033                 :  */
    5034                 : static void
    5035 GIC          66 : exec_assign_c_string(PLpgSQL_execstate *estate, PLpgSQL_datum *target,
    5036                 :                      const char *str)
    5037                 : {
    5038                 :     text       *value;
    5039                 :     MemoryContext oldcontext;
    5040                 : 
    5041 ECB             :     /* Use eval_mcontext for short-lived text value */
    5042 GIC          66 :     oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
    5043              66 :     if (str != NULL)
    5044              66 :         value = cstring_to_text(str);
    5045                 :     else
    5046 UIC           0 :         value = cstring_to_text("");
    5047 GIC          66 :     MemoryContextSwitchTo(oldcontext);
    5048 ECB             : 
    5049 CBC          66 :     exec_assign_value(estate, target, PointerGetDatum(value), false,
    5050 ECB             :                       TEXTOID, -1);
    5051 GIC          66 : }
    5052 EUB             : 
    5053 ECB             : 
    5054                 : /* ----------
    5055                 :  * exec_assign_value            Put a value into a target datum
    5056                 :  *
    5057                 :  * Note: in some code paths, this will leak memory in the eval_mcontext;
    5058                 :  * we assume that will be cleaned up later by exec_eval_cleanup.  We cannot
    5059                 :  * call exec_eval_cleanup here for fear of destroying the input Datum value.
    5060                 :  * ----------
    5061                 :  */
    5062                 : static void
    5063 GIC       69884 : exec_assign_value(PLpgSQL_execstate *estate,
    5064                 :                   PLpgSQL_datum *target,
    5065                 :                   Datum value, bool isNull,
    5066                 :                   Oid valtype, int32 valtypmod)
    5067                 : {
    5068           69884 :     switch (target->dtype)
    5069 ECB             :     {
    5070 GIC       68345 :         case PLPGSQL_DTYPE_VAR:
    5071                 :         case PLPGSQL_DTYPE_PROMISE:
    5072                 :             {
    5073                 :                 /*
    5074 ECB             :                  * Target is a variable
    5075                 :                  */
    5076 CBC       68345 :                 PLpgSQL_var *var = (PLpgSQL_var *) target;
    5077                 :                 Datum       newvalue;
    5078                 : 
    5079 GIC       68345 :                 newvalue = exec_cast_value(estate,
    5080                 :                                            value,
    5081                 :                                            &isNull,
    5082 ECB             :                                            valtype,
    5083                 :                                            valtypmod,
    5084 GIC       68345 :                                            var->datatype->typoid,
    5085 CBC       68345 :                                            var->datatype->atttypmod);
    5086                 : 
    5087 GIC       68332 :                 if (isNull && var->notnull)
    5088               5 :                     ereport(ERROR,
    5089                 :                             (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
    5090 ECB             :                              errmsg("null value cannot be assigned to variable \"%s\" declared NOT NULL",
    5091                 :                                     var->refname)));
    5092                 : 
    5093                 :                 /*
    5094                 :                  * If type is by-reference, copy the new value (which is
    5095                 :                  * probably in the eval_mcontext) into the procedure's main
    5096                 :                  * memory context.  But if it's a read/write reference to an
    5097                 :                  * expanded object, no physical copy needs to happen; at most
    5098                 :                  * we need to reparent the object's memory context.
    5099                 :                  *
    5100                 :                  * If it's an array, we force the value to be stored in R/W
    5101                 :                  * expanded form.  This wins if the function later does, say,
    5102                 :                  * a lot of array subscripting operations on the variable, and
    5103                 :                  * otherwise might lose.  We might need to use a different
    5104                 :                  * heuristic, but it's too soon to tell.  Also, are there
    5105                 :                  * cases where it'd be useful to force non-array values into
    5106                 :                  * expanded form?
    5107                 :                  */
    5108 GIC       68327 :                 if (!var->datatype->typbyval && !isNull)
    5109                 :                 {
    5110           47577 :                     if (var->datatype->typisarray &&
    5111            4921 :                         !VARATT_IS_EXTERNAL_EXPANDED_RW(DatumGetPointer(newvalue)))
    5112                 :                     {
    5113                 :                         /* array and not already R/W, so apply expand_array */
    5114 CBC        4817 :                         newvalue = expand_array(newvalue,
    5115                 :                                                 estate->datum_context,
    5116 ECB             :                                                 NULL);
    5117                 :                     }
    5118                 :                     else
    5119                 :                     {
    5120                 :                         /* else transfer value if R/W, else just datumCopy */
    5121 GIC       42760 :                         newvalue = datumTransfer(newvalue,
    5122                 :                                                  false,
    5123           42760 :                                                  var->datatype->typlen);
    5124                 :                     }
    5125                 :                 }
    5126                 : 
    5127 ECB             :                 /*
    5128                 :                  * Now free the old value, if any, and assign the new one. But
    5129                 :                  * skip the assignment if old and new values are the same.
    5130                 :                  * Note that for expanded objects, this test is necessary and
    5131                 :                  * cannot reliably be made any earlier; we have to be looking
    5132                 :                  * at the object's standard R/W pointer to be sure pointer
    5133                 :                  * equality is meaningful.
    5134                 :                  *
    5135                 :                  * Also, if it's a promise variable, we should disarm the
    5136                 :                  * promise in any case --- otherwise, assigning null to an
    5137                 :                  * armed promise variable would fail to disarm the promise.
    5138                 :                  */
    5139 GIC       68327 :                 if (var->value != newvalue || var->isnull || isNull)
    5140           66973 :                     assign_simple_var(estate, var, newvalue, isNull,
    5141           66973 :                                       (!var->datatype->typbyval && !isNull));
    5142                 :                 else
    5143            1354 :                     var->promise = PLPGSQL_PROMISE_NONE;
    5144           68327 :                 break;
    5145 ECB             :             }
    5146                 : 
    5147 CBC          21 :         case PLPGSQL_DTYPE_ROW:
    5148                 :             {
    5149 ECB             :                 /*
    5150                 :                  * Target is a row variable
    5151                 :                  */
    5152 GIC          21 :                 PLpgSQL_row *row = (PLpgSQL_row *) target;
    5153 ECB             : 
    5154 GIC          21 :                 if (isNull)
    5155                 :                 {
    5156                 :                     /* If source is null, just assign nulls to the row */
    5157 UIC           0 :                     exec_move_row(estate, (PLpgSQL_variable *) row,
    5158 ECB             :                                   NULL, NULL);
    5159                 :                 }
    5160                 :                 else
    5161                 :                 {
    5162                 :                     /* Source must be of RECORD or composite type */
    5163 GBC          21 :                     if (!type_is_rowtype(valtype))
    5164 UIC           0 :                         ereport(ERROR,
    5165                 :                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    5166                 :                                  errmsg("cannot assign non-composite value to a row variable")));
    5167 GIC          21 :                     exec_move_row_from_datum(estate, (PLpgSQL_variable *) row,
    5168                 :                                              value);
    5169 ECB             :                 }
    5170 GBC          21 :                 break;
    5171                 :             }
    5172                 : 
    5173 CBC         406 :         case PLPGSQL_DTYPE_REC:
    5174                 :             {
    5175                 :                 /*
    5176 ECB             :                  * Target is a record variable
    5177                 :                  */
    5178 GIC         406 :                 PLpgSQL_rec *rec = (PLpgSQL_rec *) target;
    5179 ECB             : 
    5180 GIC         406 :                 if (isNull)
    5181                 :                 {
    5182              89 :                     if (rec->notnull)
    5183               4 :                         ereport(ERROR,
    5184 ECB             :                                 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
    5185                 :                                  errmsg("null value cannot be assigned to variable \"%s\" declared NOT NULL",
    5186                 :                                         rec->refname)));
    5187                 : 
    5188                 :                     /* Set variable to a simple NULL */
    5189 CBC          85 :                     exec_move_row(estate, (PLpgSQL_variable *) rec,
    5190                 :                                   NULL, NULL);
    5191                 :                 }
    5192                 :                 else
    5193                 :                 {
    5194                 :                     /* Source must be of RECORD or composite type */
    5195             317 :                     if (!type_is_rowtype(valtype))
    5196 UIC           0 :                         ereport(ERROR,
    5197                 :                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    5198                 :                                  errmsg("cannot assign non-composite value to a record variable")));
    5199 GIC         317 :                     exec_move_row_from_datum(estate, (PLpgSQL_variable *) rec,
    5200                 :                                              value);
    5201 ECB             :                 }
    5202 GBC         393 :                 break;
    5203                 :             }
    5204                 : 
    5205 CBC        1112 :         case PLPGSQL_DTYPE_RECFIELD:
    5206                 :             {
    5207                 :                 /*
    5208 ECB             :                  * Target is a field of a record
    5209                 :                  */
    5210 GIC        1112 :                 PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) target;
    5211 ECB             :                 PLpgSQL_rec *rec;
    5212                 :                 ExpandedRecordHeader *erh;
    5213                 : 
    5214 GIC        1112 :                 rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]);
    5215            1112 :                 erh = rec->erh;
    5216 ECB             : 
    5217                 :                 /*
    5218                 :                  * If record variable is NULL, instantiate it if it has a
    5219                 :                  * named composite type, else complain.  (This won't change
    5220                 :                  * the logical state of the record, but if we successfully
    5221                 :                  * assign below, the unassigned fields will all become NULLs.)
    5222                 :                  */
    5223 GIC        1112 :                 if (erh == NULL)
    5224                 :                 {
    5225              29 :                     instantiate_empty_record_variable(estate, rec);
    5226              28 :                     erh = rec->erh;
    5227                 :                 }
    5228                 : 
    5229 ECB             :                 /*
    5230                 :                  * Look up the field's properties if we have not already, or
    5231                 :                  * if the tuple descriptor ID changed since last time.
    5232                 :                  */
    5233 GIC        1111 :                 if (unlikely(recfield->rectupledescid != erh->er_tupdesc_id))
    5234                 :                 {
    5235               6 :                     if (!expanded_record_lookup_field(erh,
    5236               6 :                                                       recfield->fieldname,
    5237                 :                                                       &recfield->finfo))
    5238               1 :                         ereport(ERROR,
    5239 ECB             :                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
    5240                 :                                  errmsg("record \"%s\" has no field \"%s\"",
    5241                 :                                         rec->refname, recfield->fieldname)));
    5242 CBC           5 :                     recfield->rectupledescid = erh->er_tupdesc_id;
    5243                 :                 }
    5244 ECB             : 
    5245                 :                 /* We don't support assignments to system columns. */
    5246 GIC        1110 :                 if (recfield->finfo.fnumber <= 0)
    5247 UIC           0 :                     ereport(ERROR,
    5248 ECB             :                             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    5249                 :                              errmsg("cannot assign to system column \"%s\"",
    5250                 :                                     recfield->fieldname)));
    5251                 : 
    5252                 :                 /* Cast the new value to the right type, if needed. */
    5253 GBC        1110 :                 value = exec_cast_value(estate,
    5254                 :                                         value,
    5255                 :                                         &isNull,
    5256                 :                                         valtype,
    5257                 :                                         valtypmod,
    5258                 :                                         recfield->finfo.ftypeid,
    5259 ECB             :                                         recfield->finfo.ftypmod);
    5260                 : 
    5261                 :                 /* And assign it. */
    5262 GIC        1110 :                 expanded_record_set_field(erh, recfield->finfo.fnumber,
    5263                 :                                           value, isNull, !estate->atomic);
    5264            1107 :                 break;
    5265                 :             }
    5266                 : 
    5267 UIC           0 :         default:
    5268 LBC           0 :             elog(ERROR, "unrecognized dtype: %d", target->dtype);
    5269                 :     }
    5270 CBC       69848 : }
    5271                 : 
    5272                 : /*
    5273 EUB             :  * exec_eval_datum              Get current value of a PLpgSQL_datum
    5274                 :  *
    5275                 :  * The type oid, typmod, value in Datum format, and null flag are returned.
    5276 ECB             :  *
    5277                 :  * At present this doesn't handle PLpgSQL_expr datums; that's not needed
    5278                 :  * because we never pass references to such datums to SPI.
    5279                 :  *
    5280                 :  * NOTE: the returned Datum points right at the stored value in the case of
    5281                 :  * pass-by-reference datatypes.  Generally callers should take care not to
    5282                 :  * modify the stored value.  Some callers intentionally manipulate variables
    5283                 :  * referenced by R/W expanded pointers, though; it is those callers'
    5284                 :  * responsibility that the results are semantically OK.
    5285                 :  *
    5286                 :  * In some cases we have to palloc a return value, and in such cases we put
    5287                 :  * it into the estate's eval_mcontext.
    5288                 :  */
    5289                 : static void
    5290 GIC       26815 : exec_eval_datum(PLpgSQL_execstate *estate,
    5291                 :                 PLpgSQL_datum *datum,
    5292                 :                 Oid *typeid,
    5293                 :                 int32 *typetypmod,
    5294                 :                 Datum *value,
    5295                 :                 bool *isnull)
    5296 ECB             : {
    5297                 :     MemoryContext oldcontext;
    5298                 : 
    5299 GIC       26815 :     switch (datum->dtype)
    5300                 :     {
    5301           10456 :         case PLPGSQL_DTYPE_PROMISE:
    5302                 :             /* fulfill promise if needed, then handle like regular var */
    5303           10456 :             plpgsql_fulfill_promise(estate, (PLpgSQL_var *) datum);
    5304                 : 
    5305 ECB             :             /* FALL THRU */
    5306                 : 
    5307 CBC       21302 :         case PLPGSQL_DTYPE_VAR:
    5308                 :             {
    5309           21302 :                 PLpgSQL_var *var = (PLpgSQL_var *) datum;
    5310                 : 
    5311 GIC       21302 :                 *typeid = var->datatype->typoid;
    5312           21302 :                 *typetypmod = var->datatype->atttypmod;
    5313 CBC       21302 :                 *value = var->value;
    5314 GIC       21302 :                 *isnull = var->isnull;
    5315 CBC       21302 :                 break;
    5316                 :             }
    5317 ECB             : 
    5318 CBC        3035 :         case PLPGSQL_DTYPE_ROW:
    5319 ECB             :             {
    5320 CBC        3035 :                 PLpgSQL_row *row = (PLpgSQL_row *) datum;
    5321 ECB             :                 HeapTuple   tup;
    5322                 : 
    5323                 :                 /* We get here if there are multiple OUT parameters */
    5324 CBC        3035 :                 if (!row->rowtupdesc)    /* should not happen */
    5325 UIC           0 :                     elog(ERROR, "row variable has no tupdesc");
    5326 ECB             :                 /* Make sure we have a valid type/typmod setting */
    5327 GIC        3035 :                 BlessTupleDesc(row->rowtupdesc);
    5328            3035 :                 oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
    5329            3035 :                 tup = make_tuple_from_row(estate, row, row->rowtupdesc);
    5330 CBC        3035 :                 if (tup == NULL)    /* should not happen */
    5331 UBC           0 :                     elog(ERROR, "row not compatible with its own tupdesc");
    5332 GIC        3035 :                 *typeid = row->rowtupdesc->tdtypeid;
    5333 CBC        3035 :                 *typetypmod = row->rowtupdesc->tdtypmod;
    5334            3035 :                 *value = HeapTupleGetDatum(tup);
    5335            3035 :                 *isnull = false;
    5336            3035 :                 MemoryContextSwitchTo(oldcontext);
    5337 GBC        3035 :                 break;
    5338 ECB             :             }
    5339                 : 
    5340 CBC        1701 :         case PLPGSQL_DTYPE_REC:
    5341 ECB             :             {
    5342 CBC        1701 :                 PLpgSQL_rec *rec = (PLpgSQL_rec *) datum;
    5343 ECB             : 
    5344 GIC        1701 :                 if (rec->erh == NULL)
    5345                 :                 {
    5346 ECB             :                     /* Treat uninstantiated record as a simple NULL */
    5347 GIC          35 :                     *value = (Datum) 0;
    5348 CBC          35 :                     *isnull = true;
    5349                 :                     /* Report variable's declared type */
    5350              35 :                     *typeid = rec->rectypeid;
    5351 GIC          35 :                     *typetypmod = -1;
    5352                 :                 }
    5353 ECB             :                 else
    5354                 :                 {
    5355 GIC        1666 :                     if (ExpandedRecordIsEmpty(rec->erh))
    5356 ECB             :                     {
    5357                 :                         /* Empty record is also a NULL */
    5358 GIC          28 :                         *value = (Datum) 0;
    5359              28 :                         *isnull = true;
    5360                 :                     }
    5361 ECB             :                     else
    5362                 :                     {
    5363 GIC        1638 :                         *value = ExpandedRecordGetDatum(rec->erh);
    5364 CBC        1638 :                         *isnull = false;
    5365 ECB             :                     }
    5366 GIC        1666 :                     if (rec->rectypeid != RECORDOID)
    5367                 :                     {
    5368                 :                         /* Report variable's declared type, if not RECORD */
    5369 CBC         171 :                         *typeid = rec->rectypeid;
    5370             171 :                         *typetypmod = -1;
    5371                 :                     }
    5372 ECB             :                     else
    5373                 :                     {
    5374                 :                         /* Report record's actual type if declared RECORD */
    5375 CBC        1495 :                         *typeid = rec->erh->er_typeid;
    5376            1495 :                         *typetypmod = rec->erh->er_typmod;
    5377                 :                     }
    5378                 :                 }
    5379 GIC        1701 :                 break;
    5380                 :             }
    5381 ECB             : 
    5382 CBC         777 :         case PLPGSQL_DTYPE_RECFIELD:
    5383                 :             {
    5384 GIC         777 :                 PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) datum;
    5385 ECB             :                 PLpgSQL_rec *rec;
    5386                 :                 ExpandedRecordHeader *erh;
    5387                 : 
    5388 CBC         777 :                 rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]);
    5389 GIC         777 :                 erh = rec->erh;
    5390 ECB             : 
    5391                 :                 /*
    5392                 :                  * If record variable is NULL, instantiate it if it has a
    5393                 :                  * named composite type, else complain.  (This won't change
    5394                 :                  * the logical state of the record: it's still NULL.)
    5395                 :                  */
    5396 GIC         777 :                 if (erh == NULL)
    5397                 :                 {
    5398 UIC           0 :                     instantiate_empty_record_variable(estate, rec);
    5399               0 :                     erh = rec->erh;
    5400                 :                 }
    5401                 : 
    5402 ECB             :                 /*
    5403                 :                  * Look up the field's properties if we have not already, or
    5404 EUB             :                  * if the tuple descriptor ID changed since last time.
    5405                 :                  */
    5406 GIC         777 :                 if (unlikely(recfield->rectupledescid != erh->er_tupdesc_id))
    5407                 :                 {
    5408 UIC           0 :                     if (!expanded_record_lookup_field(erh,
    5409               0 :                                                       recfield->fieldname,
    5410                 :                                                       &recfield->finfo))
    5411               0 :                         ereport(ERROR,
    5412 ECB             :                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
    5413                 :                                  errmsg("record \"%s\" has no field \"%s\"",
    5414 EUB             :                                         rec->refname, recfield->fieldname)));
    5415 UBC           0 :                     recfield->rectupledescid = erh->er_tupdesc_id;
    5416                 :                 }
    5417 EUB             : 
    5418                 :                 /* Report type data. */
    5419 GIC         777 :                 *typeid = recfield->finfo.ftypeid;
    5420             777 :                 *typetypmod = recfield->finfo.ftypmod;
    5421 EUB             : 
    5422                 :                 /* And fetch the field value. */
    5423 GIC         777 :                 *value = expanded_record_get_field(erh,
    5424                 :                                                    recfield->finfo.fnumber,
    5425 ECB             :                                                    isnull);
    5426 CBC         777 :                 break;
    5427                 :             }
    5428                 : 
    5429 LBC           0 :         default:
    5430 UIC           0 :             elog(ERROR, "unrecognized dtype: %d", datum->dtype);
    5431                 :     }
    5432 CBC       26815 : }
    5433                 : 
    5434                 : /*
    5435 EUB             :  * plpgsql_exec_get_datum_type              Get datatype of a PLpgSQL_datum
    5436                 :  *
    5437                 :  * This is the same logic as in exec_eval_datum, but we skip acquiring
    5438 ECB             :  * the actual value of the variable.  Also, needn't support DTYPE_ROW.
    5439                 :  */
    5440                 : Oid
    5441 GIC          30 : plpgsql_exec_get_datum_type(PLpgSQL_execstate *estate,
    5442                 :                             PLpgSQL_datum *datum)
    5443                 : {
    5444                 :     Oid         typeid;
    5445                 : 
    5446              30 :     switch (datum->dtype)
    5447 ECB             :     {
    5448 GIC          30 :         case PLPGSQL_DTYPE_VAR:
    5449                 :         case PLPGSQL_DTYPE_PROMISE:
    5450                 :             {
    5451              30 :                 PLpgSQL_var *var = (PLpgSQL_var *) datum;
    5452 ECB             : 
    5453 GIC          30 :                 typeid = var->datatype->typoid;
    5454 CBC          30 :                 break;
    5455                 :             }
    5456                 : 
    5457 LBC           0 :         case PLPGSQL_DTYPE_REC:
    5458                 :             {
    5459               0 :                 PLpgSQL_rec *rec = (PLpgSQL_rec *) datum;
    5460 ECB             : 
    5461 UIC           0 :                 if (rec->erh == NULL || rec->rectypeid != RECORDOID)
    5462                 :                 {
    5463 EUB             :                     /* Report variable's declared type */
    5464 UIC           0 :                     typeid = rec->rectypeid;
    5465 EUB             :                 }
    5466                 :                 else
    5467                 :                 {
    5468                 :                     /* Report record's actual type if declared RECORD */
    5469 UIC           0 :                     typeid = rec->erh->er_typeid;
    5470 EUB             :                 }
    5471 UIC           0 :                 break;
    5472                 :             }
    5473                 : 
    5474               0 :         case PLPGSQL_DTYPE_RECFIELD:
    5475 EUB             :             {
    5476 UIC           0 :                 PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) datum;
    5477 EUB             :                 PLpgSQL_rec *rec;
    5478                 : 
    5479 UIC           0 :                 rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]);
    5480 EUB             : 
    5481                 :                 /*
    5482                 :                  * If record variable is NULL, instantiate it if it has a
    5483                 :                  * named composite type, else complain.  (This won't change
    5484                 :                  * the logical state of the record: it's still NULL.)
    5485                 :                  */
    5486 UIC           0 :                 if (rec->erh == NULL)
    5487               0 :                     instantiate_empty_record_variable(estate, rec);
    5488                 : 
    5489                 :                 /*
    5490                 :                  * Look up the field's properties if we have not already, or
    5491                 :                  * if the tuple descriptor ID changed since last time.
    5492 EUB             :                  */
    5493 UBC           0 :                 if (unlikely(recfield->rectupledescid != rec->erh->er_tupdesc_id))
    5494                 :                 {
    5495 UIC           0 :                     if (!expanded_record_lookup_field(rec->erh,
    5496               0 :                                                       recfield->fieldname,
    5497                 :                                                       &recfield->finfo))
    5498               0 :                         ereport(ERROR,
    5499 EUB             :                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
    5500                 :                                  errmsg("record \"%s\" has no field \"%s\"",
    5501                 :                                         rec->refname, recfield->fieldname)));
    5502 UBC           0 :                     recfield->rectupledescid = rec->erh->er_tupdesc_id;
    5503                 :                 }
    5504 EUB             : 
    5505 UIC           0 :                 typeid = recfield->finfo.ftypeid;
    5506               0 :                 break;
    5507                 :             }
    5508 EUB             : 
    5509 UIC           0 :         default:
    5510               0 :             elog(ERROR, "unrecognized dtype: %d", datum->dtype);
    5511 EUB             :             typeid = InvalidOid;    /* keep compiler quiet */
    5512                 :             break;
    5513                 :     }
    5514                 : 
    5515 GBC          30 :     return typeid;
    5516 EUB             : }
    5517                 : 
    5518                 : /*
    5519                 :  * plpgsql_exec_get_datum_type_info         Get datatype etc of a PLpgSQL_datum
    5520                 :  *
    5521 ECB             :  * An extended version of plpgsql_exec_get_datum_type, which also retrieves the
    5522                 :  * typmod and collation of the datum.  Note however that we don't report the
    5523                 :  * possibly-mutable typmod of RECORD values, but say -1 always.
    5524                 :  */
    5525                 : void
    5526 GIC       15606 : plpgsql_exec_get_datum_type_info(PLpgSQL_execstate *estate,
    5527                 :                                  PLpgSQL_datum *datum,
    5528                 :                                  Oid *typeId, int32 *typMod, Oid *collation)
    5529                 : {
    5530           15606 :     switch (datum->dtype)
    5531                 :     {
    5532 CBC       12003 :         case PLPGSQL_DTYPE_VAR:
    5533                 :         case PLPGSQL_DTYPE_PROMISE:
    5534                 :             {
    5535 GIC       12003 :                 PLpgSQL_var *var = (PLpgSQL_var *) datum;
    5536 ECB             : 
    5537 GIC       12003 :                 *typeId = var->datatype->typoid;
    5538 CBC       12003 :                 *typMod = var->datatype->atttypmod;
    5539 GIC       12003 :                 *collation = var->datatype->collation;
    5540           12003 :                 break;
    5541 ECB             :             }
    5542                 : 
    5543 CBC        1316 :         case PLPGSQL_DTYPE_REC:
    5544 ECB             :             {
    5545 CBC        1316 :                 PLpgSQL_rec *rec = (PLpgSQL_rec *) datum;
    5546 ECB             : 
    5547 GIC        1316 :                 if (rec->erh == NULL || rec->rectypeid != RECORDOID)
    5548                 :                 {
    5549 ECB             :                     /* Report variable's declared type */
    5550 GIC         273 :                     *typeId = rec->rectypeid;
    5551 CBC         273 :                     *typMod = -1;
    5552                 :                 }
    5553 ECB             :                 else
    5554                 :                 {
    5555                 :                     /* Report record's actual type if declared RECORD */
    5556 CBC        1043 :                     *typeId = rec->erh->er_typeid;
    5557 ECB             :                     /* do NOT return the mutable typmod of a RECORD variable */
    5558 GIC        1043 :                     *typMod = -1;
    5559                 :                 }
    5560                 :                 /* composite types are never collatable */
    5561            1316 :                 *collation = InvalidOid;
    5562 CBC        1316 :                 break;
    5563                 :             }
    5564 ECB             : 
    5565 GIC        2287 :         case PLPGSQL_DTYPE_RECFIELD:
    5566                 :             {
    5567 CBC        2287 :                 PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) datum;
    5568 ECB             :                 PLpgSQL_rec *rec;
    5569                 : 
    5570 GIC        2287 :                 rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]);
    5571 ECB             : 
    5572                 :                 /*
    5573                 :                  * If record variable is NULL, instantiate it if it has a
    5574                 :                  * named composite type, else complain.  (This won't change
    5575                 :                  * the logical state of the record: it's still NULL.)
    5576                 :                  */
    5577 GIC        2287 :                 if (rec->erh == NULL)
    5578              23 :                     instantiate_empty_record_variable(estate, rec);
    5579                 : 
    5580                 :                 /*
    5581                 :                  * Look up the field's properties if we have not already, or
    5582                 :                  * if the tuple descriptor ID changed since last time.
    5583 ECB             :                  */
    5584 CBC        2286 :                 if (unlikely(recfield->rectupledescid != rec->erh->er_tupdesc_id))
    5585                 :                 {
    5586 GIC        1278 :                     if (!expanded_record_lookup_field(rec->erh,
    5587            1278 :                                                       recfield->fieldname,
    5588                 :                                                       &recfield->finfo))
    5589              10 :                         ereport(ERROR,
    5590 ECB             :                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
    5591                 :                                  errmsg("record \"%s\" has no field \"%s\"",
    5592                 :                                         rec->refname, recfield->fieldname)));
    5593 CBC        1268 :                     recfield->rectupledescid = rec->erh->er_tupdesc_id;
    5594                 :                 }
    5595 ECB             : 
    5596 GIC        2276 :                 *typeId = recfield->finfo.ftypeid;
    5597            2276 :                 *typMod = recfield->finfo.ftypmod;
    5598            2276 :                 *collation = recfield->finfo.fcollation;
    5599 CBC        2276 :                 break;
    5600                 :             }
    5601                 : 
    5602 LBC           0 :         default:
    5603               0 :             elog(ERROR, "unrecognized dtype: %d", datum->dtype);
    5604 ECB             :             *typeId = InvalidOid;   /* keep compiler quiet */
    5605                 :             *typMod = -1;
    5606                 :             *collation = InvalidOid;
    5607                 :             break;
    5608 EUB             :     }
    5609 GBC       15595 : }
    5610                 : 
    5611                 : /* ----------
    5612                 :  * exec_eval_integer        Evaluate an expression, coerce result to int4
    5613                 :  *
    5614                 :  * Note we do not do exec_eval_cleanup here; the caller must do it at
    5615 ECB             :  * some later point.  (We do this because the caller may be holding the
    5616                 :  * results of other, pass-by-reference, expression evaluations, such as
    5617                 :  * an array value to be subscripted.)
    5618                 :  * ----------
    5619                 :  */
    5620                 : static int
    5621 GIC          33 : exec_eval_integer(PLpgSQL_execstate *estate,
    5622                 :                   PLpgSQL_expr *expr,
    5623                 :                   bool *isNull)
    5624                 : {
    5625                 :     Datum       exprdatum;
    5626                 :     Oid         exprtypeid;
    5627 ECB             :     int32       exprtypmod;
    5628                 : 
    5629 GIC          33 :     exprdatum = exec_eval_expr(estate, expr, isNull, &exprtypeid, &exprtypmod);
    5630              33 :     exprdatum = exec_cast_value(estate, exprdatum, isNull,
    5631                 :                                 exprtypeid, exprtypmod,
    5632                 :                                 INT4OID, -1);
    5633              33 :     return DatumGetInt32(exprdatum);
    5634                 : }
    5635 ECB             : 
    5636                 : /* ----------
    5637                 :  * exec_eval_boolean        Evaluate an expression, coerce result to bool
    5638                 :  *
    5639                 :  * Note we do not do exec_eval_cleanup here; the caller must do it at
    5640                 :  * some later point.
    5641                 :  * ----------
    5642                 :  */
    5643                 : static bool
    5644 GIC       50894 : exec_eval_boolean(PLpgSQL_execstate *estate,
    5645                 :                   PLpgSQL_expr *expr,
    5646                 :                   bool *isNull)
    5647                 : {
    5648                 :     Datum       exprdatum;
    5649                 :     Oid         exprtypeid;
    5650 ECB             :     int32       exprtypmod;
    5651                 : 
    5652 GIC       50894 :     exprdatum = exec_eval_expr(estate, expr, isNull, &exprtypeid, &exprtypmod);
    5653           50894 :     exprdatum = exec_cast_value(estate, exprdatum, isNull,
    5654                 :                                 exprtypeid, exprtypmod,
    5655                 :                                 BOOLOID, -1);
    5656           50894 :     return DatumGetBool(exprdatum);
    5657                 : }
    5658 ECB             : 
    5659                 : /* ----------
    5660                 :  * exec_eval_expr           Evaluate an expression and return
    5661                 :  *                  the result Datum, along with data type/typmod.
    5662                 :  *
    5663                 :  * NOTE: caller must do exec_eval_cleanup when done with the Datum.
    5664                 :  * ----------
    5665                 :  */
    5666                 : static Datum
    5667 GIC      130384 : exec_eval_expr(PLpgSQL_execstate *estate,
    5668                 :                PLpgSQL_expr *expr,
    5669                 :                bool *isNull,
    5670                 :                Oid *rettype,
    5671                 :                int32 *rettypmod)
    5672                 : {
    5673 CBC      130384 :     Datum       result = 0;
    5674                 :     int         rc;
    5675                 :     Form_pg_attribute attr;
    5676                 : 
    5677                 :     /*
    5678                 :      * If first time through, create a plan for this expression.
    5679 ECB             :      */
    5680 GIC      130384 :     if (expr->plan == NULL)
    5681            8162 :         exec_prepare_plan(estate, expr, CURSOR_OPT_PARALLEL_OK);
    5682                 : 
    5683                 :     /*
    5684                 :      * If this is a simple expression, bypass SPI and use the executor
    5685                 :      * directly
    5686 ECB             :      */
    5687 CBC      130365 :     if (exec_eval_simple_expr(estate, expr,
    5688                 :                               &result, isNull, rettype, rettypmod))
    5689 GIC      127923 :         return result;
    5690                 : 
    5691                 :     /*
    5692                 :      * Else do it the hard way via exec_run_select
    5693 ECB             :      */
    5694 GIC        2328 :     rc = exec_run_select(estate, expr, 2, NULL);
    5695 CBC        2322 :     if (rc != SPI_OK_SELECT)
    5696 UIC           0 :         ereport(ERROR,
    5697                 :                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
    5698                 :                  errmsg("query did not return data"),
    5699                 :                  errcontext("query: %s", expr->query)));
    5700 ECB             : 
    5701                 :     /*
    5702 EUB             :      * Check that the expression returns exactly one column...
    5703                 :      */
    5704 GIC        2322 :     if (estate->eval_tuptable->tupdesc->natts != 1)
    5705 UIC           0 :         ereport(ERROR,
    5706                 :                 (errcode(ERRCODE_SYNTAX_ERROR),
    5707                 :                  errmsg_plural("query returned %d column",
    5708                 :                                "query returned %d columns",
    5709                 :                                estate->eval_tuptable->tupdesc->natts,
    5710 ECB             :                                estate->eval_tuptable->tupdesc->natts),
    5711 EUB             :                  errcontext("query: %s", expr->query)));
    5712                 : 
    5713                 :     /*
    5714                 :      * ... and get the column's datatype.
    5715                 :      */
    5716 GIC        2322 :     attr = TupleDescAttr(estate->eval_tuptable->tupdesc, 0);
    5717            2322 :     *rettype = attr->atttypid;
    5718            2322 :     *rettypmod = attr->atttypmod;
    5719                 : 
    5720                 :     /*
    5721                 :      * If there are no rows selected, the result is a NULL of that type.
    5722 ECB             :      */
    5723 CBC        2322 :     if (estate->eval_processed == 0)
    5724 ECB             :     {
    5725 GIC           1 :         *isNull = true;
    5726               1 :         return (Datum) 0;
    5727                 :     }
    5728                 : 
    5729 ECB             :     /*
    5730                 :      * Check that the expression returned no more than one row.
    5731                 :      */
    5732 CBC        2321 :     if (estate->eval_processed != 1)
    5733 GIC           1 :         ereport(ERROR,
    5734                 :                 (errcode(ERRCODE_CARDINALITY_VIOLATION),
    5735                 :                  errmsg("query returned more than one row"),
    5736                 :                  errcontext("query: %s", expr->query)));
    5737                 : 
    5738 ECB             :     /*
    5739                 :      * Return the single result Datum.
    5740                 :      */
    5741 GIC        2320 :     return SPI_getbinval(estate->eval_tuptable->vals[0],
    5742            2320 :                          estate->eval_tuptable->tupdesc, 1, isNull);
    5743                 : }
    5744                 : 
    5745                 : 
    5746                 : /* ----------
    5747 ECB             :  * exec_run_select          Execute a select query
    5748                 :  * ----------
    5749                 :  */
    5750                 : static int
    5751 GIC        5193 : exec_run_select(PLpgSQL_execstate *estate,
    5752                 :                 PLpgSQL_expr *expr, long maxtuples, Portal *portalP)
    5753                 : {
    5754                 :     ParamListInfo paramLI;
    5755                 :     int         rc;
    5756                 : 
    5757 ECB             :     /*
    5758                 :      * On the first call for this expression generate the plan.
    5759                 :      *
    5760                 :      * If we don't need to return a portal, then we're just going to execute
    5761                 :      * the query immediately, which means it's OK to use a parallel plan, even
    5762                 :      * if the number of rows being fetched is limited.  If we do need to
    5763                 :      * return a portal (i.e., this is for a FOR loop), the user's code might
    5764                 :      * invoke additional operations inside the FOR loop, making parallel query
    5765                 :      * unsafe.  In any case, we don't expect any cursor operations to be done,
    5766                 :      * so specify NO_SCROLL for efficiency and semantic safety.
    5767                 :      */
    5768 GIC        5193 :     if (expr->plan == NULL)
    5769                 :     {
    5770             317 :         int         cursorOptions = CURSOR_OPT_NO_SCROLL;
    5771                 : 
    5772             317 :         if (portalP == NULL)
    5773             173 :             cursorOptions |= CURSOR_OPT_PARALLEL_OK;
    5774 CBC         317 :         exec_prepare_plan(estate, expr, cursorOptions);
    5775                 :     }
    5776 ECB             : 
    5777                 :     /*
    5778                 :      * Set up ParamListInfo to pass to executor
    5779                 :      */
    5780 CBC        5178 :     paramLI = setup_param_list(estate, expr);
    5781                 : 
    5782                 :     /*
    5783                 :      * If a portal was requested, put the query and paramlist into the portal
    5784                 :      */
    5785 GIC        5178 :     if (portalP != NULL)
    5786 ECB             :     {
    5787 GIC        2244 :         *portalP = SPI_cursor_open_with_paramlist(NULL, expr->plan,
    5788                 :                                                   paramLI,
    5789            1122 :                                                   estate->readonly_func);
    5790            1122 :         if (*portalP == NULL)
    5791 LBC           0 :             elog(ERROR, "could not open implicit cursor for query \"%s\": %s",
    5792                 :                  expr->query, SPI_result_code_string(SPI_result));
    5793 CBC        1122 :         exec_eval_cleanup(estate);
    5794 GIC        1122 :         return SPI_OK_CURSOR;
    5795 ECB             :     }
    5796                 : 
    5797 EUB             :     /*
    5798                 :      * Execute the query
    5799 ECB             :      */
    5800 CBC        4056 :     rc = SPI_execute_plan_with_paramlist(expr->plan, paramLI,
    5801 GIC        4056 :                                          estate->readonly_func, maxtuples);
    5802            3358 :     if (rc != SPI_OK_SELECT)
    5803                 :     {
    5804                 :         /*
    5805                 :          * SELECT INTO deserves a special error message, because "query is not
    5806 ECB             :          * a SELECT" is not very helpful in that case.
    5807                 :          */
    5808 LBC           0 :         if (rc == SPI_OK_SELINTO)
    5809 UIC           0 :             ereport(ERROR,
    5810                 :                     (errcode(ERRCODE_SYNTAX_ERROR),
    5811                 :                      errmsg("query is SELECT INTO, but it should be plain SELECT"),
    5812                 :                      errcontext("query: %s", expr->query)));
    5813                 :         else
    5814 UBC           0 :             ereport(ERROR,
    5815 EUB             :                     (errcode(ERRCODE_SYNTAX_ERROR),
    5816                 :                      errmsg("query is not a SELECT"),
    5817                 :                      errcontext("query: %s", expr->query)));
    5818                 :     }
    5819                 : 
    5820                 :     /* Save query results for eventual cleanup */
    5821 GIC        3358 :     Assert(estate->eval_tuptable == NULL);
    5822            3358 :     estate->eval_tuptable = SPI_tuptable;
    5823            3358 :     estate->eval_processed = SPI_processed;
    5824                 : 
    5825            3358 :     return rc;
    5826                 : }
    5827 ECB             : 
    5828                 : 
    5829                 : /*
    5830                 :  * exec_for_query --- execute body of FOR loop for each row from a portal
    5831                 :  *
    5832                 :  * Used by exec_stmt_fors, exec_stmt_forc and exec_stmt_dynfors
    5833                 :  */
    5834                 : static int
    5835 GIC        5744 : exec_for_query(PLpgSQL_execstate *estate, PLpgSQL_stmt_forq *stmt,
    5836                 :                Portal portal, bool prefetch_ok)
    5837                 : {
    5838                 :     PLpgSQL_variable *var;
    5839                 :     SPITupleTable *tuptab;
    5840            5744 :     bool        found = false;
    5841 CBC        5744 :     int         rc = PLPGSQL_RC_OK;
    5842 GIC        5744 :     uint64      previous_id = INVALID_TUPLEDESC_IDENTIFIER;
    5843            5744 :     bool        tupdescs_match = true;
    5844                 :     uint64      n;
    5845                 : 
    5846 ECB             :     /* Fetch loop variable's datum entry */
    5847 CBC        5744 :     var = (PLpgSQL_variable *) estate->datums[stmt->var->dno];
    5848 ECB             : 
    5849                 :     /*
    5850                 :      * Make sure the portal doesn't get closed by the user statements we
    5851                 :      * execute.
    5852                 :      */
    5853 CBC        5744 :     PinPortal(portal);
    5854                 : 
    5855                 :     /*
    5856                 :      * In a non-atomic context, we dare not prefetch, even if it would
    5857                 :      * otherwise be safe.  Aside from any semantic hazards that that might
    5858                 :      * create, if we prefetch toasted data and then the user commits the
    5859 ECB             :      * transaction, the toast references could turn into dangling pointers.
    5860                 :      * (Rows we haven't yet fetched from the cursor are safe, because the
    5861                 :      * PersistHoldablePortal mechanism handles this scenario.)
    5862                 :      */
    5863 GIC        5744 :     if (!estate->atomic)
    5864            3699 :         prefetch_ok = false;
    5865                 : 
    5866                 :     /*
    5867                 :      * Fetch the initial tuple(s).  If prefetching is allowed then we grab a
    5868                 :      * few more rows to avoid multiple trips through executor startup
    5869 ECB             :      * overhead.
    5870                 :      */
    5871 GIC        5744 :     SPI_cursor_fetch(portal, true, prefetch_ok ? 10 : 1);
    5872            5741 :     tuptab = SPI_tuptable;
    5873            5741 :     n = SPI_processed;
    5874                 : 
    5875                 :     /*
    5876                 :      * If the query didn't return any rows, set the target to NULL and fall
    5877 ECB             :      * through with found = false.
    5878                 :      */
    5879 CBC        5741 :     if (n == 0)
    5880                 :     {
    5881 GIC         759 :         exec_move_row(estate, var, NULL, tuptab->tupdesc);
    5882             759 :         exec_eval_cleanup(estate);
    5883                 :     }
    5884                 :     else
    5885 CBC        4982 :         found = true;           /* processed at least one tuple */
    5886                 : 
    5887 ECB             :     /*
    5888                 :      * Now do the loop
    5889                 :      */
    5890 GIC       21263 :     while (n > 0)
    5891 ECB             :     {
    5892                 :         uint64      i;
    5893                 : 
    5894 GIC       38505 :         for (i = 0; i < n; i++)
    5895                 :         {
    5896 ECB             :             /*
    5897                 :              * Assign the tuple to the target.  Here, because we know that all
    5898                 :              * loop iterations should be assigning the same tupdesc, we can
    5899                 :              * optimize away repeated creations of expanded records with
    5900                 :              * identical tupdescs.  Testing for changes of er_tupdesc_id is
    5901                 :              * reliable even if the loop body contains assignments that
    5902                 :              * replace the target's value entirely, because it's assigned from
    5903                 :              * a process-global counter.  The case where the tupdescs don't
    5904                 :              * match could possibly be handled more efficiently than this
    5905                 :              * coding does, but it's not clear extra effort is worthwhile.
    5906                 :              */
    5907 GIC       22983 :             if (var->dtype == PLPGSQL_DTYPE_REC)
    5908                 :             {
    5909            3269 :                 PLpgSQL_rec *rec = (PLpgSQL_rec *) var;
    5910                 : 
    5911            3269 :                 if (rec->erh &&
    5912            2895 :                     rec->erh->er_tupdesc_id == previous_id &&
    5913 ECB             :                     tupdescs_match)
    5914                 :                 {
    5915                 :                     /* Only need to assign a new tuple value */
    5916 GIC        2857 :                     expanded_record_set_tuple(rec->erh, tuptab->vals[i],
    5917 CBC        2857 :                                               true, !estate->atomic);
    5918 ECB             :                 }
    5919                 :                 else
    5920                 :                 {
    5921                 :                     /*
    5922                 :                      * First time through, or var's tupdesc changed in loop,
    5923                 :                      * or we have to do it the hard way because type coercion
    5924                 :                      * is needed.
    5925                 :                      */
    5926 GIC         412 :                     exec_move_row(estate, var,
    5927             412 :                                   tuptab->vals[i], tuptab->tupdesc);
    5928                 : 
    5929                 :                     /*
    5930                 :                      * Check to see if physical assignment is OK next time.
    5931                 :                      * Once the tupdesc comparison has failed once, we don't
    5932 ECB             :                      * bother rechecking in subsequent loop iterations.
    5933                 :                      */
    5934 GIC         411 :                     if (tupdescs_match)
    5935                 :                     {
    5936             407 :                         tupdescs_match =
    5937             417 :                             (rec->rectypeid == RECORDOID ||
    5938             417 :                              rec->rectypeid == tuptab->tupdesc->tdtypeid ||
    5939              10 :                              compatible_tupdescs(tuptab->tupdesc,
    5940 ECB             :                                                  expanded_record_get_tupdesc(rec->erh)));
    5941                 :                     }
    5942 CBC         411 :                     previous_id = rec->erh->er_tupdesc_id;
    5943 ECB             :                 }
    5944                 :             }
    5945                 :             else
    5946 GIC       19714 :                 exec_move_row(estate, var, tuptab->vals[i], tuptab->tupdesc);
    5947                 : 
    5948 CBC       22981 :             exec_eval_cleanup(estate);
    5949                 : 
    5950                 :             /*
    5951                 :              * Execute the statements
    5952 ECB             :              */
    5953 GIC       22981 :             rc = exec_stmts(estate, stmt->body);
    5954 ECB             : 
    5955 GIC       22966 :             LOOP_RC_PROCESSING(stmt->label, goto loop_exit);
    5956                 :         }
    5957                 : 
    5958           15522 :         SPI_freetuptable(tuptab);
    5959 ECB             : 
    5960                 :         /*
    5961                 :          * Fetch more tuples.  If prefetching is allowed, grab 50 at a time.
    5962                 :          */
    5963 GIC       15522 :         SPI_cursor_fetch(portal, true, prefetch_ok ? 50 : 1);
    5964 CBC       15522 :         tuptab = SPI_tuptable;
    5965 GIC       15522 :         n = SPI_processed;
    5966                 :     }
    5967                 : 
    5968            5535 : loop_exit:
    5969 ECB             : 
    5970                 :     /*
    5971                 :      * Release last group of tuples (if any)
    5972                 :      */
    5973 GIC        5724 :     SPI_freetuptable(tuptab);
    5974 ECB             : 
    5975 GIC        5724 :     UnpinPortal(portal);
    5976                 : 
    5977                 :     /*
    5978                 :      * Set the FOUND variable to indicate the result of executing the loop
    5979 ECB             :      * (namely, whether we looped one or more times). This must be set last so
    5980                 :      * that it does not interfere with the value of the FOUND variable inside
    5981                 :      * the loop processing itself.
    5982                 :      */
    5983 GIC        5724 :     exec_set_found(estate, found);
    5984                 : 
    5985            5724 :     return rc;
    5986                 : }
    5987                 : 
    5988                 : 
    5989 ECB             : /* ----------
    5990                 :  * exec_eval_simple_expr -      Evaluate a simple expression returning
    5991                 :  *                              a Datum by directly calling ExecEvalExpr().
    5992                 :  *
    5993                 :  * If successful, store results into *result, *isNull, *rettype, *rettypmod
    5994                 :  * and return true.  If the expression cannot be handled by simple evaluation,
    5995                 :  * return false.
    5996                 :  *
    5997                 :  * Because we only store one execution tree for a simple expression, we
    5998                 :  * can't handle recursion cases.  So, if we see the tree is already busy
    5999                 :  * with an evaluation in the current xact, we just return false and let the
    6000                 :  * caller run the expression the hard way.  (Other alternatives such as
    6001                 :  * creating a new tree for a recursive call either introduce memory leaks,
    6002                 :  * or add enough bookkeeping to be doubtful wins anyway.)  Another case that
    6003                 :  * is covered by the expr_simple_in_use test is where a previous execution
    6004                 :  * of the tree was aborted by an error: the tree may contain bogus state
    6005                 :  * so we dare not re-use it.
    6006                 :  *
    6007                 :  * It is possible that we'd need to replan a simple expression; for example,
    6008                 :  * someone might redefine a SQL function that had been inlined into the simple
    6009                 :  * expression.  That cannot cause a simple expression to become non-simple (or
    6010                 :  * vice versa), but we do have to handle replacing the expression tree.
    6011                 :  *
    6012                 :  * Note: if pass-by-reference, the result is in the eval_mcontext.
    6013                 :  * It will be freed when exec_eval_cleanup is done.
    6014                 :  * ----------
    6015                 :  */
    6016                 : static bool
    6017 GIC      130365 : exec_eval_simple_expr(PLpgSQL_execstate *estate,
    6018                 :                       PLpgSQL_expr *expr,
    6019                 :                       Datum *result,
    6020                 :                       bool *isNull,
    6021                 :                       Oid *rettype,
    6022                 :                       int32 *rettypmod)
    6023 ECB             : {
    6024 GIC      130365 :     ExprContext *econtext = estate->eval_econtext;
    6025          130365 :     LocalTransactionId curlxid = MyProc->lxid;
    6026                 :     ParamListInfo paramLI;
    6027                 :     void       *save_setup_arg;
    6028                 :     bool        need_snapshot;
    6029                 :     MemoryContext oldcontext;
    6030 ECB             : 
    6031                 :     /*
    6032                 :      * Forget it if expression wasn't simple before.
    6033                 :      */
    6034 GIC      130365 :     if (expr->expr_simple_expr == NULL)
    6035            2070 :         return false;
    6036                 : 
    6037                 :     /*
    6038                 :      * If expression is in use in current xact, don't touch it.
    6039                 :      */
    6040 CBC      128295 :     if (unlikely(expr->expr_simple_in_use) &&
    6041             291 :         expr->expr_simple_lxid == curlxid)
    6042 GIC         258 :         return false;
    6043                 : 
    6044                 :     /*
    6045                 :      * Ensure that there's a portal-level snapshot, in case this simple
    6046 ECB             :      * expression is the first thing evaluated after a COMMIT or ROLLBACK.
    6047                 :      * We'd have to do this anyway before executing the expression, so we
    6048                 :      * might as well do it now to ensure that any possible replanning doesn't
    6049                 :      * need to take a new snapshot.
    6050                 :      */
    6051 GIC      128037 :     EnsurePortalSnapshotExists();
    6052                 : 
    6053                 :     /*
    6054                 :      * Check to see if the cached plan has been invalidated.  If not, and this
    6055                 :      * is the first use in the current transaction, save a plan refcount in
    6056                 :      * the simple-expression resowner.
    6057 ECB             :      */
    6058 GIC      128037 :     if (likely(CachedPlanIsSimplyValid(expr->expr_simple_plansource,
    6059                 :                                        expr->expr_simple_plan,
    6060                 :                                        (expr->expr_simple_plan_lxid != curlxid ?
    6061                 :                                         estate->simple_eval_resowner : NULL))))
    6062                 :     {
    6063                 :         /*
    6064 ECB             :          * It's still good, so just remember that we have a refcount on the
    6065                 :          * plan in the current transaction.  (If we already had one, this
    6066                 :          * assignment is a no-op.)
    6067                 :          */
    6068 GIC      126089 :         expr->expr_simple_plan_lxid = curlxid;
    6069                 :     }
    6070                 :     else
    6071                 :     {
    6072                 :         /* Need to replan */
    6073                 :         CachedPlan *cplan;
    6074 ECB             : 
    6075                 :         /*
    6076                 :          * If we have a valid refcount on some previous version of the plan,
    6077                 :          * release it, so we don't leak plans intra-transaction.
    6078                 :          */
    6079 GIC        1948 :         if (expr->expr_simple_plan_lxid == curlxid)
    6080                 :         {
    6081            1080 :             ReleaseCachedPlan(expr->expr_simple_plan,
    6082                 :                               estate->simple_eval_resowner);
    6083            1080 :             expr->expr_simple_plan = NULL;
    6084            1080 :             expr->expr_simple_plan_lxid = InvalidLocalTransactionId;
    6085 ECB             :         }
    6086                 : 
    6087                 :         /* Do the replanning work in the eval_mcontext */
    6088 GIC        1948 :         oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
    6089 CBC        1948 :         cplan = SPI_plan_get_cached_plan(expr->plan);
    6090            1948 :         MemoryContextSwitchTo(oldcontext);
    6091                 : 
    6092                 :         /*
    6093                 :          * We can't get a failure here, because the number of
    6094 ECB             :          * CachedPlanSources in the SPI plan can't change from what
    6095                 :          * exec_simple_check_plan saw; it's a property of the raw parsetree
    6096                 :          * generated from the query text.
    6097                 :          */
    6098 GIC        1948 :         Assert(cplan != NULL);
    6099                 : 
    6100                 :         /*
    6101                 :          * This test probably can't fail either, but if it does, cope by
    6102                 :          * declaring the plan to be non-simple.  On success, we'll acquire a
    6103                 :          * refcount on the new plan, stored in simple_eval_resowner.
    6104 ECB             :          */
    6105 GIC        1948 :         if (CachedPlanAllowsSimpleValidityCheck(expr->expr_simple_plansource,
    6106                 :                                                 cplan,
    6107                 :                                                 estate->simple_eval_resowner))
    6108                 :         {
    6109                 :             /* Remember that we have the refcount */
    6110            1948 :             expr->expr_simple_plan = cplan;
    6111 CBC        1948 :             expr->expr_simple_plan_lxid = curlxid;
    6112                 :         }
    6113                 :         else
    6114                 :         {
    6115                 :             /* Release SPI_plan_get_cached_plan's refcount */
    6116 LBC           0 :             ReleaseCachedPlan(cplan, CurrentResourceOwner);
    6117 ECB             :             /* Mark expression as non-simple, and fail */
    6118 UIC           0 :             expr->expr_simple_expr = NULL;
    6119               0 :             expr->expr_rw_param = NULL;
    6120               0 :             return false;
    6121                 :         }
    6122 EUB             : 
    6123                 :         /*
    6124                 :          * SPI_plan_get_cached_plan acquired a plan refcount stored in the
    6125                 :          * active resowner.  We don't need that anymore, so release it.
    6126                 :          */
    6127 GIC        1948 :         ReleaseCachedPlan(cplan, CurrentResourceOwner);
    6128                 : 
    6129                 :         /* Extract desired scalar expression from cached plan */
    6130            1948 :         exec_save_simple_expr(expr, cplan);
    6131                 :     }
    6132                 : 
    6133 ECB             :     /*
    6134                 :      * Pass back previously-determined result type.
    6135                 :      */
    6136 CBC      128037 :     *rettype = expr->expr_simple_type;
    6137 GIC      128037 :     *rettypmod = expr->expr_simple_typmod;
    6138                 : 
    6139                 :     /*
    6140                 :      * Set up ParamListInfo to pass to executor.  For safety, save and restore
    6141                 :      * estate->paramLI->parserSetupArg around our use of the param list.
    6142 ECB             :      */
    6143 CBC      128037 :     paramLI = estate->paramLI;
    6144 GIC      128037 :     save_setup_arg = paramLI->parserSetupArg;
    6145                 : 
    6146                 :     /*
    6147                 :      * We can skip using setup_param_list() in favor of just doing this
    6148                 :      * unconditionally, because there's no need for the optimization of
    6149 ECB             :      * possibly setting ecxt_param_list_info to NULL; we've already forced use
    6150                 :      * of a generic plan.
    6151                 :      */
    6152 GIC      128037 :     paramLI->parserSetupArg = (void *) expr;
    6153          128037 :     econtext->ecxt_param_list_info = paramLI;
    6154                 : 
    6155                 :     /*
    6156                 :      * Prepare the expression for execution, if it's not been done already in
    6157                 :      * the current transaction.  (This will be forced to happen if we called
    6158 ECB             :      * exec_save_simple_expr above.)
    6159                 :      */
    6160 GIC      128037 :     if (unlikely(expr->expr_simple_lxid != curlxid))
    6161                 :     {
    6162           36177 :         oldcontext = MemoryContextSwitchTo(estate->simple_eval_estate->es_query_cxt);
    6163           36177 :         expr->expr_simple_state =
    6164           36177 :             ExecInitExprWithParams(expr->expr_simple_expr,
    6165                 :                                    econtext->ecxt_param_list_info);
    6166 CBC       36177 :         expr->expr_simple_in_use = false;
    6167 GIC       36177 :         expr->expr_simple_lxid = curlxid;
    6168 CBC       36177 :         MemoryContextSwitchTo(oldcontext);
    6169 ECB             :     }
    6170                 : 
    6171                 :     /*
    6172                 :      * We have to do some of the things SPI_execute_plan would do, in
    6173                 :      * particular push a new snapshot so that stable functions within the
    6174                 :      * expression can see updates made so far by our own function.  However,
    6175                 :      * we can skip doing that (and just invoke the expression with the same
    6176                 :      * snapshot passed to our function) in some cases, which is useful because
    6177                 :      * it's quite expensive relative to the cost of a simple expression.  We
    6178                 :      * can skip it if the expression contains no stable or volatile functions;
    6179                 :      * immutable functions shouldn't need to see our updates.  Also, if this
    6180                 :      * is a read-only function, we haven't made any updates so again it's okay
    6181                 :      * to skip.
    6182                 :      */
    6183 GIC      128037 :     oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
    6184          128037 :     need_snapshot = (expr->expr_simple_mutable && !estate->readonly_func);
    6185          128037 :     if (need_snapshot)
    6186                 :     {
    6187           12675 :         CommandCounterIncrement();
    6188           12675 :         PushActiveSnapshot(GetTransactionSnapshot());
    6189 ECB             :     }
    6190                 : 
    6191                 :     /*
    6192                 :      * Mark expression as busy for the duration of the ExecEvalExpr call.
    6193                 :      */
    6194 CBC      128037 :     expr->expr_simple_in_use = true;
    6195                 : 
    6196                 :     /*
    6197                 :      * Finally we can call the executor to evaluate the expression
    6198                 :      */
    6199 GIC      128037 :     *result = ExecEvalExpr(expr->expr_simple_state,
    6200 ECB             :                            econtext,
    6201                 :                            isNull);
    6202                 : 
    6203                 :     /* Assorted cleanup */
    6204 GIC      127923 :     expr->expr_simple_in_use = false;
    6205 ECB             : 
    6206 GIC      127923 :     econtext->ecxt_param_list_info = NULL;
    6207                 : 
    6208          127923 :     paramLI->parserSetupArg = save_setup_arg;
    6209                 : 
    6210 CBC      127923 :     if (need_snapshot)
    6211 GIC       12656 :         PopActiveSnapshot();
    6212 ECB             : 
    6213 GIC      127923 :     MemoryContextSwitchTo(oldcontext);
    6214 ECB             : 
    6215                 :     /*
    6216                 :      * That's it.
    6217                 :      */
    6218 GIC      127923 :     return true;
    6219 ECB             : }
    6220                 : 
    6221                 : 
    6222                 : /*
    6223                 :  * Create a ParamListInfo to pass to SPI
    6224                 :  *
    6225                 :  * We use a single ParamListInfo struct for all SPI calls made to evaluate
    6226                 :  * PLpgSQL_exprs in this estate.  It contains no per-param data, just hook
    6227                 :  * functions, so it's effectively read-only for SPI.
    6228                 :  *
    6229                 :  * An exception from pure read-only-ness is that the parserSetupArg points
    6230                 :  * to the specific PLpgSQL_expr being evaluated.  This is not an issue for
    6231                 :  * statement-level callers, but lower-level callers must save and restore
    6232                 :  * estate->paramLI->parserSetupArg just in case there's an active evaluation
    6233                 :  * at an outer call level.  (A plausible alternative design would be to
    6234                 :  * create a ParamListInfo struct for each PLpgSQL_expr, but for the moment
    6235                 :  * that seems like a waste of memory.)
    6236                 :  */
    6237                 : static ParamListInfo
    6238 GIC       31556 : setup_param_list(PLpgSQL_execstate *estate, PLpgSQL_expr *expr)
    6239                 : {
    6240                 :     ParamListInfo paramLI;
    6241                 : 
    6242                 :     /*
    6243                 :      * We must have created the SPIPlan already (hence, query text has been
    6244 ECB             :      * parsed/analyzed at least once); else we cannot rely on expr->paramnos.
    6245                 :      */
    6246 GIC       31556 :     Assert(expr->plan != NULL);
    6247                 : 
    6248                 :     /*
    6249                 :      * We only need a ParamListInfo if the expression has parameters.
    6250                 :      */
    6251 GNC       31556 :     if (!bms_is_empty(expr->paramnos))
    6252                 :     {
    6253                 :         /* Use the common ParamListInfo */
    6254 CBC       13830 :         paramLI = estate->paramLI;
    6255                 : 
    6256                 :         /*
    6257 ECB             :          * Set up link to active expr where the hook functions can find it.
    6258                 :          * Callers must save and restore parserSetupArg if there is any chance
    6259                 :          * that they are interrupting an active use of parameters.
    6260                 :          */
    6261 GIC       13830 :         paramLI->parserSetupArg = (void *) expr;
    6262                 : 
    6263                 :         /*
    6264 ECB             :          * Also make sure this is set before parser hooks need it.  There is
    6265                 :          * no need to save and restore, since the value is always correct once
    6266                 :          * set.  (Should be set already, but let's be sure.)
    6267                 :          */
    6268 GIC       13830 :         expr->func = estate->func;
    6269                 :     }
    6270                 :     else
    6271 ECB             :     {
    6272                 :         /*
    6273                 :          * Expression requires no parameters.  Be sure we represent this case
    6274                 :          * as a NULL ParamListInfo, so that plancache.c knows there is no
    6275                 :          * point in a custom plan.
    6276                 :          */
    6277 GIC       17726 :         paramLI = NULL;
    6278                 :     }
    6279           31556 :     return paramLI;
    6280 ECB             : }
    6281                 : 
    6282                 : /*
    6283                 :  * plpgsql_param_fetch      paramFetch callback for dynamic parameter fetch
    6284                 :  *
    6285                 :  * We always use the caller's workspace to construct the returned struct.
    6286                 :  *
    6287                 :  * Note: this is no longer used during query execution.  It is used during
    6288                 :  * planning (with speculative == true) and when the ParamListInfo we supply
    6289                 :  * to the executor is copied into a cursor portal or transferred to a
    6290                 :  * parallel child process.
    6291                 :  */
    6292                 : static ParamExternData *
    6293 GIC        5527 : plpgsql_param_fetch(ParamListInfo params,
    6294                 :                     int paramid, bool speculative,
    6295                 :                     ParamExternData *prm)
    6296 ECB             : {
    6297                 :     int         dno;
    6298                 :     PLpgSQL_execstate *estate;
    6299                 :     PLpgSQL_expr *expr;
    6300                 :     PLpgSQL_datum *datum;
    6301 GIC        5527 :     bool        ok = true;
    6302                 :     int32       prmtypmod;
    6303                 : 
    6304 ECB             :     /* paramid's are 1-based, but dnos are 0-based */
    6305 GIC        5527 :     dno = paramid - 1;
    6306            5527 :     Assert(dno >= 0 && dno < params->numParams);
    6307                 : 
    6308 ECB             :     /* fetch back the hook data */
    6309 CBC        5527 :     estate = (PLpgSQL_execstate *) params->paramFetchArg;
    6310 GIC        5527 :     expr = (PLpgSQL_expr *) params->parserSetupArg;
    6311            5527 :     Assert(params->numParams == estate->ndatums);
    6312 ECB             : 
    6313                 :     /* now we can access the target datum */
    6314 CBC        5527 :     datum = estate->datums[dno];
    6315                 : 
    6316                 :     /*
    6317 ECB             :      * Since copyParamList() or SerializeParamList() will try to materialize
    6318                 :      * every single parameter slot, it's important to return a dummy param
    6319                 :      * when asked for a datum that's not supposed to be used by this SQL
    6320                 :      * expression.  Otherwise we risk failures in exec_eval_datum(), or
    6321                 :      * copying a lot more data than necessary.
    6322                 :      */
    6323 GIC        5527 :     if (!bms_is_member(dno, expr->paramnos))
    6324            1812 :         ok = false;
    6325                 : 
    6326 ECB             :     /*
    6327                 :      * If the access is speculative, we prefer to return no data rather than
    6328                 :      * to fail in exec_eval_datum().  Check the likely failure cases.
    6329                 :      */
    6330 GIC        3715 :     else if (speculative)
    6331                 :     {
    6332            3200 :         switch (datum->dtype)
    6333 ECB             :         {
    6334 GIC        2182 :             case PLPGSQL_DTYPE_VAR:
    6335 ECB             :             case PLPGSQL_DTYPE_PROMISE:
    6336                 :                 /* always safe */
    6337 CBC        2182 :                 break;
    6338                 : 
    6339 UIC           0 :             case PLPGSQL_DTYPE_ROW:
    6340 ECB             :                 /* should be safe in all interesting cases */
    6341 UIC           0 :                 break;
    6342 EUB             : 
    6343 GIC         283 :             case PLPGSQL_DTYPE_REC:
    6344 EUB             :                 /* always safe (might return NULL, that's fine) */
    6345 GIC         283 :                 break;
    6346 ECB             : 
    6347 GIC         735 :             case PLPGSQL_DTYPE_RECFIELD:
    6348 ECB             :                 {
    6349 GIC         735 :                     PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) datum;
    6350 ECB             :                     PLpgSQL_rec *rec;
    6351                 : 
    6352 CBC         735 :                     rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]);
    6353                 : 
    6354                 :                     /*
    6355 ECB             :                      * If record variable is NULL, don't risk anything.
    6356                 :                      */
    6357 GIC         735 :                     if (rec->erh == NULL)
    6358 UIC           0 :                         ok = false;
    6359                 : 
    6360 ECB             :                     /*
    6361 EUB             :                      * Look up the field's properties if we have not already,
    6362                 :                      * or if the tuple descriptor ID changed since last time.
    6363                 :                      */
    6364 GIC         735 :                     else if (unlikely(recfield->rectupledescid != rec->erh->er_tupdesc_id))
    6365                 :                     {
    6366               4 :                         if (expanded_record_lookup_field(rec->erh,
    6367 CBC           4 :                                                          recfield->fieldname,
    6368                 :                                                          &recfield->finfo))
    6369               4 :                             recfield->rectupledescid = rec->erh->er_tupdesc_id;
    6370 ECB             :                         else
    6371 UIC           0 :                             ok = false;
    6372 ECB             :                     }
    6373 GIC         735 :                     break;
    6374 EUB             :                 }
    6375                 : 
    6376 LBC           0 :             default:
    6377 UIC           0 :                 ok = false;
    6378               0 :                 break;
    6379 EUB             :         }
    6380                 :     }
    6381                 : 
    6382                 :     /* Return "no such parameter" if not ok */
    6383 GIC        5527 :     if (!ok)
    6384                 :     {
    6385            1812 :         prm->value = (Datum) 0;
    6386 CBC        1812 :         prm->isnull = true;
    6387 GIC        1812 :         prm->pflags = 0;
    6388 CBC        1812 :         prm->ptype = InvalidOid;
    6389            1812 :         return prm;
    6390 ECB             :     }
    6391                 : 
    6392                 :     /* OK, evaluate the value and store into the return struct */
    6393 GIC        3715 :     exec_eval_datum(estate, datum,
    6394                 :                     &prm->ptype, &prmtypmod,
    6395                 :                     &prm->value, &prm->isnull);
    6396 ECB             :     /* We can always mark params as "const" for executor's purposes */
    6397 GIC        3715 :     prm->pflags = PARAM_FLAG_CONST;
    6398                 : 
    6399                 :     /*
    6400 ECB             :      * If it's a read/write expanded datum, convert reference to read-only.
    6401                 :      * (There's little point in trying to optimize read/write parameters,
    6402                 :      * given the cases in which this function is used.)
    6403                 :      */
    6404 GIC        3715 :     if (datum->dtype == PLPGSQL_DTYPE_VAR)
    6405            1654 :         prm->value = MakeExpandedObjectReadOnly(prm->value,
    6406                 :                                                 prm->isnull,
    6407 ECB             :                                                 ((PLpgSQL_var *) datum)->datatype->typlen);
    6408 CBC        2061 :     else if (datum->dtype == PLPGSQL_DTYPE_REC)
    6409 GIC         283 :         prm->value = MakeExpandedObjectReadOnly(prm->value,
    6410                 :                                                 prm->isnull,
    6411 ECB             :                                                 -1);
    6412                 : 
    6413 GIC        3715 :     return prm;
    6414                 : }
    6415                 : 
    6416 ECB             : /*
    6417                 :  * plpgsql_param_compile        paramCompile callback for plpgsql parameters
    6418                 :  */
    6419                 : static void
    6420 GIC       60361 : plpgsql_param_compile(ParamListInfo params, Param *param,
    6421                 :                       ExprState *state,
    6422                 :                       Datum *resv, bool *resnull)
    6423 ECB             : {
    6424                 :     PLpgSQL_execstate *estate;
    6425                 :     PLpgSQL_expr *expr;
    6426                 :     int         dno;
    6427                 :     PLpgSQL_datum *datum;
    6428                 :     ExprEvalStep scratch;
    6429                 : 
    6430                 :     /* fetch back the hook data */
    6431 GIC       60361 :     estate = (PLpgSQL_execstate *) params->paramFetchArg;
    6432           60361 :     expr = (PLpgSQL_expr *) params->parserSetupArg;
    6433                 : 
    6434 ECB             :     /* paramid's are 1-based, but dnos are 0-based */
    6435 CBC       60361 :     dno = param->paramid - 1;
    6436 GIC       60361 :     Assert(dno >= 0 && dno < estate->ndatums);
    6437                 : 
    6438 ECB             :     /* now we can access the target datum */
    6439 CBC       60361 :     datum = estate->datums[dno];
    6440                 : 
    6441 GIC       60361 :     scratch.opcode = EEOP_PARAM_CALLBACK;
    6442 CBC       60361 :     scratch.resvalue = resv;
    6443 GIC       60361 :     scratch.resnull = resnull;
    6444 ECB             : 
    6445                 :     /*
    6446                 :      * Select appropriate eval function.  It seems worth special-casing
    6447                 :      * DTYPE_VAR and DTYPE_RECFIELD for performance.  Also, we can determine
    6448                 :      * in advance whether MakeExpandedObjectReadOnly() will be required.
    6449                 :      * Currently, only VAR/PROMISE and REC datums could contain read/write
    6450                 :      * expanded objects.
    6451                 :      */
    6452 GIC       60361 :     if (datum->dtype == PLPGSQL_DTYPE_VAR)
    6453                 :     {
    6454           39026 :         if (param != expr->expr_rw_param &&
    6455 CBC       38949 :             ((PLpgSQL_var *) datum)->datatype->typlen == -1)
    6456 GIC       30845 :             scratch.d.cparam.paramfunc = plpgsql_param_eval_var_ro;
    6457 ECB             :         else
    6458 CBC        8181 :             scratch.d.cparam.paramfunc = plpgsql_param_eval_var;
    6459 ECB             :     }
    6460 GIC       21335 :     else if (datum->dtype == PLPGSQL_DTYPE_RECFIELD)
    6461 CBC       11596 :         scratch.d.cparam.paramfunc = plpgsql_param_eval_recfield;
    6462 GIC        9739 :     else if (datum->dtype == PLPGSQL_DTYPE_PROMISE)
    6463 ECB             :     {
    6464 CBC        8433 :         if (param != expr->expr_rw_param &&
    6465            8433 :             ((PLpgSQL_var *) datum)->datatype->typlen == -1)
    6466 GIC        7230 :             scratch.d.cparam.paramfunc = plpgsql_param_eval_generic_ro;
    6467 ECB             :         else
    6468 CBC        1203 :             scratch.d.cparam.paramfunc = plpgsql_param_eval_generic;
    6469 ECB             :     }
    6470 GIC        1306 :     else if (datum->dtype == PLPGSQL_DTYPE_REC &&
    6471 CBC        1306 :              param != expr->expr_rw_param)
    6472 GIC        1306 :         scratch.d.cparam.paramfunc = plpgsql_param_eval_generic_ro;
    6473 ECB             :     else
    6474 LBC           0 :         scratch.d.cparam.paramfunc = plpgsql_param_eval_generic;
    6475 ECB             : 
    6476                 :     /*
    6477 EUB             :      * Note: it's tempting to use paramarg to store the estate pointer and
    6478                 :      * thereby save an indirection or two in the eval functions.  But that
    6479                 :      * doesn't work because the compiled expression might be used with
    6480                 :      * different estates for the same PL/pgSQL function.
    6481                 :      */
    6482 GIC       60361 :     scratch.d.cparam.paramarg = NULL;
    6483           60361 :     scratch.d.cparam.paramid = param->paramid;
    6484           60361 :     scratch.d.cparam.paramtype = param->paramtype;
    6485 CBC       60361 :     ExprEvalPushStep(state, &scratch);
    6486           60361 : }
    6487 ECB             : 
    6488                 : /*
    6489                 :  * plpgsql_param_eval_var       evaluation of EEOP_PARAM_CALLBACK step
    6490                 :  *
    6491                 :  * This is specialized to the case of DTYPE_VAR variables for which
    6492                 :  * we do not need to invoke MakeExpandedObjectReadOnly.
    6493                 :  */
    6494                 : static void
    6495 GIC       41894 : plpgsql_param_eval_var(ExprState *state, ExprEvalStep *op,
    6496                 :                        ExprContext *econtext)
    6497                 : {
    6498 ECB             :     ParamListInfo params;
    6499                 :     PLpgSQL_execstate *estate;
    6500 GIC       41894 :     int         dno = op->d.cparam.paramid - 1;
    6501                 :     PLpgSQL_var *var;
    6502                 : 
    6503 ECB             :     /* fetch back the hook data */
    6504 GIC       41894 :     params = econtext->ecxt_param_list_info;
    6505           41894 :     estate = (PLpgSQL_execstate *) params->paramFetchArg;
    6506           41894 :     Assert(dno >= 0 && dno < estate->ndatums);
    6507 ECB             : 
    6508                 :     /* now we can access the target datum */
    6509 CBC       41894 :     var = (PLpgSQL_var *) estate->datums[dno];
    6510 GIC       41894 :     Assert(var->dtype == PLPGSQL_DTYPE_VAR);
    6511                 : 
    6512 ECB             :     /* inlined version of exec_eval_datum() */
    6513 CBC       41894 :     *op->resvalue = var->value;
    6514 GIC       41894 :     *op->resnull = var->isnull;
    6515                 : 
    6516 ECB             :     /* safety check -- an assertion should be sufficient */
    6517 CBC       41894 :     Assert(var->datatype->typoid == op->d.cparam.paramtype);
    6518 GIC       41894 : }
    6519                 : 
    6520 ECB             : /*
    6521                 :  * plpgsql_param_eval_var_ro        evaluation of EEOP_PARAM_CALLBACK step
    6522                 :  *
    6523                 :  * This is specialized to the case of DTYPE_VAR variables for which
    6524                 :  * we need to invoke MakeExpandedObjectReadOnly.
    6525                 :  */
    6526                 : static void
    6527 GIC       76940 : plpgsql_param_eval_var_ro(ExprState *state, ExprEvalStep *op,
    6528                 :                           ExprContext *econtext)
    6529                 : {
    6530 ECB             :     ParamListInfo params;
    6531                 :     PLpgSQL_execstate *estate;
    6532 GIC       76940 :     int         dno = op->d.cparam.paramid - 1;
    6533                 :     PLpgSQL_var *var;
    6534                 : 
    6535 ECB             :     /* fetch back the hook data */
    6536 GIC       76940 :     params = econtext->ecxt_param_list_info;
    6537           76940 :     estate = (PLpgSQL_execstate *) params->paramFetchArg;
    6538           76940 :     Assert(dno >= 0 && dno < estate->ndatums);
    6539 ECB             : 
    6540                 :     /* now we can access the target datum */
    6541 CBC       76940 :     var = (PLpgSQL_var *) estate->datums[dno];
    6542 GIC       76940 :     Assert(var->dtype == PLPGSQL_DTYPE_VAR);
    6543                 : 
    6544 ECB             :     /*
    6545                 :      * Inlined version of exec_eval_datum() ... and while we're at it, force
    6546                 :      * expanded datums to read-only.
    6547                 :      */
    6548 GIC       76940 :     *op->resvalue = MakeExpandedObjectReadOnly(var->value,
    6549                 :                                                var->isnull,
    6550                 :                                                -1);
    6551 CBC       76940 :     *op->resnull = var->isnull;
    6552                 : 
    6553                 :     /* safety check -- an assertion should be sufficient */
    6554           76940 :     Assert(var->datatype->typoid == op->d.cparam.paramtype);
    6555 GIC       76940 : }
    6556                 : 
    6557 ECB             : /*
    6558                 :  * plpgsql_param_eval_recfield      evaluation of EEOP_PARAM_CALLBACK step
    6559                 :  *
    6560                 :  * This is specialized to the case of DTYPE_RECFIELD variables, for which
    6561                 :  * we never need to invoke MakeExpandedObjectReadOnly.
    6562                 :  */
    6563                 : static void
    6564 GIC       30018 : plpgsql_param_eval_recfield(ExprState *state, ExprEvalStep *op,
    6565                 :                             ExprContext *econtext)
    6566                 : {
    6567 ECB             :     ParamListInfo params;
    6568                 :     PLpgSQL_execstate *estate;
    6569 GIC       30018 :     int         dno = op->d.cparam.paramid - 1;
    6570                 :     PLpgSQL_recfield *recfield;
    6571                 :     PLpgSQL_rec *rec;
    6572 ECB             :     ExpandedRecordHeader *erh;
    6573                 : 
    6574                 :     /* fetch back the hook data */
    6575 GIC       30018 :     params = econtext->ecxt_param_list_info;
    6576           30018 :     estate = (PLpgSQL_execstate *) params->paramFetchArg;
    6577           30018 :     Assert(dno >= 0 && dno < estate->ndatums);
    6578 ECB             : 
    6579                 :     /* now we can access the target datum */
    6580 CBC       30018 :     recfield = (PLpgSQL_recfield *) estate->datums[dno];
    6581 GIC       30018 :     Assert(recfield->dtype == PLPGSQL_DTYPE_RECFIELD);
    6582                 : 
    6583 ECB             :     /* inline the relevant part of exec_eval_datum */
    6584 CBC       30018 :     rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]);
    6585 GIC       30018 :     erh = rec->erh;
    6586                 : 
    6587 ECB             :     /*
    6588                 :      * If record variable is NULL, instantiate it if it has a named composite
    6589                 :      * type, else complain.  (This won't change the logical state of the
    6590                 :      * record: it's still NULL.)
    6591                 :      */
    6592 GIC       30018 :     if (erh == NULL)
    6593                 :     {
    6594               1 :         instantiate_empty_record_variable(estate, rec);
    6595 CBC           1 :         erh = rec->erh;
    6596                 :     }
    6597 ECB             : 
    6598                 :     /*
    6599                 :      * Look up the field's properties if we have not already, or if the tuple
    6600                 :      * descriptor ID changed since last time.
    6601                 :      */
    6602 GIC       30018 :     if (unlikely(recfield->rectupledescid != erh->er_tupdesc_id))
    6603                 :     {
    6604            1662 :         if (!expanded_record_lookup_field(erh,
    6605 CBC        1662 :                                           recfield->fieldname,
    6606                 :                                           &recfield->finfo))
    6607               1 :             ereport(ERROR,
    6608 ECB             :                     (errcode(ERRCODE_UNDEFINED_COLUMN),
    6609                 :                      errmsg("record \"%s\" has no field \"%s\"",
    6610                 :                             rec->refname, recfield->fieldname)));
    6611 GIC        1661 :         recfield->rectupledescid = erh->er_tupdesc_id;
    6612                 :     }
    6613                 : 
    6614 ECB             :     /* OK to fetch the field value. */
    6615 GIC       30017 :     *op->resvalue = expanded_record_get_field(erh,
    6616                 :                                               recfield->finfo.fnumber,
    6617                 :                                               op->resnull);
    6618 ECB             : 
    6619                 :     /* safety check -- needed for, eg, record fields */
    6620 GIC       30017 :     if (unlikely(recfield->finfo.ftypeid != op->d.cparam.paramtype))
    6621               2 :         ereport(ERROR,
    6622                 :                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    6623 ECB             :                  errmsg("type of parameter %d (%s) does not match that when preparing the plan (%s)",
    6624                 :                         op->d.cparam.paramid,
    6625                 :                         format_type_be(recfield->finfo.ftypeid),
    6626                 :                         format_type_be(op->d.cparam.paramtype))));
    6627 GIC       30015 : }
    6628                 : 
    6629                 : /*
    6630 ECB             :  * plpgsql_param_eval_generic       evaluation of EEOP_PARAM_CALLBACK step
    6631                 :  *
    6632                 :  * This handles all variable types, but assumes we do not need to invoke
    6633                 :  * MakeExpandedObjectReadOnly.
    6634                 :  */
    6635                 : static void
    6636 GIC        1322 : plpgsql_param_eval_generic(ExprState *state, ExprEvalStep *op,
    6637                 :                            ExprContext *econtext)
    6638                 : {
    6639 ECB             :     ParamListInfo params;
    6640                 :     PLpgSQL_execstate *estate;
    6641 GIC        1322 :     int         dno = op->d.cparam.paramid - 1;
    6642                 :     PLpgSQL_datum *datum;
    6643                 :     Oid         datumtype;
    6644 ECB             :     int32       datumtypmod;
    6645                 : 
    6646                 :     /* fetch back the hook data */
    6647 GIC        1322 :     params = econtext->ecxt_param_list_info;
    6648            1322 :     estate = (PLpgSQL_execstate *) params->paramFetchArg;
    6649            1322 :     Assert(dno >= 0 && dno < estate->ndatums);
    6650 ECB             : 
    6651                 :     /* now we can access the target datum */
    6652 CBC        1322 :     datum = estate->datums[dno];
    6653                 : 
    6654                 :     /* fetch datum's value */
    6655            1322 :     exec_eval_datum(estate, datum,
    6656                 :                     &datumtype, &datumtypmod,
    6657                 :                     op->resvalue, op->resnull);
    6658 ECB             : 
    6659                 :     /* safety check -- needed for, eg, record fields */
    6660 GIC        1322 :     if (unlikely(datumtype != op->d.cparam.paramtype))
    6661 UIC           0 :         ereport(ERROR,
    6662                 :                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    6663 ECB             :                  errmsg("type of parameter %d (%s) does not match that when preparing the plan (%s)",
    6664 EUB             :                         op->d.cparam.paramid,
    6665                 :                         format_type_be(datumtype),
    6666                 :                         format_type_be(op->d.cparam.paramtype))));
    6667 GIC        1322 : }
    6668                 : 
    6669                 : /*
    6670 ECB             :  * plpgsql_param_eval_generic_ro    evaluation of EEOP_PARAM_CALLBACK step
    6671                 :  *
    6672                 :  * This handles all variable types, but assumes we need to invoke
    6673                 :  * MakeExpandedObjectReadOnly (hence, variable must be of a varlena type).
    6674                 :  */
    6675                 : static void
    6676 GIC        9551 : plpgsql_param_eval_generic_ro(ExprState *state, ExprEvalStep *op,
    6677                 :                               ExprContext *econtext)
    6678                 : {
    6679 ECB             :     ParamListInfo params;
    6680                 :     PLpgSQL_execstate *estate;
    6681 GIC        9551 :     int         dno = op->d.cparam.paramid - 1;
    6682                 :     PLpgSQL_datum *datum;
    6683                 :     Oid         datumtype;
    6684 ECB             :     int32       datumtypmod;
    6685                 : 
    6686                 :     /* fetch back the hook data */
    6687 GIC        9551 :     params = econtext->ecxt_param_list_info;
    6688            9551 :     estate = (PLpgSQL_execstate *) params->paramFetchArg;
    6689            9551 :     Assert(dno >= 0 && dno < estate->ndatums);
    6690 ECB             : 
    6691                 :     /* now we can access the target datum */
    6692 CBC        9551 :     datum = estate->datums[dno];
    6693                 : 
    6694                 :     /* fetch datum's value */
    6695            9551 :     exec_eval_datum(estate, datum,
    6696                 :                     &datumtype, &datumtypmod,
    6697                 :                     op->resvalue, op->resnull);
    6698 ECB             : 
    6699                 :     /* safety check -- needed for, eg, record fields */
    6700 GIC        9551 :     if (unlikely(datumtype != op->d.cparam.paramtype))
    6701 UIC           0 :         ereport(ERROR,
    6702                 :                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    6703 ECB             :                  errmsg("type of parameter %d (%s) does not match that when preparing the plan (%s)",
    6704 EUB             :                         op->d.cparam.paramid,
    6705                 :                         format_type_be(datumtype),
    6706                 :                         format_type_be(op->d.cparam.paramtype))));
    6707                 : 
    6708                 :     /* force the value to read-only */
    6709 GIC        9551 :     *op->resvalue = MakeExpandedObjectReadOnly(*op->resvalue,
    6710                 :                                                *op->resnull,
    6711                 :                                                -1);
    6712 CBC        9551 : }
    6713                 : 
    6714                 : 
    6715 ECB             : /*
    6716                 :  * exec_move_row            Move one tuple's values into a record or row
    6717                 :  *
    6718                 :  * tup and tupdesc may both be NULL if we're just assigning an indeterminate
    6719                 :  * composite NULL to the target.  Alternatively, can have tup be NULL and
    6720                 :  * tupdesc not NULL, in which case we assign a row of NULLs to the target.
    6721                 :  *
    6722                 :  * Since this uses the mcontext for workspace, caller should eventually call
    6723                 :  * exec_eval_cleanup to prevent long-term memory leaks.
    6724                 :  */
    6725                 : static void
    6726 GIC       31861 : exec_move_row(PLpgSQL_execstate *estate,
    6727                 :               PLpgSQL_variable *target,
    6728                 :               HeapTuple tup, TupleDesc tupdesc)
    6729 ECB             : {
    6730 GIC       31861 :     ExpandedRecordHeader *newerh = NULL;
    6731                 : 
    6732                 :     /*
    6733 ECB             :      * If target is RECORD, we may be able to avoid field-by-field processing.
    6734                 :      */
    6735 GIC       31861 :     if (target->dtype == PLPGSQL_DTYPE_REC)
    6736                 :     {
    6737            5164 :         PLpgSQL_rec *rec = (PLpgSQL_rec *) target;
    6738 ECB             : 
    6739                 :         /*
    6740                 :          * If we have no source tupdesc, just set the record variable to NULL.
    6741                 :          * (If we have a source tupdesc but not a tuple, we'll set the
    6742                 :          * variable to a row of nulls, instead.  This is odd perhaps, but
    6743                 :          * backwards compatible.)
    6744                 :          */
    6745 GIC        5164 :         if (tupdesc == NULL)
    6746                 :         {
    6747            2422 :             if (rec->datatype &&
    6748 CBC        2422 :                 rec->datatype->typtype == TYPTYPE_DOMAIN)
    6749                 :             {
    6750 ECB             :                 /*
    6751                 :                  * If it's a composite domain, NULL might not be a legal
    6752                 :                  * value, so we instead need to make an empty expanded record
    6753                 :                  * and ensure that domain type checking gets done.  If there
    6754                 :                  * is already an expanded record, piggyback on its lookups.
    6755                 :                  */
    6756 GIC          16 :                 newerh = make_expanded_record_for_rec(estate, rec,
    6757                 :                                                       NULL, rec->erh);
    6758              16 :                 expanded_record_set_tuple(newerh, NULL, false, false);
    6759 CBC          12 :                 assign_record_var(estate, rec, newerh);
    6760                 :             }
    6761 ECB             :             else
    6762                 :             {
    6763                 :                 /* Just clear it to NULL */
    6764 GIC        2406 :                 if (rec->erh)
    6765              81 :                     DeleteExpandedObject(ExpandedRecordGetDatum(rec->erh));
    6766            2406 :                 rec->erh = NULL;
    6767 ECB             :             }
    6768 CBC        2418 :             return;
    6769 ECB             :         }
    6770                 : 
    6771                 :         /*
    6772                 :          * Build a new expanded record with appropriate tupdesc.
    6773                 :          */
    6774 GIC        2742 :         newerh = make_expanded_record_for_rec(estate, rec, tupdesc, NULL);
    6775                 : 
    6776                 :         /*
    6777 ECB             :          * If the rowtypes match, or if we have no tuple anyway, we can
    6778                 :          * complete the assignment without field-by-field processing.
    6779                 :          *
    6780                 :          * The tests here are ordered more or less in order of cheapness.  We
    6781                 :          * can easily detect it will work if the target is declared RECORD or
    6782                 :          * has the same typeid as the source.  But when assigning from a query
    6783                 :          * result, it's common to have a source tupdesc that's labeled RECORD
    6784                 :          * but is actually physically compatible with a named-composite-type
    6785                 :          * target, so it's worth spending extra cycles to check for that.
    6786                 :          */
    6787 GIC        2742 :         if (rec->rectypeid == RECORDOID ||
    6788             109 :             rec->rectypeid == tupdesc->tdtypeid ||
    6789             109 :             !HeapTupleIsValid(tup) ||
    6790 CBC         109 :             compatible_tupdescs(tupdesc, expanded_record_get_tupdesc(newerh)))
    6791 ECB             :         {
    6792 CBC        2694 :             if (!HeapTupleIsValid(tup))
    6793 ECB             :             {
    6794                 :                 /* No data, so force the record into all-nulls state */
    6795 CBC         711 :                 deconstruct_expanded_record(newerh);
    6796                 :             }
    6797                 :             else
    6798 ECB             :             {
    6799                 :                 /* No coercion is needed, so just assign the row value */
    6800 GIC        1983 :                 expanded_record_set_tuple(newerh, tup, true, !estate->atomic);
    6801                 :             }
    6802                 : 
    6803 ECB             :             /* Complete the assignment */
    6804 GIC        2691 :             assign_record_var(estate, rec, newerh);
    6805                 : 
    6806            2691 :             return;
    6807 ECB             :         }
    6808                 :     }
    6809                 : 
    6810                 :     /*
    6811                 :      * Otherwise, deconstruct the tuple and do field-by-field assignment,
    6812                 :      * using exec_move_row_from_fields.
    6813                 :      */
    6814 GIC       26745 :     if (tupdesc && HeapTupleIsValid(tup))
    6815           26634 :     {
    6816           26651 :         int         td_natts = tupdesc->natts;
    6817 ECB             :         Datum      *values;
    6818                 :         bool       *nulls;
    6819                 :         Datum       values_local[64];
    6820                 :         bool        nulls_local[64];
    6821                 : 
    6822                 :         /*
    6823                 :          * Need workspace arrays.  If td_natts is small enough, use local
    6824                 :          * arrays to save doing a palloc.  Even if it's not small, we can
    6825                 :          * allocate both the Datum and isnull arrays in one palloc chunk.
    6826                 :          */
    6827 GIC       26651 :         if (td_natts <= lengthof(values_local))
    6828                 :         {
    6829           26651 :             values = values_local;
    6830 CBC       26651 :             nulls = nulls_local;
    6831                 :         }
    6832 ECB             :         else
    6833                 :         {
    6834                 :             char       *chunk;
    6835                 : 
    6836 UIC           0 :             chunk = eval_mcontext_alloc(estate,
    6837                 :                                         td_natts * (sizeof(Datum) + sizeof(bool)));
    6838               0 :             values = (Datum *) chunk;
    6839 UBC           0 :             nulls = (bool *) (chunk + td_natts * sizeof(Datum));
    6840                 :         }
    6841 EUB             : 
    6842 GBC       26651 :         heap_deform_tuple(tup, tupdesc, values, nulls);
    6843                 : 
    6844 GIC       26651 :         exec_move_row_from_fields(estate, target, newerh,
    6845 ECB             :                                   values, nulls, tupdesc);
    6846                 :     }
    6847                 :     else
    6848                 :     {
    6849                 :         /*
    6850                 :          * Assign all-nulls.
    6851                 :          */
    6852 GIC          94 :         exec_move_row_from_fields(estate, target, newerh,
    6853                 :                                   NULL, NULL, NULL);
    6854                 :     }
    6855 ECB             : }
    6856                 : 
    6857                 : /*
    6858                 :  * Verify that a PLpgSQL_rec's rectypeid is up-to-date.
    6859                 :  */
    6860                 : static void
    6861 GIC         355 : revalidate_rectypeid(PLpgSQL_rec *rec)
    6862                 : {
    6863             355 :     PLpgSQL_type *typ = rec->datatype;
    6864 ECB             :     TypeCacheEntry *typentry;
    6865                 : 
    6866 CBC         355 :     if (rec->rectypeid == RECORDOID)
    6867 GIC         150 :         return;                 /* it's RECORD, so nothing to do */
    6868             205 :     Assert(typ != NULL);
    6869 CBC         205 :     if (typ->tcache &&
    6870             205 :         typ->tcache->tupDesc_identifier == typ->tupdesc_id)
    6871 ECB             :     {
    6872                 :         /*
    6873                 :          * Although *typ is known up-to-date, it's possible that rectypeid
    6874                 :          * isn't, because *rec is cloned during each function startup from a
    6875                 :          * copy that we don't have a good way to update.  Hence, forcibly fix
    6876                 :          * rectypeid before returning.
    6877                 :          */
    6878 GIC         199 :         rec->rectypeid = typ->typoid;
    6879             199 :         return;
    6880                 :     }
    6881 ECB             : 
    6882                 :     /*
    6883                 :      * typcache entry has suffered invalidation, so re-look-up the type name
    6884                 :      * if possible, and then recheck the type OID.  If we don't have a
    6885                 :      * TypeName, then we just have to soldier on with the OID we've got.
    6886                 :      */
    6887 GIC           6 :     if (typ->origtypname != NULL)
    6888                 :     {
    6889                 :         /* this bit should match parse_datatype() in pl_gram.y */
    6890 CBC           4 :         typenameTypeIdAndMod(NULL, typ->origtypname,
    6891                 :                              &typ->typoid,
    6892                 :                              &typ->atttypmod);
    6893 ECB             :     }
    6894                 : 
    6895                 :     /* this bit should match build_datatype() in pl_comp.c */
    6896 GIC           5 :     typentry = lookup_type_cache(typ->typoid,
    6897                 :                                  TYPECACHE_TUPDESC |
    6898                 :                                  TYPECACHE_DOMAIN_BASE_INFO);
    6899 CBC           5 :     if (typentry->typtype == TYPTYPE_DOMAIN)
    6900 UIC           0 :         typentry = lookup_type_cache(typentry->domainBaseType,
    6901                 :                                      TYPECACHE_TUPDESC);
    6902 CBC           5 :     if (typentry->tupDesc == NULL)
    6903 EUB             :     {
    6904                 :         /*
    6905 ECB             :          * If we get here, user tried to replace a composite type with a
    6906                 :          * non-composite one.  We're not gonna support that.
    6907                 :          */
    6908 UIC           0 :         ereport(ERROR,
    6909                 :                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
    6910                 :                  errmsg("type %s is not composite",
    6911 EUB             :                         format_type_be(typ->typoid))));
    6912                 :     }
    6913                 : 
    6914                 :     /*
    6915                 :      * Update tcache and tupdesc_id.  Since we don't support changing to a
    6916                 :      * non-composite type, none of the rest of *typ needs to change.
    6917                 :      */
    6918 GIC           5 :     typ->tcache = typentry;
    6919               5 :     typ->tupdesc_id = typentry->tupDesc_identifier;
    6920                 : 
    6921 ECB             :     /*
    6922                 :      * Update *rec, too.  (We'll deal with subsidiary RECFIELDs as needed.)
    6923                 :      */
    6924 GIC           5 :     rec->rectypeid = typ->typoid;
    6925                 : }
    6926                 : 
    6927 ECB             : /*
    6928                 :  * Build an expanded record object suitable for assignment to "rec".
    6929                 :  *
    6930                 :  * Caller must supply either a source tuple descriptor or a source expanded
    6931                 :  * record (not both).  If the record variable has declared type RECORD,
    6932                 :  * it'll adopt the source's rowtype.  Even if it doesn't, we may be able to
    6933                 :  * piggyback on a source expanded record to save a typcache lookup.
    6934                 :  *
    6935                 :  * Caller must fill the object with data, then do assign_record_var().
    6936                 :  *
    6937                 :  * The new record is initially put into the mcontext, so it will be cleaned up
    6938                 :  * if we fail before reaching assign_record_var().
    6939                 :  */
    6940                 : static ExpandedRecordHeader *
    6941 GIC        2919 : make_expanded_record_for_rec(PLpgSQL_execstate *estate,
    6942                 :                              PLpgSQL_rec *rec,
    6943                 :                              TupleDesc srctupdesc,
    6944 ECB             :                              ExpandedRecordHeader *srcerh)
    6945                 : {
    6946                 :     ExpandedRecordHeader *newerh;
    6947 GIC        2919 :     MemoryContext mcontext = get_eval_mcontext(estate);
    6948                 : 
    6949            2919 :     if (rec->rectypeid != RECORDOID)
    6950 ECB             :     {
    6951                 :         /*
    6952                 :          * Make sure rec->rectypeid is up-to-date before using it.
    6953                 :          */
    6954 GIC         137 :         revalidate_rectypeid(rec);
    6955                 : 
    6956                 :         /*
    6957 ECB             :          * New record must be of desired type, but maybe srcerh has already
    6958                 :          * done all the same lookups.
    6959                 :          */
    6960 GIC         137 :         if (srcerh && rec->rectypeid == srcerh->er_decltypeid)
    6961              13 :             newerh = make_expanded_record_from_exprecord(srcerh,
    6962                 :                                                          mcontext);
    6963 ECB             :         else
    6964 CBC         124 :             newerh = make_expanded_record_from_typeid(rec->rectypeid, -1,
    6965                 :                                                       mcontext);
    6966                 :     }
    6967 ECB             :     else
    6968                 :     {
    6969                 :         /*
    6970                 :          * We'll adopt the input tupdesc.  We can still use
    6971                 :          * make_expanded_record_from_exprecord, if srcerh isn't a composite
    6972                 :          * domain.  (If it is, we effectively adopt its base type.)
    6973                 :          */
    6974 GIC        2782 :         if (srcerh && !ExpandedRecordIsDomain(srcerh))
    6975             149 :             newerh = make_expanded_record_from_exprecord(srcerh,
    6976                 :                                                          mcontext);
    6977 ECB             :         else
    6978                 :         {
    6979 GIC        2633 :             if (!srctupdesc)
    6980 UIC           0 :                 srctupdesc = expanded_record_get_tupdesc(srcerh);
    6981 GIC        2633 :             newerh = make_expanded_record_from_tupdesc(srctupdesc,
    6982 ECB             :                                                        mcontext);
    6983 EUB             :         }
    6984 ECB             :     }
    6985                 : 
    6986 GIC        2919 :     return newerh;
    6987                 : }
    6988                 : 
    6989 ECB             : /*
    6990                 :  * exec_move_row_from_fields    Move arrays of field values into a record or row
    6991                 :  *
    6992                 :  * When assigning to a record, the caller must have already created a suitable
    6993                 :  * new expanded record object, newerh.  Pass NULL when assigning to a row.
    6994                 :  *
    6995                 :  * tupdesc describes the input row, which might have different column
    6996                 :  * types and/or different dropped-column positions than the target.
    6997                 :  * values/nulls/tupdesc can all be NULL if we just want to assign nulls to
    6998                 :  * all fields of the record or row.
    6999                 :  *
    7000                 :  * Since this uses the mcontext for workspace, caller should eventually call
    7001                 :  * exec_eval_cleanup to prevent long-term memory leaks.
    7002                 :  */
    7003                 : static void
    7004 GIC       26755 : exec_move_row_from_fields(PLpgSQL_execstate *estate,
    7005                 :                           PLpgSQL_variable *target,
    7006                 :                           ExpandedRecordHeader *newerh,
    7007 ECB             :                           Datum *values, bool *nulls,
    7008                 :                           TupleDesc tupdesc)
    7009                 : {
    7010 GIC       26755 :     int         td_natts = tupdesc ? tupdesc->natts : 0;
    7011                 :     int         fnum;
    7012                 :     int         anum;
    7013 CBC       26755 :     int         strict_multiassignment_level = 0;
    7014                 : 
    7015                 :     /*
    7016 ECB             :      * The extra check strict strict_multi_assignment can be active, only when
    7017                 :      * input tupdesc is specified.
    7018                 :      */
    7019 GIC       26755 :     if (tupdesc != NULL)
    7020                 :     {
    7021           26661 :         if (plpgsql_extra_errors & PLPGSQL_XCHECK_STRICTMULTIASSIGNMENT)
    7022 CBC          18 :             strict_multiassignment_level = ERROR;
    7023 GIC       26643 :         else if (plpgsql_extra_warnings & PLPGSQL_XCHECK_STRICTMULTIASSIGNMENT)
    7024 CBC           9 :             strict_multiassignment_level = WARNING;
    7025 ECB             :     }
    7026                 : 
    7027                 :     /* Handle RECORD-target case */
    7028 GIC       26755 :     if (target->dtype == PLPGSQL_DTYPE_REC)
    7029                 :     {
    7030              58 :         PLpgSQL_rec *rec = (PLpgSQL_rec *) target;
    7031 ECB             :         TupleDesc   var_tupdesc;
    7032                 :         Datum       newvalues_local[64];
    7033                 :         bool        newnulls_local[64];
    7034                 : 
    7035 GIC          58 :         Assert(newerh != NULL); /* caller must have built new object */
    7036                 : 
    7037              58 :         var_tupdesc = expanded_record_get_tupdesc(newerh);
    7038 ECB             : 
    7039                 :         /*
    7040                 :          * Coerce field values if needed.  This might involve dealing with
    7041                 :          * different sets of dropped columns and/or coercing individual column
    7042                 :          * types.  That's sort of a pain, but historically plpgsql has allowed
    7043                 :          * it, so we preserve the behavior.  However, it's worth a quick check
    7044                 :          * to see if the tupdescs are identical.  (Since expandedrecord.c
    7045                 :          * prefers to use refcounted tupdescs from the typcache, expanded
    7046                 :          * records with the same rowtype will have pointer-equal tupdescs.)
    7047                 :          */
    7048 GIC          58 :         if (var_tupdesc != tupdesc)
    7049                 :         {
    7050              51 :             int         vtd_natts = var_tupdesc->natts;
    7051 ECB             :             Datum      *newvalues;
    7052                 :             bool       *newnulls;
    7053                 : 
    7054                 :             /*
    7055                 :              * Need workspace arrays.  If vtd_natts is small enough, use local
    7056                 :              * arrays to save doing a palloc.  Even if it's not small, we can
    7057                 :              * allocate both the Datum and isnull arrays in one palloc chunk.
    7058                 :              */
    7059 GIC          51 :             if (vtd_natts <= lengthof(newvalues_local))
    7060                 :             {
    7061              51 :                 newvalues = newvalues_local;
    7062 CBC          51 :                 newnulls = newnulls_local;
    7063                 :             }
    7064 ECB             :             else
    7065                 :             {
    7066                 :                 char       *chunk;
    7067                 : 
    7068 UIC           0 :                 chunk = eval_mcontext_alloc(estate,
    7069                 :                                             vtd_natts * (sizeof(Datum) + sizeof(bool)));
    7070               0 :                 newvalues = (Datum *) chunk;
    7071 UBC           0 :                 newnulls = (bool *) (chunk + vtd_natts * sizeof(Datum));
    7072                 :             }
    7073 EUB             : 
    7074                 :             /* Walk over destination columns */
    7075 GIC          51 :             anum = 0;
    7076             159 :             for (fnum = 0; fnum < vtd_natts; fnum++)
    7077                 :             {
    7078 CBC         112 :                 Form_pg_attribute attr = TupleDescAttr(var_tupdesc, fnum);
    7079 ECB             :                 Datum       value;
    7080                 :                 bool        isnull;
    7081                 :                 Oid         valtype;
    7082                 :                 int32       valtypmod;
    7083                 : 
    7084 GIC         112 :                 if (attr->attisdropped)
    7085                 :                 {
    7086                 :                     /* expanded_record_set_fields should ignore this column */
    7087 CBC          10 :                     continue;   /* skip dropped column in record */
    7088                 :                 }
    7089                 : 
    7090             102 :                 while (anum < td_natts &&
    7091 GIC          99 :                        TupleDescAttr(tupdesc, anum)->attisdropped)
    7092 UIC           0 :                     anum++;     /* skip dropped column in tuple */
    7093 ECB             : 
    7094 CBC         102 :                 if (anum < td_natts)
    7095 EUB             :                 {
    7096 GIC          99 :                     value = values[anum];
    7097 CBC          99 :                     isnull = nulls[anum];
    7098 GIC          99 :                     valtype = TupleDescAttr(tupdesc, anum)->atttypid;
    7099 CBC          99 :                     valtypmod = TupleDescAttr(tupdesc, anum)->atttypmod;
    7100              99 :                     anum++;
    7101 ECB             :                 }
    7102                 :                 else
    7103                 :                 {
    7104                 :                     /* no source for destination column */
    7105 GIC           3 :                     value = (Datum) 0;
    7106               3 :                     isnull = true;
    7107               3 :                     valtype = UNKNOWNOID;
    7108 CBC           3 :                     valtypmod = -1;
    7109 ECB             : 
    7110                 :                     /* When source value is missing */
    7111 CBC           3 :                     if (strict_multiassignment_level)
    7112 GIC           3 :                         ereport(strict_multiassignment_level,
    7113                 :                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
    7114 ECB             :                                  errmsg("number of source and target fields in assignment does not match"),
    7115                 :                         /* translator: %s represents a name of an extra check */
    7116                 :                                  errdetail("%s check of %s is active.",
    7117                 :                                            "strict_multi_assignment",
    7118                 :                                            strict_multiassignment_level == ERROR ? "extra_errors" :
    7119                 :                                            "extra_warnings"),
    7120                 :                                  errhint("Make sure the query returns the exact list of columns.")));
    7121                 :                 }
    7122                 : 
    7123                 :                 /* Cast the new value to the right type, if needed. */
    7124 GIC          99 :                 newvalues[fnum] = exec_cast_value(estate,
    7125                 :                                                   value,
    7126                 :                                                   &isnull,
    7127 ECB             :                                                   valtype,
    7128                 :                                                   valtypmod,
    7129                 :                                                   attr->atttypid,
    7130                 :                                                   attr->atttypmod);
    7131 GIC          98 :                 newnulls[fnum] = isnull;
    7132                 :             }
    7133                 : 
    7134 ECB             :             /*
    7135                 :              * When strict_multiassignment extra check is active, then ensure
    7136                 :              * there are no unassigned source attributes.
    7137                 :              */
    7138 GIC          47 :             if (strict_multiassignment_level && anum < td_natts)
    7139                 :             {
    7140                 :                 /* skip dropped columns in the source descriptor */
    7141 CBC           3 :                 while (anum < td_natts &&
    7142 GIC           3 :                        TupleDescAttr(tupdesc, anum)->attisdropped)
    7143 UIC           0 :                     anum++;
    7144 ECB             : 
    7145 CBC           3 :                 if (anum < td_natts)
    7146 GBC           3 :                     ereport(strict_multiassignment_level,
    7147                 :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    7148 ECB             :                              errmsg("number of source and target fields in assignment does not match"),
    7149                 :                     /* translator: %s represents a name of an extra check */
    7150                 :                              errdetail("%s check of %s is active.",
    7151                 :                                        "strict_multi_assignment",
    7152                 :                                        strict_multiassignment_level == ERROR ? "extra_errors" :
    7153                 :                                        "extra_warnings"),
    7154                 :                              errhint("Make sure the query returns the exact list of columns.")));
    7155                 :             }
    7156                 : 
    7157 GIC          44 :             values = newvalues;
    7158              44 :             nulls = newnulls;
    7159                 :         }
    7160 ECB             : 
    7161                 :         /* Insert the coerced field values into the new expanded record */
    7162 GIC          51 :         expanded_record_set_fields(newerh, values, nulls, !estate->atomic);
    7163                 : 
    7164                 :         /* Complete the assignment */
    7165 CBC          47 :         assign_record_var(estate, rec, newerh);
    7166                 : 
    7167 GIC          47 :         return;
    7168 ECB             :     }
    7169                 : 
    7170                 :     /* newerh should not have been passed in non-RECORD cases */
    7171 GIC       26697 :     Assert(newerh == NULL);
    7172                 : 
    7173                 :     /*
    7174 ECB             :      * For a row, we assign the individual field values to the variables the
    7175                 :      * row points to.
    7176                 :      *
    7177                 :      * NOTE: both this code and the record code above silently ignore extra
    7178                 :      * columns in the source and assume NULL for missing columns.  This is
    7179                 :      * pretty dubious but it's the historical behavior.
    7180                 :      *
    7181                 :      * If we have no input data at all, we'll assign NULL to all columns of
    7182                 :      * the row variable.
    7183                 :      */
    7184 GIC       26697 :     if (target->dtype == PLPGSQL_DTYPE_ROW)
    7185                 :     {
    7186           26697 :         PLpgSQL_row *row = (PLpgSQL_row *) target;
    7187 ECB             : 
    7188 GIC       26697 :         anum = 0;
    7189 CBC       56500 :         for (fnum = 0; fnum < row->nfields; fnum++)
    7190                 :         {
    7191 ECB             :             PLpgSQL_var *var;
    7192                 :             Datum       value;
    7193                 :             bool        isnull;
    7194                 :             Oid         valtype;
    7195                 :             int32       valtypmod;
    7196                 : 
    7197 GIC       29806 :             var = (PLpgSQL_var *) (estate->datums[row->varnos[fnum]]);
    7198                 : 
    7199           29806 :             while (anum < td_natts &&
    7200 CBC       29703 :                    TupleDescAttr(tupdesc, anum)->attisdropped)
    7201 UIC           0 :                 anum++;         /* skip dropped column in tuple */
    7202 ECB             : 
    7203 CBC       29806 :             if (anum < td_natts)
    7204 EUB             :             {
    7205 GIC       29703 :                 value = values[anum];
    7206 CBC       29703 :                 isnull = nulls[anum];
    7207 GIC       29703 :                 valtype = TupleDescAttr(tupdesc, anum)->atttypid;
    7208 CBC       29703 :                 valtypmod = TupleDescAttr(tupdesc, anum)->atttypmod;
    7209           29703 :                 anum++;
    7210 ECB             :             }
    7211                 :             else
    7212                 :             {
    7213                 :                 /* no source for destination column */
    7214 GIC         103 :                 value = (Datum) 0;
    7215             103 :                 isnull = true;
    7216             103 :                 valtype = UNKNOWNOID;
    7217 CBC         103 :                 valtypmod = -1;
    7218 ECB             : 
    7219 CBC         103 :                 if (strict_multiassignment_level)
    7220               6 :                     ereport(strict_multiassignment_level,
    7221                 :                             (errcode(ERRCODE_DATATYPE_MISMATCH),
    7222 ECB             :                              errmsg("number of source and target fields in assignment does not match"),
    7223                 :                     /* translator: %s represents a name of an extra check */
    7224                 :                              errdetail("%s check of %s is active.",
    7225                 :                                        "strict_multi_assignment",
    7226                 :                                        strict_multiassignment_level == ERROR ? "extra_errors" :
    7227                 :                                        "extra_warnings"),
    7228                 :                              errhint("Make sure the query returns the exact list of columns.")));
    7229                 :             }
    7230                 : 
    7231 GIC       29803 :             exec_assign_value(estate, (PLpgSQL_datum *) var,
    7232                 :                               value, isnull, valtype, valtypmod);
    7233                 :         }
    7234 ECB             : 
    7235                 :         /*
    7236                 :          * When strict_multiassignment extra check is active, ensure there are
    7237                 :          * no unassigned source attributes.
    7238                 :          */
    7239 GIC       26694 :         if (strict_multiassignment_level && anum < td_natts)
    7240                 :         {
    7241               6 :             while (anum < td_natts &&
    7242 CBC           6 :                    TupleDescAttr(tupdesc, anum)->attisdropped)
    7243 UIC           0 :                 anum++;         /* skip dropped column in tuple */
    7244 ECB             : 
    7245 CBC           6 :             if (anum < td_natts)
    7246 GBC           6 :                 ereport(strict_multiassignment_level,
    7247                 :                         (errcode(ERRCODE_DATATYPE_MISMATCH),
    7248 ECB             :                          errmsg("number of source and target fields in assignment does not match"),
    7249                 :                 /* translator: %s represents a name of an extra check */
    7250                 :                          errdetail("%s check of %s is active.",
    7251                 :                                    "strict_multi_assignment",
    7252                 :                                    strict_multiassignment_level == ERROR ? "extra_errors" :
    7253                 :                                    "extra_warnings"),
    7254                 :                          errhint("Make sure the query returns the exact list of columns.")));
    7255                 :         }
    7256                 : 
    7257 GIC       26691 :         return;
    7258                 :     }
    7259                 : 
    7260 LBC           0 :     elog(ERROR, "unsupported target type: %d", target->dtype);
    7261                 : }
    7262                 : 
    7263 EUB             : /*
    7264                 :  * compatible_tupdescs: detect whether two tupdescs are physically compatible
    7265                 :  *
    7266                 :  * TRUE indicates that a tuple satisfying src_tupdesc can be used directly as
    7267                 :  * a value for a composite variable using dst_tupdesc.
    7268                 :  */
    7269                 : static bool
    7270 GIC         119 : compatible_tupdescs(TupleDesc src_tupdesc, TupleDesc dst_tupdesc)
    7271                 : {
    7272                 :     int         i;
    7273 ECB             : 
    7274                 :     /* Possibly we could allow src_tupdesc to have extra columns? */
    7275 GIC         119 :     if (dst_tupdesc->natts != src_tupdesc->natts)
    7276              11 :         return false;
    7277                 : 
    7278 CBC         279 :     for (i = 0; i < dst_tupdesc->natts; i++)
    7279 ECB             :     {
    7280 GIC         211 :         Form_pg_attribute dattr = TupleDescAttr(dst_tupdesc, i);
    7281 CBC         211 :         Form_pg_attribute sattr = TupleDescAttr(src_tupdesc, i);
    7282                 : 
    7283             211 :         if (dattr->attisdropped != sattr->attisdropped)
    7284               3 :             return false;
    7285 GIC         208 :         if (!dattr->attisdropped)
    7286 ECB             :         {
    7287                 :             /* Normal columns must match by type and typmod */
    7288 CBC         208 :             if (dattr->atttypid != sattr->atttypid ||
    7289 GIC         171 :                 (dattr->atttypmod >= 0 &&
    7290               6 :                  dattr->atttypmod != sattr->atttypmod))
    7291 CBC          37 :                 return false;
    7292 ECB             :         }
    7293                 :         else
    7294                 :         {
    7295                 :             /* Dropped columns are OK as long as length/alignment match */
    7296 UIC           0 :             if (dattr->attlen != sattr->attlen ||
    7297               0 :                 dattr->attalign != sattr->attalign)
    7298               0 :                 return false;
    7299 EUB             :         }
    7300                 :     }
    7301 GBC          68 :     return true;
    7302                 : }
    7303                 : 
    7304 ECB             : /* ----------
    7305                 :  * make_tuple_from_row      Make a tuple from the values of a row object
    7306                 :  *
    7307                 :  * A NULL return indicates rowtype mismatch; caller must raise suitable error
    7308                 :  *
    7309                 :  * The result tuple is freshly palloc'd in caller's context.  Some junk
    7310                 :  * may be left behind in eval_mcontext, too.
    7311                 :  * ----------
    7312                 :  */
    7313                 : static HeapTuple
    7314 GIC        3107 : make_tuple_from_row(PLpgSQL_execstate *estate,
    7315                 :                     PLpgSQL_row *row,
    7316                 :                     TupleDesc tupdesc)
    7317 ECB             : {
    7318 GIC        3107 :     int         natts = tupdesc->natts;
    7319                 :     HeapTuple   tuple;
    7320                 :     Datum      *dvalues;
    7321 ECB             :     bool       *nulls;
    7322                 :     int         i;
    7323                 : 
    7324 GIC        3107 :     if (natts != row->nfields)
    7325 UIC           0 :         return NULL;
    7326                 : 
    7327 CBC        3107 :     dvalues = (Datum *) eval_mcontext_alloc0(estate, natts * sizeof(Datum));
    7328 GBC        3107 :     nulls = (bool *) eval_mcontext_alloc(estate, natts * sizeof(bool));
    7329                 : 
    7330 CBC       12275 :     for (i = 0; i < natts; i++)
    7331 ECB             :     {
    7332                 :         Oid         fieldtypeid;
    7333                 :         int32       fieldtypmod;
    7334                 : 
    7335 GIC        9168 :         if (TupleDescAttr(tupdesc, i)->attisdropped)
    7336                 :         {
    7337 UIC           0 :             nulls[i] = true;    /* leave the column as null */
    7338 LBC           0 :             continue;
    7339                 :         }
    7340 EUB             : 
    7341 GBC        9168 :         exec_eval_datum(estate, estate->datums[row->varnos[i]],
    7342                 :                         &fieldtypeid, &fieldtypmod,
    7343 GIC        9168 :                         &dvalues[i], &nulls[i]);
    7344 CBC        9168 :         if (fieldtypeid != TupleDescAttr(tupdesc, i)->atttypid)
    7345 UIC           0 :             return NULL;
    7346 ECB             :         /* XXX should we insist on typmod match, too? */
    7347                 :     }
    7348 EUB             : 
    7349 GIC        3107 :     tuple = heap_form_tuple(tupdesc, dvalues, nulls);
    7350                 : 
    7351            3107 :     return tuple;
    7352 ECB             : }
    7353                 : 
    7354                 : /*
    7355                 :  * deconstruct_composite_datum      extract tuple+tupdesc from composite Datum
    7356                 :  *
    7357                 :  * The caller must supply a HeapTupleData variable, in which we set up a
    7358                 :  * tuple header pointing to the composite datum's body.  To make the tuple
    7359                 :  * value outlive that variable, caller would need to apply heap_copytuple...
    7360                 :  * but current callers only need a short-lived tuple value anyway.
    7361                 :  *
    7362                 :  * Returns a pointer to the TupleDesc of the datum's rowtype.
    7363                 :  * Caller is responsible for calling ReleaseTupleDesc when done with it.
    7364                 :  *
    7365                 :  * Note: it's caller's responsibility to be sure value is of composite type.
    7366                 :  * Also, best to call this in a short-lived context, as it might leak memory.
    7367                 :  */
    7368                 : static TupleDesc
    7369 GIC        3296 : deconstruct_composite_datum(Datum value, HeapTupleData *tmptup)
    7370                 : {
    7371                 :     HeapTupleHeader td;
    7372 ECB             :     Oid         tupType;
    7373                 :     int32       tupTypmod;
    7374                 : 
    7375                 :     /* Get tuple body (note this could involve detoasting) */
    7376 GIC        3296 :     td = DatumGetHeapTupleHeader(value);
    7377                 : 
    7378                 :     /* Build a temporary HeapTuple control structure */
    7379 CBC        3296 :     tmptup->t_len = HeapTupleHeaderGetDatumLength(td);
    7380 GIC        3296 :     ItemPointerSetInvalid(&(tmptup->t_self));
    7381            3296 :     tmptup->t_tableOid = InvalidOid;
    7382 CBC        3296 :     tmptup->t_data = td;
    7383 ECB             : 
    7384                 :     /* Extract rowtype info and find a tupdesc */
    7385 CBC        3296 :     tupType = HeapTupleHeaderGetTypeId(td);
    7386 GIC        3296 :     tupTypmod = HeapTupleHeaderGetTypMod(td);
    7387            3296 :     return lookup_rowtype_tupdesc(tupType, tupTypmod);
    7388 ECB             : }
    7389                 : 
    7390                 : /*
    7391                 :  * exec_move_row_from_datum     Move a composite Datum into a record or row
    7392                 :  *
    7393                 :  * This is equivalent to deconstruct_composite_datum() followed by
    7394                 :  * exec_move_row(), but we can optimize things if the Datum is an
    7395                 :  * expanded-record reference.
    7396                 :  *
    7397                 :  * Note: it's caller's responsibility to be sure value is of composite type.
    7398                 :  */
    7399                 : static void
    7400 GIC         450 : exec_move_row_from_datum(PLpgSQL_execstate *estate,
    7401                 :                          PLpgSQL_variable *target,
    7402                 :                          Datum value)
    7403 ECB             : {
    7404                 :     /* Check to see if source is an expanded record */
    7405 GIC         450 :     if (VARATT_IS_EXTERNAL_EXPANDED(DatumGetPointer(value)))
    7406              10 :     {
    7407             166 :         ExpandedRecordHeader *erh = (ExpandedRecordHeader *) DatumGetEOHP(value);
    7408 CBC         166 :         ExpandedRecordHeader *newerh = NULL;
    7409 ECB             : 
    7410 CBC         166 :         Assert(erh->er_magic == ER_MAGIC);
    7411 ECB             : 
    7412                 :         /* These cases apply if the target is record not row... */
    7413 CBC         166 :         if (target->dtype == PLPGSQL_DTYPE_REC)
    7414                 :         {
    7415 GIC         166 :             PLpgSQL_rec *rec = (PLpgSQL_rec *) target;
    7416 ECB             : 
    7417                 :             /*
    7418                 :              * If it's the same record already stored in the variable, do
    7419                 :              * nothing.  This would happen only in silly cases like "r := r",
    7420                 :              * but we need some check to avoid possibly freeing the variable's
    7421                 :              * live value below.  Note that this applies even if what we have
    7422                 :              * is a R/O pointer.
    7423                 :              */
    7424 GIC         166 :             if (erh == rec->erh)
    7425               1 :                 return;
    7426                 : 
    7427 ECB             :             /*
    7428                 :              * Make sure rec->rectypeid is up-to-date before using it.
    7429                 :              */
    7430 GIC         165 :             revalidate_rectypeid(rec);
    7431                 : 
    7432                 :             /*
    7433 ECB             :              * If we have a R/W pointer, we're allowed to just commandeer
    7434                 :              * ownership of the expanded record.  If it's of the right type to
    7435                 :              * put into the record variable, do that.  (Note we don't accept
    7436                 :              * an expanded record of a composite-domain type as a RECORD
    7437                 :              * value.  We'll treat it as the base composite type instead;
    7438                 :              * compare logic in make_expanded_record_for_rec.)
    7439                 :              */
    7440 GIC         165 :             if (VARATT_IS_EXTERNAL_EXPANDED_RW(DatumGetPointer(value)) &&
    7441               3 :                 (rec->rectypeid == erh->er_decltypeid ||
    7442               1 :                  (rec->rectypeid == RECORDOID &&
    7443 CBC           1 :                   !ExpandedRecordIsDomain(erh))))
    7444 ECB             :             {
    7445 CBC           3 :                 assign_record_var(estate, rec, erh);
    7446               3 :                 return;
    7447                 :             }
    7448 ECB             : 
    7449                 :             /*
    7450                 :              * If we already have an expanded record object in the target
    7451                 :              * variable, and the source record contains a valid tuple
    7452                 :              * representation with the right rowtype, then we can skip making
    7453                 :              * a new expanded record and just assign the tuple with
    7454                 :              * expanded_record_set_tuple.  (We can't do the equivalent if we
    7455                 :              * have to do field-by-field assignment, since that wouldn't be
    7456                 :              * atomic if there's an error.)  We consider that there's a
    7457                 :              * rowtype match only if it's the same named composite type or
    7458                 :              * same registered rowtype; checking for matches of anonymous
    7459                 :              * rowtypes would be more expensive than this is worth.
    7460                 :              */
    7461 GIC         162 :             if (rec->erh &&
    7462               4 :                 (erh->flags & ER_FLAG_FVALUE_VALID) &&
    7463               2 :                 erh->er_typeid == rec->erh->er_typeid &&
    7464 CBC           1 :                 (erh->er_typeid != RECORDOID ||
    7465 LBC           0 :                  (erh->er_typmod == rec->erh->er_typmod &&
    7466               0 :                   erh->er_typmod >= 0)))
    7467 ECB             :             {
    7468 GBC           1 :                 expanded_record_set_tuple(rec->erh, erh->fvalue,
    7469               1 :                                           true, !estate->atomic);
    7470 GIC           1 :                 return;
    7471 ECB             :             }
    7472                 : 
    7473                 :             /*
    7474                 :              * Otherwise we're gonna need a new expanded record object.  Make
    7475                 :              * it here in hopes of piggybacking on the source object's
    7476                 :              * previous typcache lookup.
    7477                 :              */
    7478 GIC         161 :             newerh = make_expanded_record_for_rec(estate, rec, NULL, erh);
    7479                 : 
    7480                 :             /*
    7481 ECB             :              * If the expanded record contains a valid tuple representation,
    7482                 :              * and we don't need rowtype conversion, then just copying the
    7483                 :              * tuple is probably faster than field-by-field processing.  (This
    7484                 :              * isn't duplicative of the previous check, since here we will
    7485                 :              * catch the case where the record variable was previously empty.)
    7486                 :              */
    7487 GIC         161 :             if ((erh->flags & ER_FLAG_FVALUE_VALID) &&
    7488             152 :                 (rec->rectypeid == RECORDOID ||
    7489               4 :                  rec->rectypeid == erh->er_typeid))
    7490 ECB             :             {
    7491 CBC         151 :                 expanded_record_set_tuple(newerh, erh->fvalue,
    7492             151 :                                           true, !estate->atomic);
    7493 GIC         151 :                 assign_record_var(estate, rec, newerh);
    7494 CBC         151 :                 return;
    7495 ECB             :             }
    7496                 : 
    7497                 :             /*
    7498                 :              * Need to special-case empty source record, else code below would
    7499                 :              * leak newerh.
    7500                 :              */
    7501 GIC          10 :             if (ExpandedRecordIsEmpty(erh))
    7502                 :             {
    7503                 :                 /* Set newerh to a row of NULLs */
    7504 LBC           0 :                 deconstruct_expanded_record(newerh);
    7505 UIC           0 :                 assign_record_var(estate, rec, newerh);
    7506               0 :                 return;
    7507 EUB             :             }
    7508                 :         }                       /* end of record-target-only cases */
    7509                 : 
    7510                 :         /*
    7511                 :          * If the source expanded record is empty, we should treat that like a
    7512                 :          * NULL tuple value.  (We're unlikely to see such a case, but we must
    7513                 :          * check this; deconstruct_expanded_record would cause a change of
    7514                 :          * logical state, which is not OK.)
    7515                 :          */
    7516 GIC          10 :         if (ExpandedRecordIsEmpty(erh))
    7517                 :         {
    7518 UIC           0 :             exec_move_row(estate, target, NULL,
    7519 ECB             :                           expanded_record_get_tupdesc(erh));
    7520 UIC           0 :             return;
    7521 EUB             :         }
    7522                 : 
    7523                 :         /*
    7524                 :          * Otherwise, ensure that the source record is deconstructed, and
    7525                 :          * assign from its field values.
    7526                 :          */
    7527 GIC          10 :         deconstruct_expanded_record(erh);
    7528              10 :         exec_move_row_from_fields(estate, target, newerh,
    7529                 :                                   erh->dvalues, erh->dnulls,
    7530 ECB             :                                   expanded_record_get_tupdesc(erh));
    7531                 :     }
    7532                 :     else
    7533                 :     {
    7534                 :         /*
    7535                 :          * Nope, we've got a plain composite Datum.  Deconstruct it; but we
    7536                 :          * don't use deconstruct_composite_datum(), because we may be able to
    7537                 :          * skip calling lookup_rowtype_tupdesc().
    7538                 :          */
    7539                 :         HeapTupleHeader td;
    7540                 :         HeapTupleData tmptup;
    7541                 :         Oid         tupType;
    7542                 :         int32       tupTypmod;
    7543                 :         TupleDesc   tupdesc;
    7544                 :         MemoryContext oldcontext;
    7545                 : 
    7546                 :         /* Ensure that any detoasted data winds up in the eval_mcontext */
    7547 GIC         284 :         oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
    7548                 :         /* Get tuple body (note this could involve detoasting) */
    7549             284 :         td = DatumGetHeapTupleHeader(value);
    7550 CBC         284 :         MemoryContextSwitchTo(oldcontext);
    7551                 : 
    7552 ECB             :         /* Build a temporary HeapTuple control structure */
    7553 CBC         284 :         tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
    7554 GIC         284 :         ItemPointerSetInvalid(&(tmptup.t_self));
    7555             284 :         tmptup.t_tableOid = InvalidOid;
    7556 CBC         284 :         tmptup.t_data = td;
    7557 ECB             : 
    7558                 :         /* Extract rowtype info */
    7559 CBC         284 :         tupType = HeapTupleHeaderGetTypeId(td);
    7560 GIC         284 :         tupTypmod = HeapTupleHeaderGetTypMod(td);
    7561                 : 
    7562 ECB             :         /* Now, if the target is record not row, maybe we can optimize ... */
    7563 CBC         284 :         if (target->dtype == PLPGSQL_DTYPE_REC)
    7564                 :         {
    7565 GIC         263 :             PLpgSQL_rec *rec = (PLpgSQL_rec *) target;
    7566 ECB             : 
    7567                 :             /*
    7568                 :              * If we already have an expanded record object in the target
    7569                 :              * variable, and the source datum has a matching rowtype, then we
    7570                 :              * can skip making a new expanded record and just assign the tuple
    7571                 :              * with expanded_record_set_tuple.  We consider that there's a
    7572                 :              * rowtype match only if it's the same named composite type or
    7573                 :              * same registered rowtype.  (Checking to reject an anonymous
    7574                 :              * rowtype here should be redundant, but let's be safe.)
    7575                 :              */
    7576 GIC         263 :             if (rec->erh &&
    7577              79 :                 tupType == rec->erh->er_typeid &&
    7578               1 :                 (tupType != RECORDOID ||
    7579 CBC           1 :                  (tupTypmod == rec->erh->er_typmod &&
    7580 ECB             :                   tupTypmod >= 0)))
    7581                 :             {
    7582 CBC          66 :                 expanded_record_set_tuple(rec->erh, &tmptup,
    7583 GIC          66 :                                           true, !estate->atomic);
    7584             215 :                 return;
    7585 ECB             :             }
    7586                 : 
    7587                 :             /*
    7588                 :              * If the source datum has a rowtype compatible with the target
    7589                 :              * variable, just build a new expanded record and assign the tuple
    7590                 :              * into it.  Using make_expanded_record_from_typeid() here saves
    7591                 :              * one typcache lookup compared to the code below.
    7592                 :              */
    7593 GIC         197 :             if (rec->rectypeid == RECORDOID || rec->rectypeid == tupType)
    7594                 :             {
    7595                 :                 ExpandedRecordHeader *newerh;
    7596 CBC         149 :                 MemoryContext mcontext = get_eval_mcontext(estate);
    7597                 : 
    7598 GIC         149 :                 newerh = make_expanded_record_from_typeid(tupType, tupTypmod,
    7599 ECB             :                                                           mcontext);
    7600 GIC         149 :                 expanded_record_set_tuple(newerh, &tmptup,
    7601 CBC         149 :                                           true, !estate->atomic);
    7602 GIC         149 :                 assign_record_var(estate, rec, newerh);
    7603 CBC         149 :                 return;
    7604 ECB             :             }
    7605                 : 
    7606                 :             /*
    7607                 :              * Otherwise, we're going to need conversion, so fall through to
    7608                 :              * do it the hard way.
    7609                 :              */
    7610                 :         }
    7611                 : 
    7612                 :         /*
    7613                 :          * ROW target, or unoptimizable RECORD target, so we have to expend a
    7614                 :          * lookup to obtain the source datum's tupdesc.
    7615                 :          */
    7616 GIC          69 :         tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
    7617                 : 
    7618                 :         /* Do the move */
    7619 CBC          69 :         exec_move_row(estate, target, &tmptup, tupdesc);
    7620                 : 
    7621                 :         /* Release tupdesc usage count */
    7622              62 :         ReleaseTupleDesc(tupdesc);
    7623                 :     }
    7624                 : }
    7625 ECB             : 
    7626                 : /*
    7627                 :  * If we have not created an expanded record to hold the record variable's
    7628                 :  * value, do so.  The expanded record will be "empty", so this does not
    7629                 :  * change the logical state of the record variable: it's still NULL.
    7630                 :  * However, now we'll have a tupdesc with which we can e.g. look up fields.
    7631                 :  */
    7632                 : static void
    7633 GIC          55 : instantiate_empty_record_variable(PLpgSQL_execstate *estate, PLpgSQL_rec *rec)
    7634                 : {
    7635              55 :     Assert(rec->erh == NULL);    /* else caller error */
    7636 ECB             : 
    7637                 :     /* If declared type is RECORD, we can't instantiate */
    7638 CBC          55 :     if (rec->rectypeid == RECORDOID)
    7639 GIC           2 :         ereport(ERROR,
    7640                 :                 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
    7641 ECB             :                  errmsg("record \"%s\" is not assigned yet", rec->refname),
    7642                 :                  errdetail("The tuple structure of a not-yet-assigned record is indeterminate.")));
    7643                 : 
    7644                 :     /* Make sure rec->rectypeid is up-to-date before using it */
    7645 GIC          53 :     revalidate_rectypeid(rec);
    7646                 : 
    7647                 :     /* OK, do it */
    7648 CBC          52 :     rec->erh = make_expanded_record_from_typeid(rec->rectypeid, -1,
    7649                 :                                                 estate->datum_context);
    7650 GIC          52 : }
    7651 ECB             : 
    7652                 : /* ----------
    7653                 :  * convert_value_to_string          Convert a non-null Datum to C string
    7654                 :  *
    7655                 :  * Note: the result is in the estate's eval_mcontext, and will be cleared
    7656                 :  * by the next exec_eval_cleanup() call.  The invoked output function might
    7657                 :  * leave additional cruft there as well, so just pfree'ing the result string
    7658                 :  * would not be enough to avoid memory leaks if we did not do it like this.
    7659                 :  * In most usages the Datum being passed in is also in that context (if
    7660                 :  * pass-by-reference) and so an exec_eval_cleanup() call is needed anyway.
    7661                 :  *
    7662                 :  * Note: not caching the conversion function lookup is bad for performance.
    7663                 :  * However, this function isn't currently used in any places where an extra
    7664                 :  * catalog lookup or two seems like a big deal.
    7665                 :  * ----------
    7666                 :  */
    7667                 : static char *
    7668 GIC       27110 : convert_value_to_string(PLpgSQL_execstate *estate, Datum value, Oid valtype)
    7669                 : {
    7670                 :     char       *result;
    7671 ECB             :     MemoryContext oldcontext;
    7672                 :     Oid         typoutput;
    7673                 :     bool        typIsVarlena;
    7674                 : 
    7675 GIC       27110 :     oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
    7676           27110 :     getTypeOutputInfo(valtype, &typoutput, &typIsVarlena);
    7677           27110 :     result = OidOutputFunctionCall(typoutput, value);
    7678 CBC       27110 :     MemoryContextSwitchTo(oldcontext);
    7679 ECB             : 
    7680 CBC       27110 :     return result;
    7681 ECB             : }
    7682                 : 
    7683                 : /* ----------
    7684                 :  * exec_cast_value          Cast a value if required
    7685                 :  *
    7686                 :  * Note that *isnull is an input and also an output parameter.  While it's
    7687                 :  * unlikely that a cast operation would produce null from non-null or vice
    7688                 :  * versa, that could happen in principle.
    7689                 :  *
    7690                 :  * Note: the estate's eval_mcontext is used for temporary storage, and may
    7691                 :  * also contain the result Datum if we have to do a conversion to a pass-
    7692                 :  * by-reference data type.  Be sure to do an exec_eval_cleanup() call when
    7693                 :  * done with the result.
    7694                 :  * ----------
    7695                 :  */
    7696                 : static inline Datum
    7697 GIC      152723 : exec_cast_value(PLpgSQL_execstate *estate,
    7698                 :                 Datum value, bool *isnull,
    7699                 :                 Oid valtype, int32 valtypmod,
    7700 ECB             :                 Oid reqtype, int32 reqtypmod)
    7701                 : {
    7702                 :     /*
    7703                 :      * If the type of the given value isn't what's requested, convert it.
    7704                 :      */
    7705 GIC      152723 :     if (valtype != reqtype ||
    7706 UIC           0 :         (valtypmod != reqtypmod && reqtypmod != -1))
    7707                 :     {
    7708 ECB             :         /* We keep the slow path out-of-line. */
    7709 GBC        1473 :         value = do_cast_value(estate, value, isnull, valtype, valtypmod,
    7710                 :                               reqtype, reqtypmod);
    7711                 :     }
    7712 ECB             : 
    7713 GIC      152690 :     return value;
    7714                 : }
    7715                 : 
    7716 ECB             : /* ----------
    7717                 :  * do_cast_value            Slow path for exec_cast_value.
    7718                 :  * ----------
    7719                 :  */
    7720                 : static Datum
    7721 GIC        1473 : do_cast_value(PLpgSQL_execstate *estate,
    7722                 :               Datum value, bool *isnull,
    7723                 :               Oid valtype, int32 valtypmod,
    7724 ECB             :               Oid reqtype, int32 reqtypmod)
    7725                 : {
    7726                 :     plpgsql_CastHashEntry *cast_entry;
    7727                 : 
    7728 GIC        1473 :     cast_entry = get_cast_hashentry(estate,
    7729                 :                                     valtype, valtypmod,
    7730                 :                                     reqtype, reqtypmod);
    7731 CBC        1473 :     if (cast_entry)
    7732                 :     {
    7733 GIC        1473 :         ExprContext *econtext = estate->eval_econtext;
    7734 ECB             :         MemoryContext oldcontext;
    7735                 : 
    7736 CBC        1473 :         oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
    7737                 : 
    7738 GIC        1473 :         econtext->caseValue_datum = value;
    7739 CBC        1473 :         econtext->caseValue_isNull = *isnull;
    7740                 : 
    7741            1473 :         cast_entry->cast_in_use = true;
    7742 ECB             : 
    7743 GIC        1473 :         value = ExecEvalExpr(cast_entry->cast_exprstate, econtext,
    7744 ECB             :                              isnull);
    7745                 : 
    7746 CBC        1440 :         cast_entry->cast_in_use = false;
    7747                 : 
    7748 GIC        1440 :         MemoryContextSwitchTo(oldcontext);
    7749 ECB             :     }
    7750                 : 
    7751 CBC        1440 :     return value;
    7752                 : }
    7753                 : 
    7754 ECB             : /* ----------
    7755                 :  * get_cast_hashentry           Look up how to perform a type cast
    7756                 :  *
    7757                 :  * Returns a plpgsql_CastHashEntry if an expression has to be evaluated,
    7758                 :  * or NULL if the cast is a mere no-op relabeling.  If there's work to be
    7759                 :  * done, the cast_exprstate field contains an expression evaluation tree
    7760                 :  * based on a CaseTestExpr input, and the cast_in_use field should be set
    7761                 :  * true while executing it.
    7762                 :  * ----------
    7763                 :  */
    7764                 : static plpgsql_CastHashEntry *
    7765 GIC        1473 : get_cast_hashentry(PLpgSQL_execstate *estate,
    7766                 :                    Oid srctype, int32 srctypmod,
    7767                 :                    Oid dsttype, int32 dsttypmod)
    7768 ECB             : {
    7769                 :     plpgsql_CastHashKey cast_key;
    7770                 :     plpgsql_CastHashEntry *cast_entry;
    7771                 :     bool        found;
    7772                 :     LocalTransactionId curlxid;
    7773                 :     MemoryContext oldcontext;
    7774                 : 
    7775                 :     /* Look for existing entry */
    7776 GIC        1473 :     cast_key.srctype = srctype;
    7777            1473 :     cast_key.dsttype = dsttype;
    7778            1473 :     cast_key.srctypmod = srctypmod;
    7779 CBC        1473 :     cast_key.dsttypmod = dsttypmod;
    7780            1473 :     cast_entry = (plpgsql_CastHashEntry *) hash_search(estate->cast_hash,
    7781                 :                                                        &cast_key,
    7782 ECB             :                                                        HASH_ENTER, &found);
    7783 CBC        1473 :     if (!found)                 /* initialize if new entry */
    7784 GIC         163 :         cast_entry->cast_cexpr = NULL;
    7785                 : 
    7786 CBC        1473 :     if (cast_entry->cast_cexpr == NULL ||
    7787            1310 :         !cast_entry->cast_cexpr->is_valid)
    7788                 :     {
    7789 ECB             :         /*
    7790                 :          * We've not looked up this coercion before, or we have but the cached
    7791                 :          * expression has been invalidated.
    7792                 :          */
    7793                 :         Node       *cast_expr;
    7794                 :         CachedExpression *cast_cexpr;
    7795                 :         CaseTestExpr *placeholder;
    7796                 : 
    7797                 :         /*
    7798                 :          * Drop old cached expression if there is one.
    7799                 :          */
    7800 GIC         177 :         if (cast_entry->cast_cexpr)
    7801                 :         {
    7802              14 :             FreeCachedExpression(cast_entry->cast_cexpr);
    7803 CBC          14 :             cast_entry->cast_cexpr = NULL;
    7804                 :         }
    7805 ECB             : 
    7806                 :         /*
    7807                 :          * Since we could easily fail (no such coercion), construct a
    7808                 :          * temporary coercion expression tree in the short-lived
    7809                 :          * eval_mcontext, then if successful save it as a CachedExpression.
    7810                 :          */
    7811 GIC         177 :         oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
    7812                 : 
    7813                 :         /*
    7814 ECB             :          * We use a CaseTestExpr as the base of the coercion tree, since it's
    7815                 :          * very cheap to insert the source value for that.
    7816                 :          */
    7817 GIC         177 :         placeholder = makeNode(CaseTestExpr);
    7818             177 :         placeholder->typeId = srctype;
    7819             177 :         placeholder->typeMod = srctypmod;
    7820 CBC         177 :         placeholder->collation = get_typcollation(srctype);
    7821 ECB             : 
    7822                 :         /*
    7823                 :          * Apply coercion.  We use the special coercion context
    7824                 :          * COERCION_PLPGSQL to match plpgsql's historical behavior, namely
    7825                 :          * that any cast not available at ASSIGNMENT level will be implemented
    7826                 :          * as an I/O coercion.  (It's somewhat dubious that we prefer I/O
    7827                 :          * coercion over cast pathways that exist at EXPLICIT level.  Changing
    7828                 :          * that would cause assorted minor behavioral differences though, and
    7829                 :          * a user who wants the explicit-cast behavior can always write an
    7830                 :          * explicit cast.)
    7831                 :          *
    7832                 :          * If source type is UNKNOWN, coerce_to_target_type will fail (it only
    7833                 :          * expects to see that for Const input nodes), so don't call it; we'll
    7834                 :          * apply CoerceViaIO instead.  Likewise, it doesn't currently work for
    7835                 :          * coercing RECORD to some other type, so skip for that too.
    7836                 :          */
    7837 GIC         177 :         if (srctype == UNKNOWNOID || srctype == RECORDOID)
    7838              57 :             cast_expr = NULL;
    7839                 :         else
    7840 CBC         120 :             cast_expr = coerce_to_target_type(NULL,
    7841 ECB             :                                               (Node *) placeholder, srctype,
    7842                 :                                               dsttype, dsttypmod,
    7843                 :                                               COERCION_PLPGSQL,
    7844                 :                                               COERCE_IMPLICIT_CAST,
    7845                 :                                               -1);
    7846                 : 
    7847                 :         /*
    7848                 :          * If there's no cast path according to the parser, fall back to using
    7849                 :          * an I/O coercion; this is semantically dubious but matches plpgsql's
    7850                 :          * historical behavior.  We would need something of the sort for
    7851                 :          * UNKNOWN literals in any case.  (This is probably now only reachable
    7852                 :          * in the case where srctype is UNKNOWN/RECORD.)
    7853                 :          */
    7854 GIC         177 :         if (cast_expr == NULL)
    7855                 :         {
    7856              57 :             CoerceViaIO *iocoerce = makeNode(CoerceViaIO);
    7857 ECB             : 
    7858 GIC          57 :             iocoerce->arg = (Expr *) placeholder;
    7859 CBC          57 :             iocoerce->resulttype = dsttype;
    7860 GIC          57 :             iocoerce->resultcollid = InvalidOid;
    7861 CBC          57 :             iocoerce->coerceformat = COERCE_IMPLICIT_CAST;
    7862              57 :             iocoerce->location = -1;
    7863              57 :             cast_expr = (Node *) iocoerce;
    7864              57 :             if (dsttypmod != -1)
    7865 LBC           0 :                 cast_expr = coerce_to_target_type(NULL,
    7866 ECB             :                                                   cast_expr, dsttype,
    7867                 :                                                   dsttype, dsttypmod,
    7868 EUB             :                                                   COERCION_ASSIGNMENT,
    7869                 :                                                   COERCE_IMPLICIT_CAST,
    7870                 :                                                   -1);
    7871                 :         }
    7872                 : 
    7873                 :         /* Note: we don't bother labeling the expression tree with collation */
    7874                 : 
    7875                 :         /* Plan the expression and build a CachedExpression */
    7876 GIC         177 :         cast_cexpr = GetCachedExpression(cast_expr);
    7877             177 :         cast_expr = cast_cexpr->expr;
    7878                 : 
    7879 ECB             :         /* Detect whether we have a no-op (RelabelType) coercion */
    7880 CBC         177 :         if (IsA(cast_expr, RelabelType) &&
    7881 GIC          10 :             ((RelabelType *) cast_expr)->arg == (Expr *) placeholder)
    7882 UIC           0 :             cast_expr = NULL;
    7883 ECB             : 
    7884                 :         /* Now we can fill in the hashtable entry. */
    7885 GBC         177 :         cast_entry->cast_cexpr = cast_cexpr;
    7886 GIC         177 :         cast_entry->cast_expr = (Expr *) cast_expr;
    7887             177 :         cast_entry->cast_exprstate = NULL;
    7888 CBC         177 :         cast_entry->cast_in_use = false;
    7889             177 :         cast_entry->cast_lxid = InvalidLocalTransactionId;
    7890 ECB             : 
    7891 CBC         177 :         MemoryContextSwitchTo(oldcontext);
    7892 ECB             :     }
    7893                 : 
    7894                 :     /* Done if we have determined that this is a no-op cast. */
    7895 GIC        1473 :     if (cast_entry->cast_expr == NULL)
    7896 UIC           0 :         return NULL;
    7897                 : 
    7898 ECB             :     /*
    7899 EUB             :      * Prepare the expression for execution, if it's not been done already in
    7900                 :      * the current transaction; also, if it's marked busy in the current
    7901                 :      * transaction, abandon that expression tree and build a new one, so as to
    7902                 :      * avoid potential problems with recursive cast expressions and failed
    7903                 :      * executions.  (We will leak some memory intra-transaction if that
    7904                 :      * happens a lot, but we don't expect it to.)  It's okay to update the
    7905                 :      * hash table with the new tree because all plpgsql functions within a
    7906                 :      * given transaction share the same simple_eval_estate.  (Well, regular
    7907                 :      * functions do; DO blocks have private simple_eval_estates, and private
    7908                 :      * cast hash tables to go with them.)
    7909                 :      */
    7910 GIC        1473 :     curlxid = MyProc->lxid;
    7911            1473 :     if (cast_entry->cast_lxid != curlxid || cast_entry->cast_in_use)
    7912                 :     {
    7913 CBC         319 :         oldcontext = MemoryContextSwitchTo(estate->simple_eval_estate->es_query_cxt);
    7914             319 :         cast_entry->cast_exprstate = ExecInitExpr(cast_entry->cast_expr, NULL);
    7915 GIC         319 :         cast_entry->cast_in_use = false;
    7916 CBC         319 :         cast_entry->cast_lxid = curlxid;
    7917             319 :         MemoryContextSwitchTo(oldcontext);
    7918 ECB             :     }
    7919                 : 
    7920 CBC        1473 :     return cast_entry;
    7921                 : }
    7922                 : 
    7923 ECB             : 
    7924                 : /* ----------
    7925                 :  * exec_simple_check_plan -     Check if a plan is simple enough to
    7926                 :  *                              be evaluated by ExecEvalExpr() instead
    7927                 :  *                              of SPI.
    7928                 :  *
    7929                 :  * Note: the refcount manipulations in this function assume that expr->plan
    7930                 :  * is a "saved" SPI plan.  That's a bit annoying from the caller's standpoint,
    7931                 :  * but it's otherwise difficult to avoid leaking the plan on failure.
    7932                 :  * ----------
    7933                 :  */
    7934                 : static void
    7935 GIC       11547 : exec_simple_check_plan(PLpgSQL_execstate *estate, PLpgSQL_expr *expr)
    7936                 : {
    7937                 :     List       *plansources;
    7938 ECB             :     CachedPlanSource *plansource;
    7939                 :     Query      *query;
    7940                 :     CachedPlan *cplan;
    7941                 :     MemoryContext oldcontext;
    7942                 : 
    7943                 :     /*
    7944                 :      * Initialize to "not simple".
    7945                 :      */
    7946 GIC       11547 :     expr->expr_simple_expr = NULL;
    7947           11547 :     expr->expr_rw_param = NULL;
    7948                 : 
    7949 ECB             :     /*
    7950                 :      * Check the analyzed-and-rewritten form of the query to see if we will be
    7951                 :      * able to treat it as a simple expression.  Since this function is only
    7952                 :      * called immediately after creating the CachedPlanSource, we need not
    7953                 :      * worry about the query being stale.
    7954                 :      */
    7955                 : 
    7956                 :     /*
    7957                 :      * We can only test queries that resulted in exactly one CachedPlanSource
    7958                 :      */
    7959 GIC       11547 :     plansources = SPI_plan_get_plan_sources(expr->plan);
    7960           11547 :     if (list_length(plansources) != 1)
    7961 UIC           0 :         return;
    7962 CBC       11547 :     plansource = (CachedPlanSource *) linitial(plansources);
    7963 ECB             : 
    7964 EUB             :     /*
    7965 ECB             :      * 1. There must be one single querytree.
    7966                 :      */
    7967 GIC       11547 :     if (list_length(plansource->query_list) != 1)
    7968 UIC           0 :         return;
    7969 GIC       11547 :     query = (Query *) linitial(plansource->query_list);
    7970 ECB             : 
    7971 EUB             :     /*
    7972 ECB             :      * 2. It must be a plain SELECT query without any input tables
    7973                 :      */
    7974 GIC       11547 :     if (!IsA(query, Query))
    7975 UIC           0 :         return;
    7976 GIC       11547 :     if (query->commandType != CMD_SELECT)
    7977 CBC         487 :         return;
    7978 GBC       11060 :     if (query->rtable != NIL)
    7979 CBC         557 :         return;
    7980 ECB             : 
    7981                 :     /*
    7982                 :      * 3. Can't have any subplans, aggregates, qual clauses either.  (These
    7983                 :      * tests should generally match what inline_function() checks before
    7984                 :      * inlining a SQL function; otherwise, inlining could change our
    7985                 :      * conclusion about whether an expression is simple, which we don't want.)
    7986                 :      */
    7987 GIC       10503 :     if (query->hasAggs ||
    7988           10503 :         query->hasWindowFuncs ||
    7989           10503 :         query->hasTargetSRFs ||
    7990 CBC       10488 :         query->hasSubLinks ||
    7991           10302 :         query->cteList ||
    7992           10302 :         query->jointree->fromlist ||
    7993           10302 :         query->jointree->quals ||
    7994           10302 :         query->groupClause ||
    7995           10302 :         query->groupingSets ||
    7996           10302 :         query->havingQual ||
    7997           10302 :         query->windowClause ||
    7998           10302 :         query->distinctClause ||
    7999           10302 :         query->sortClause ||
    8000           10302 :         query->limitOffset ||
    8001           10302 :         query->limitCount ||
    8002           10302 :         query->setOperations)
    8003             201 :         return;
    8004 ECB             : 
    8005                 :     /*
    8006                 :      * 4. The query must have a single attribute as result
    8007                 :      */
    8008 GIC       10302 :     if (list_length(query->targetList) != 1)
    8009              52 :         return;
    8010                 : 
    8011 ECB             :     /*
    8012                 :      * OK, we can treat it as a simple plan.
    8013                 :      *
    8014                 :      * Get the generic plan for the query.  If replanning is needed, do that
    8015                 :      * work in the eval_mcontext.  (Note that replanning could throw an error,
    8016                 :      * in which case the expr is left marked "not simple", which is fine.)
    8017                 :      */
    8018 GIC       10250 :     oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
    8019           10250 :     cplan = SPI_plan_get_cached_plan(expr->plan);
    8020           10234 :     MemoryContextSwitchTo(oldcontext);
    8021 ECB             : 
    8022                 :     /* Can't fail, because we checked for a single CachedPlanSource above */
    8023 CBC       10234 :     Assert(cplan != NULL);
    8024                 : 
    8025                 :     /*
    8026 ECB             :      * Verify that plancache.c thinks the plan is simple enough to use
    8027                 :      * CachedPlanIsSimplyValid.  Given the restrictions above, it's unlikely
    8028                 :      * that this could fail, but if it does, just treat plan as not simple. On
    8029                 :      * success, save a refcount on the plan in the simple-expression resowner.
    8030                 :      */
    8031 GIC       10234 :     if (CachedPlanAllowsSimpleValidityCheck(plansource, cplan,
    8032                 :                                             estate->simple_eval_resowner))
    8033                 :     {
    8034 ECB             :         /* Remember that we have the refcount */
    8035 GIC       10234 :         expr->expr_simple_plansource = plansource;
    8036           10234 :         expr->expr_simple_plan = cplan;
    8037           10234 :         expr->expr_simple_plan_lxid = MyProc->lxid;
    8038 ECB             : 
    8039                 :         /* Share the remaining work with the replan code path */
    8040 CBC       10234 :         exec_save_simple_expr(expr, cplan);
    8041                 :     }
    8042                 : 
    8043 ECB             :     /*
    8044                 :      * Release the plan refcount obtained by SPI_plan_get_cached_plan.  (This
    8045                 :      * refcount is held by the wrong resowner, so we can't just repurpose it.)
    8046                 :      */
    8047 GIC       10234 :     ReleaseCachedPlan(cplan, CurrentResourceOwner);
    8048                 : }
    8049                 : 
    8050 ECB             : /*
    8051                 :  * exec_save_simple_expr --- extract simple expression from CachedPlan
    8052                 :  */
    8053                 : static void
    8054 GIC       12182 : exec_save_simple_expr(PLpgSQL_expr *expr, CachedPlan *cplan)
    8055                 : {
    8056                 :     PlannedStmt *stmt;
    8057 ECB             :     Plan       *plan;
    8058                 :     Expr       *tle_expr;
    8059                 : 
    8060                 :     /*
    8061                 :      * Given the checks that exec_simple_check_plan did, none of the Asserts
    8062                 :      * here should ever fail.
    8063                 :      */
    8064                 : 
    8065                 :     /* Extract the single PlannedStmt */
    8066 GIC       12182 :     Assert(list_length(cplan->stmt_list) == 1);
    8067           12182 :     stmt = linitial_node(PlannedStmt, cplan->stmt_list);
    8068           12182 :     Assert(stmt->commandType == CMD_SELECT);
    8069 ECB             : 
    8070                 :     /*
    8071                 :      * Ordinarily, the plan node should be a simple Result.  However, if
    8072                 :      * debug_parallel_query is on, the planner might've stuck a Gather node
    8073                 :      * atop that.  The simplest way to deal with this is to look through the
    8074                 :      * Gather node.  The Gather node's tlist would normally contain a Var
    8075                 :      * referencing the child node's output, but it could also be a Param, or
    8076                 :      * it could be a Const that setrefs.c copied as-is.
    8077                 :      */
    8078 GIC       12182 :     plan = stmt->planTree;
    8079                 :     for (;;)
    8080                 :     {
    8081 ECB             :         /* Extract the single tlist expression */
    8082 GIC       12182 :         Assert(list_length(plan->targetlist) == 1);
    8083           12182 :         tle_expr = linitial_node(TargetEntry, plan->targetlist)->expr;
    8084                 : 
    8085 CBC       12182 :         if (IsA(plan, Result))
    8086 ECB             :         {
    8087 GIC       12182 :             Assert(plan->lefttree == NULL &&
    8088 ECB             :                    plan->righttree == NULL &&
    8089                 :                    plan->initPlan == NULL &&
    8090                 :                    plan->qual == NULL &&
    8091                 :                    ((Result *) plan)->resconstantqual == NULL);
    8092 GIC       12182 :             break;
    8093                 :         }
    8094 UIC           0 :         else if (IsA(plan, Gather))
    8095 ECB             :         {
    8096 UIC           0 :             Assert(plan->lefttree != NULL &&
    8097 EUB             :                    plan->righttree == NULL &&
    8098                 :                    plan->initPlan == NULL &&
    8099                 :                    plan->qual == NULL);
    8100                 :             /* If setrefs.c copied up a Const, no need to look further */
    8101 UIC           0 :             if (IsA(tle_expr, Const))
    8102               0 :                 break;
    8103                 :             /* Otherwise, it had better be a Param or an outer Var */
    8104 UBC           0 :             Assert(IsA(tle_expr, Param) || (IsA(tle_expr, Var) &&
    8105 EUB             :                                             ((Var *) tle_expr)->varno == OUTER_VAR));
    8106                 :             /* Descend to the child node */
    8107 UBC           0 :             plan = plan->lefttree;
    8108                 :         }
    8109                 :         else
    8110               0 :             elog(ERROR, "unexpected plan node type: %d",
    8111                 :                  (int) nodeTag(plan));
    8112                 :     }
    8113 EUB             : 
    8114                 :     /*
    8115                 :      * Save the simple expression, and initialize state to "not valid in
    8116                 :      * current transaction".
    8117                 :      */
    8118 GIC       12182 :     expr->expr_simple_expr = tle_expr;
    8119           12182 :     expr->expr_simple_state = NULL;
    8120           12182 :     expr->expr_simple_in_use = false;
    8121 CBC       12182 :     expr->expr_simple_lxid = InvalidLocalTransactionId;
    8122 ECB             :     /* Also stash away the expression result type */
    8123 CBC       12182 :     expr->expr_simple_type = exprType((Node *) tle_expr);
    8124           12182 :     expr->expr_simple_typmod = exprTypmod((Node *) tle_expr);
    8125                 :     /* We also want to remember if it is immutable or not */
    8126           12182 :     expr->expr_simple_mutable = contain_mutable_functions((Node *) tle_expr);
    8127 ECB             : 
    8128                 :     /*
    8129                 :      * Lastly, check to see if there's a possibility of optimizing a
    8130                 :      * read/write parameter.
    8131                 :      */
    8132 GIC       12182 :     exec_check_rw_parameter(expr);
    8133           12182 : }
    8134                 : 
    8135 ECB             : /*
    8136                 :  * exec_check_rw_parameter --- can we pass expanded object as read/write param?
    8137                 :  *
    8138                 :  * If we have an assignment like "x := array_append(x, foo)" in which the
    8139                 :  * top-level function is trusted not to corrupt its argument in case of an
    8140                 :  * error, then when x has an expanded object as value, it is safe to pass the
    8141                 :  * value as a read/write pointer and let the function modify the value
    8142                 :  * in-place.
    8143                 :  *
    8144                 :  * This function checks for a safe expression, and sets expr->expr_rw_param
    8145                 :  * to the address of any Param within the expression that can be passed as
    8146                 :  * read/write (there can be only one); or to NULL when there is no safe Param.
    8147                 :  *
    8148                 :  * Note that this mechanism intentionally applies the safety labeling to just
    8149                 :  * one Param; the expression could contain other Params referencing the target
    8150                 :  * variable, but those must still be treated as read-only.
    8151                 :  *
    8152                 :  * Also note that we only apply this optimization within simple expressions.
    8153                 :  * There's no point in it for non-simple expressions, because the
    8154                 :  * exec_run_select code path will flatten any expanded result anyway.
    8155                 :  * Also, it's safe to assume that an expr_simple_expr tree won't get copied
    8156                 :  * somewhere before it gets compiled, so that looking for pointer equality
    8157                 :  * to expr_rw_param will work for matching the target Param.  That'd be much
    8158                 :  * shakier in the general case.
    8159                 :  */
    8160                 : static void
    8161 GIC       12182 : exec_check_rw_parameter(PLpgSQL_expr *expr)
    8162                 : {
    8163                 :     int         target_dno;
    8164 ECB             :     Oid         funcid;
    8165                 :     List       *fargs;
    8166                 :     ListCell   *lc;
    8167                 : 
    8168                 :     /* Assume unsafe */
    8169 GIC       12182 :     expr->expr_rw_param = NULL;
    8170                 : 
    8171                 :     /* Done if expression isn't an assignment source */
    8172 CBC       12182 :     target_dno = expr->target_param;
    8173 GIC       12182 :     if (target_dno < 0)
    8174            9930 :         return;
    8175 ECB             : 
    8176                 :     /*
    8177                 :      * If target variable isn't referenced by expression, no need to look
    8178                 :      * further.
    8179                 :      */
    8180 GIC        2252 :     if (!bms_is_member(target_dno, expr->paramnos))
    8181             374 :         return;
    8182                 : 
    8183 ECB             :     /* Shouldn't be here for non-simple expression */
    8184 CBC        1878 :     Assert(expr->expr_simple_expr != NULL);
    8185                 : 
    8186                 :     /*
    8187 ECB             :      * Top level of expression must be a simple FuncExpr, OpExpr, or
    8188                 :      * SubscriptingRef, else we can't optimize.
    8189                 :      */
    8190 GIC        1878 :     if (IsA(expr->expr_simple_expr, FuncExpr))
    8191                 :     {
    8192             490 :         FuncExpr   *fexpr = (FuncExpr *) expr->expr_simple_expr;
    8193 ECB             : 
    8194 GIC         490 :         funcid = fexpr->funcid;
    8195 CBC         490 :         fargs = fexpr->args;
    8196                 :     }
    8197            1388 :     else if (IsA(expr->expr_simple_expr, OpExpr))
    8198 ECB             :     {
    8199 GIC         539 :         OpExpr     *opexpr = (OpExpr *) expr->expr_simple_expr;
    8200 ECB             : 
    8201 GIC         539 :         funcid = opexpr->opfuncid;
    8202 CBC         539 :         fargs = opexpr->args;
    8203                 :     }
    8204             849 :     else if (IsA(expr->expr_simple_expr, SubscriptingRef))
    8205 ECB             :     {
    8206 GIC          24 :         SubscriptingRef *sbsref = (SubscriptingRef *) expr->expr_simple_expr;
    8207 ECB             : 
    8208                 :         /* We only trust standard varlena arrays to be safe */
    8209 CBC          24 :         if (get_typsubscript(sbsref->refcontainertype, NULL) !=
    8210                 :             F_ARRAY_SUBSCRIPT_HANDLER)
    8211 GIC           1 :             return;
    8212 ECB             : 
    8213                 :         /* We can optimize the refexpr if it's the target, otherwise not */
    8214 CBC          23 :         if (sbsref->refexpr && IsA(sbsref->refexpr, Param))
    8215                 :         {
    8216 GIC          23 :             Param      *param = (Param *) sbsref->refexpr;
    8217 ECB             : 
    8218 GIC          23 :             if (param->paramkind == PARAM_EXTERN &&
    8219 CBC          23 :                 param->paramid == target_dno + 1)
    8220                 :             {
    8221 ECB             :                 /* Found the Param we want to pass as read/write */
    8222 CBC          20 :                 expr->expr_rw_param = param;
    8223 GIC          20 :                 return;
    8224                 :             }
    8225 ECB             :         }
    8226                 : 
    8227 GIC           3 :         return;
    8228                 :     }
    8229                 :     else
    8230 CBC         825 :         return;
    8231                 : 
    8232                 :     /*
    8233 ECB             :      * The top-level function must be one that we trust to be "safe".
    8234                 :      * Currently we hard-wire the list, but it would be very desirable to
    8235                 :      * allow extensions to mark their functions as safe ...
    8236                 :      */
    8237 GIC        1029 :     if (!(funcid == F_ARRAY_APPEND ||
    8238                 :           funcid == F_ARRAY_PREPEND))
    8239             993 :         return;
    8240 ECB             : 
    8241                 :     /*
    8242                 :      * The target variable (in the form of a Param) must appear as a direct
    8243                 :      * argument of the top-level function.  References further down in the
    8244                 :      * tree can't be optimized; but on the other hand, they don't invalidate
    8245                 :      * optimizing the top-level call, since that will be executed last.
    8246                 :      */
    8247 GIC          48 :     foreach(lc, fargs)
    8248                 :     {
    8249              42 :         Node       *arg = (Node *) lfirst(lc);
    8250 ECB             : 
    8251 GIC          42 :         if (arg && IsA(arg, Param))
    8252 ECB             :         {
    8253 GIC          42 :             Param      *param = (Param *) arg;
    8254 ECB             : 
    8255 GIC          42 :             if (param->paramkind == PARAM_EXTERN &&
    8256 CBC          42 :                 param->paramid == target_dno + 1)
    8257                 :             {
    8258 ECB             :                 /* Found the Param we want to pass as read/write */
    8259 CBC          30 :                 expr->expr_rw_param = param;
    8260 GIC          30 :                 return;
    8261                 :             }
    8262 ECB             :         }
    8263                 :     }
    8264                 : }
    8265                 : 
    8266                 : /*
    8267                 :  * exec_check_assignable --- is it OK to assign to the indicated datum?
    8268                 :  *
    8269                 :  * This should match pl_gram.y's check_assignable().
    8270                 :  */
    8271                 : static void
    8272 GIC         147 : exec_check_assignable(PLpgSQL_execstate *estate, int dno)
    8273                 : {
    8274                 :     PLpgSQL_datum *datum;
    8275 ECB             : 
    8276 GIC         147 :     Assert(dno >= 0 && dno < estate->ndatums);
    8277             147 :     datum = estate->datums[dno];
    8278             147 :     switch (datum->dtype)
    8279 ECB             :     {
    8280 CBC         145 :         case PLPGSQL_DTYPE_VAR:
    8281 ECB             :         case PLPGSQL_DTYPE_PROMISE:
    8282                 :         case PLPGSQL_DTYPE_REC:
    8283 CBC         145 :             if (((PLpgSQL_variable *) datum)->isconst)
    8284 GIC           4 :                 ereport(ERROR,
    8285                 :                         (errcode(ERRCODE_ERROR_IN_ASSIGNMENT),
    8286 ECB             :                          errmsg("variable \"%s\" is declared CONSTANT",
    8287                 :                                 ((PLpgSQL_variable *) datum)->refname)));
    8288 GIC         141 :             break;
    8289 UIC           0 :         case PLPGSQL_DTYPE_ROW:
    8290                 :             /* always assignable; member vars were checked at compile time */
    8291 LBC           0 :             break;
    8292 GBC           2 :         case PLPGSQL_DTYPE_RECFIELD:
    8293                 :             /* assignable if parent record is */
    8294               2 :             exec_check_assignable(estate,
    8295 ECB             :                                   ((PLpgSQL_recfield *) datum)->recparentno);
    8296 GIC           2 :             break;
    8297 LBC           0 :         default:
    8298 UIC           0 :             elog(ERROR, "unrecognized dtype: %d", datum->dtype);
    8299 ECB             :             break;
    8300 EUB             :     }
    8301 GBC         143 : }
    8302                 : 
    8303                 : /* ----------
    8304 ECB             :  * exec_set_found           Set the global found variable to true/false
    8305                 :  * ----------
    8306                 :  */
    8307                 : static void
    8308 GIC       67441 : exec_set_found(PLpgSQL_execstate *estate, bool state)
    8309                 : {
    8310                 :     PLpgSQL_var *var;
    8311 ECB             : 
    8312 GIC       67441 :     var = (PLpgSQL_var *) (estate->datums[estate->found_varno]);
    8313           67441 :     assign_simple_var(estate, var, BoolGetDatum(state), false, false);
    8314           67441 : }
    8315 ECB             : 
    8316                 : /*
    8317                 :  * plpgsql_create_econtext --- create an eval_econtext for the current function
    8318                 :  *
    8319                 :  * We may need to create a new shared_simple_eval_estate too, if there's not
    8320                 :  * one already for the current transaction.  The EState will be cleaned up at
    8321                 :  * transaction end.  Ditto for shared_simple_eval_resowner.
    8322                 :  */
    8323                 : static void
    8324 GIC       48269 : plpgsql_create_econtext(PLpgSQL_execstate *estate)
    8325                 : {
    8326                 :     SimpleEcontextStackEntry *entry;
    8327 ECB             : 
    8328                 :     /*
    8329                 :      * Create an EState for evaluation of simple expressions, if there's not
    8330                 :      * one already in the current transaction.  The EState is made a child of
    8331                 :      * TopTransactionContext so it will have the right lifespan.
    8332                 :      *
    8333                 :      * Note that this path is never taken when beginning a DO block; the
    8334                 :      * required EState was already made by plpgsql_inline_handler.  However,
    8335                 :      * if the DO block executes COMMIT or ROLLBACK, then we'll come here and
    8336                 :      * make a shared EState to use for the rest of the DO block.  That's OK;
    8337                 :      * see the comments for shared_simple_eval_estate.  (Note also that a DO
    8338                 :      * block will continue to use its private cast hash table for the rest of
    8339                 :      * the block.  That's okay for now, but it might cause problems someday.)
    8340                 :      */
    8341 GIC       48269 :     if (estate->simple_eval_estate == NULL)
    8342                 :     {
    8343                 :         MemoryContext oldcontext;
    8344 ECB             : 
    8345 GIC        7457 :         if (shared_simple_eval_estate == NULL)
    8346                 :         {
    8347            7453 :             oldcontext = MemoryContextSwitchTo(TopTransactionContext);
    8348 CBC        7453 :             shared_simple_eval_estate = CreateExecutorState();
    8349 GIC        7453 :             MemoryContextSwitchTo(oldcontext);
    8350 ECB             :         }
    8351 CBC        7457 :         estate->simple_eval_estate = shared_simple_eval_estate;
    8352 ECB             :     }
    8353                 : 
    8354                 :     /*
    8355                 :      * Likewise for the simple-expression resource owner.
    8356                 :      */
    8357 GIC       48269 :     if (estate->simple_eval_resowner == NULL)
    8358                 :     {
    8359            7457 :         if (shared_simple_eval_resowner == NULL)
    8360 CBC        7453 :             shared_simple_eval_resowner =
    8361 GIC        7453 :                 ResourceOwnerCreate(TopTransactionResourceOwner,
    8362 ECB             :                                     "PL/pgSQL simple expressions");
    8363 CBC        7457 :         estate->simple_eval_resowner = shared_simple_eval_resowner;
    8364 ECB             :     }
    8365                 : 
    8366                 :     /*
    8367                 :      * Create a child econtext for the current function.
    8368                 :      */
    8369 GIC       48269 :     estate->eval_econtext = CreateExprContext(estate->simple_eval_estate);
    8370                 : 
    8371                 :     /*
    8372 ECB             :      * Make a stack entry so we can clean up the econtext at subxact end.
    8373                 :      * Stack entries are kept in TopTransactionContext for simplicity.
    8374                 :      */
    8375                 :     entry = (SimpleEcontextStackEntry *)
    8376 GIC       48269 :         MemoryContextAlloc(TopTransactionContext,
    8377                 :                            sizeof(SimpleEcontextStackEntry));
    8378                 : 
    8379 CBC       48269 :     entry->stack_econtext = estate->eval_econtext;
    8380 GIC       48269 :     entry->xact_subxid = GetCurrentSubTransactionId();
    8381                 : 
    8382 CBC       48269 :     entry->next = simple_econtext_stack;
    8383           48269 :     simple_econtext_stack = entry;
    8384 GIC       48269 : }
    8385 ECB             : 
    8386                 : /*
    8387                 :  * plpgsql_destroy_econtext --- destroy function's econtext
    8388                 :  *
    8389                 :  * We check that it matches the top stack entry, and destroy the stack
    8390                 :  * entry along with the context.
    8391                 :  */
    8392                 : static void
    8393 GIC       39511 : plpgsql_destroy_econtext(PLpgSQL_execstate *estate)
    8394                 : {
    8395                 :     SimpleEcontextStackEntry *next;
    8396 ECB             : 
    8397 GIC       39511 :     Assert(simple_econtext_stack != NULL);
    8398           39511 :     Assert(simple_econtext_stack->stack_econtext == estate->eval_econtext);
    8399                 : 
    8400 CBC       39511 :     next = simple_econtext_stack->next;
    8401           39511 :     pfree(simple_econtext_stack);
    8402 GIC       39511 :     simple_econtext_stack = next;
    8403 ECB             : 
    8404 CBC       39511 :     FreeExprContext(estate->eval_econtext, true);
    8405           39511 :     estate->eval_econtext = NULL;
    8406 GIC       39511 : }
    8407 ECB             : 
    8408                 : /*
    8409                 :  * plpgsql_xact_cb --- post-transaction-commit-or-abort cleanup
    8410                 :  *
    8411                 :  * If a simple-expression EState was created in the current transaction,
    8412                 :  * it has to be cleaned up.  The same for the simple-expression resowner.
    8413                 :  */
    8414                 : void
    8415 GIC      223111 : plpgsql_xact_cb(XactEvent event, void *arg)
    8416                 : {
    8417                 :     /*
    8418 ECB             :      * If we are doing a clean transaction shutdown, free the EState and tell
    8419                 :      * the resowner to release whatever plancache references it has, so that
    8420                 :      * all remaining resources will be released correctly.  (We don't need to
    8421                 :      * actually delete the resowner here; deletion of the
    8422                 :      * TopTransactionResourceOwner will take care of that.)
    8423                 :      *
    8424                 :      * In an abort, we expect the regular abort recovery procedures to release
    8425                 :      * everything of interest, so just clear our pointers.
    8426                 :      */
    8427 GIC      223111 :     if (event == XACT_EVENT_COMMIT ||
    8428          114207 :         event == XACT_EVENT_PARALLEL_COMMIT ||
    8429                 :         event == XACT_EVENT_PREPARE)
    8430 ECB             :     {
    8431 CBC      108920 :         simple_econtext_stack = NULL;
    8432                 : 
    8433 GIC      108920 :         if (shared_simple_eval_estate)
    8434 CBC        6835 :             FreeExecutorState(shared_simple_eval_estate);
    8435 GIC      108920 :         shared_simple_eval_estate = NULL;
    8436 CBC      108920 :         if (shared_simple_eval_resowner)
    8437            6835 :             ResourceOwnerReleaseAllPlanCacheRefs(shared_simple_eval_resowner);
    8438          108920 :         shared_simple_eval_resowner = NULL;
    8439 ECB             :     }
    8440 CBC      114191 :     else if (event == XACT_EVENT_ABORT ||
    8441 ECB             :              event == XACT_EVENT_PARALLEL_ABORT)
    8442                 :     {
    8443 CBC        5263 :         simple_econtext_stack = NULL;
    8444 GIC        5263 :         shared_simple_eval_estate = NULL;
    8445            5263 :         shared_simple_eval_resowner = NULL;
    8446 ECB             :     }
    8447 CBC      223111 : }
    8448 ECB             : 
    8449                 : /*
    8450                 :  * plpgsql_subxact_cb --- post-subtransaction-commit-or-abort cleanup
    8451                 :  *
    8452                 :  * Make sure any simple-expression econtexts created in the current
    8453                 :  * subtransaction get cleaned up.  We have to do this explicitly because
    8454                 :  * no other code knows which econtexts belong to which level of subxact.
    8455                 :  */
    8456                 : void
    8457 GIC       16572 : plpgsql_subxact_cb(SubXactEvent event, SubTransactionId mySubid,
    8458                 :                    SubTransactionId parentSubid, void *arg)
    8459                 : {
    8460 CBC       16572 :     if (event == SUBXACT_EVENT_COMMIT_SUB || event == SUBXACT_EVENT_ABORT_SUB)
    8461                 :     {
    8462 GIC       13030 :         while (simple_econtext_stack != NULL &&
    8463 CBC       12388 :                simple_econtext_stack->xact_subxid == mySubid)
    8464                 :         {
    8465 ECB             :             SimpleEcontextStackEntry *next;
    8466                 : 
    8467 GIC        6271 :             FreeExprContext(simple_econtext_stack->stack_econtext,
    8468                 :                             (event == SUBXACT_EVENT_COMMIT_SUB));
    8469            6271 :             next = simple_econtext_stack->next;
    8470 CBC        6271 :             pfree(simple_econtext_stack);
    8471 GIC        6271 :             simple_econtext_stack = next;
    8472 ECB             :         }
    8473                 :     }
    8474 CBC       16572 : }
    8475                 : 
    8476                 : /*
    8477 ECB             :  * assign_simple_var --- assign a new value to any VAR datum.
    8478                 :  *
    8479                 :  * This should be the only mechanism for assignment to simple variables,
    8480                 :  * lest we do the release of the old value incorrectly (not to mention
    8481                 :  * the detoasting business).
    8482                 :  */
    8483                 : static void
    8484 GIC      212963 : assign_simple_var(PLpgSQL_execstate *estate, PLpgSQL_var *var,
    8485                 :                   Datum newvalue, bool isnull, bool freeable)
    8486                 : {
    8487 CBC      212963 :     Assert(var->dtype == PLPGSQL_DTYPE_VAR ||
    8488                 :            var->dtype == PLPGSQL_DTYPE_PROMISE);
    8489                 : 
    8490 ECB             :     /*
    8491                 :      * In non-atomic contexts, we do not want to store TOAST pointers in
    8492                 :      * variables, because such pointers might become stale after a commit.
    8493                 :      * Forcibly detoast in such cases.  We don't want to detoast (flatten)
    8494                 :      * expanded objects, however; those should be OK across a transaction
    8495                 :      * boundary since they're just memory-resident objects.  (Elsewhere in
    8496                 :      * this module, operations on expanded records likewise need to request
    8497                 :      * detoasting of record fields when !estate->atomic.  Expanded arrays are
    8498                 :      * not a problem since all array entries are always detoasted.)
    8499                 :      */
    8500 GIC      212963 :     if (!estate->atomic && !isnull && var->datatype->typlen == -1 &&
    8501           21759 :         VARATT_IS_EXTERNAL_NON_EXPANDED(DatumGetPointer(newvalue)))
    8502                 :     {
    8503 ECB             :         MemoryContext oldcxt;
    8504                 :         Datum       detoasted;
    8505                 : 
    8506                 :         /*
    8507                 :          * Do the detoasting in the eval_mcontext to avoid long-term leakage
    8508                 :          * of whatever memory toast fetching might leak.  Then we have to copy
    8509                 :          * the detoasted datum to the function's main context, which is a
    8510                 :          * pain, but there's little choice.
    8511                 :          */
    8512 GIC           8 :         oldcxt = MemoryContextSwitchTo(get_eval_mcontext(estate));
    8513               8 :         detoasted = PointerGetDatum(detoast_external_attr((struct varlena *) DatumGetPointer(newvalue)));
    8514               8 :         MemoryContextSwitchTo(oldcxt);
    8515 ECB             :         /* Now's a good time to not leak the input value if it's freeable */
    8516 CBC           8 :         if (freeable)
    8517               8 :             pfree(DatumGetPointer(newvalue));
    8518                 :         /* Once we copy the value, it's definitely freeable */
    8519               8 :         newvalue = datumCopy(detoasted, false, -1);
    8520               8 :         freeable = true;
    8521                 :         /* Can't clean up eval_mcontext here, but it'll happen before long */
    8522 ECB             :     }
    8523                 : 
    8524                 :     /* Free the old value if needed */
    8525 GIC      212963 :     if (var->freeval)
    8526                 :     {
    8527           36614 :         if (DatumIsReadWriteExpandedObject(var->value,
    8528 ECB             :                                            var->isnull,
    8529                 :                                            var->datatype->typlen))
    8530 CBC        3479 :             DeleteExpandedObject(var->value);
    8531                 :         else
    8532 GIC       33135 :             pfree(DatumGetPointer(var->value));
    8533 ECB             :     }
    8534                 :     /* Assign new value to datum */
    8535 CBC      212963 :     var->value = newvalue;
    8536 GIC      212963 :     var->isnull = isnull;
    8537          212963 :     var->freeval = freeable;
    8538 ECB             : 
    8539                 :     /*
    8540                 :      * If it's a promise variable, then either we just assigned the promised
    8541                 :      * value, or the user explicitly assigned an overriding value.  Either
    8542                 :      * way, cancel the promise.
    8543                 :      */
    8544 GIC      212963 :     var->promise = PLPGSQL_PROMISE_NONE;
    8545          212963 : }
    8546                 : 
    8547 ECB             : /*
    8548                 :  * free old value of a text variable and assign new value from C string
    8549                 :  */
    8550                 : static void
    8551 GIC       11336 : assign_text_var(PLpgSQL_execstate *estate, PLpgSQL_var *var, const char *str)
    8552                 : {
    8553           11336 :     assign_simple_var(estate, var, CStringGetTextDatum(str), false, true);
    8554 CBC       11336 : }
    8555                 : 
    8556 ECB             : /*
    8557                 :  * assign_record_var --- assign a new value to any REC datum.
    8558                 :  */
    8559                 : static void
    8560 GIC        3053 : assign_record_var(PLpgSQL_execstate *estate, PLpgSQL_rec *rec,
    8561                 :                   ExpandedRecordHeader *erh)
    8562                 : {
    8563 CBC        3053 :     Assert(rec->dtype == PLPGSQL_DTYPE_REC);
    8564                 : 
    8565                 :     /* Transfer new record object into datum_context */
    8566            3053 :     TransferExpandedRecord(erh, estate->datum_context);
    8567                 : 
    8568                 :     /* Free the old value ... */
    8569            3053 :     if (rec->erh)
    8570 GIC         887 :         DeleteExpandedObject(ExpandedRecordGetDatum(rec->erh));
    8571                 : 
    8572 ECB             :     /* ... and install the new */
    8573 CBC        3053 :     rec->erh = erh;
    8574 GIC        3053 : }
    8575                 : 
    8576 ECB             : /*
    8577                 :  * exec_eval_using_params --- evaluate params of USING clause
    8578                 :  *
    8579                 :  * The result data structure is created in the stmt_mcontext, and should
    8580                 :  * be freed by resetting that context.
    8581                 :  */
    8582                 : static ParamListInfo
    8583 GIC        9934 : exec_eval_using_params(PLpgSQL_execstate *estate, List *params)
    8584                 : {
    8585                 :     ParamListInfo paramLI;
    8586 ECB             :     int         nargs;
    8587                 :     MemoryContext stmt_mcontext;
    8588                 :     MemoryContext oldcontext;
    8589                 :     int         i;
    8590                 :     ListCell   *lc;
    8591                 : 
    8592                 :     /* Fast path for no parameters: we can just return NULL */
    8593 GIC        9934 :     if (params == NIL)
    8594            9643 :         return NULL;
    8595                 : 
    8596 CBC         291 :     nargs = list_length(params);
    8597             291 :     stmt_mcontext = get_stmt_mcontext(estate);
    8598 GIC         291 :     oldcontext = MemoryContextSwitchTo(stmt_mcontext);
    8599 CBC         291 :     paramLI = makeParamList(nargs);
    8600             291 :     MemoryContextSwitchTo(oldcontext);
    8601 ECB             : 
    8602 CBC         291 :     i = 0;
    8603             864 :     foreach(lc, params)
    8604                 :     {
    8605             573 :         PLpgSQL_expr *param = (PLpgSQL_expr *) lfirst(lc);
    8606             573 :         ParamExternData *prm = &paramLI->params[i];
    8607                 :         int32       ppdtypmod;
    8608 ECB             : 
    8609                 :         /*
    8610                 :          * Always mark params as const, since we only use the result with
    8611                 :          * one-shot plans.
    8612                 :          */
    8613 GIC         573 :         prm->pflags = PARAM_FLAG_CONST;
    8614                 : 
    8615             573 :         prm->value = exec_eval_expr(estate, param,
    8616 ECB             :                                     &prm->isnull,
    8617                 :                                     &prm->ptype,
    8618                 :                                     &ppdtypmod);
    8619                 : 
    8620 GIC         573 :         oldcontext = MemoryContextSwitchTo(stmt_mcontext);
    8621                 : 
    8622             573 :         if (prm->ptype == UNKNOWNOID)
    8623 ECB             :         {
    8624                 :             /*
    8625                 :              * Treat 'unknown' parameters as text, since that's what most
    8626                 :              * people would expect.  The SPI functions can coerce unknown
    8627                 :              * constants in a more intelligent way, but not unknown Params.
    8628                 :              * This code also takes care of copying into the right context.
    8629                 :              * Note we assume 'unknown' has the representation of C-string.
    8630                 :              */
    8631 UIC           0 :             prm->ptype = TEXTOID;
    8632               0 :             if (!prm->isnull)
    8633               0 :                 prm->value = CStringGetTextDatum(DatumGetCString(prm->value));
    8634 EUB             :         }
    8635                 :         /* pass-by-ref non null values must be copied into stmt_mcontext */
    8636 GBC         573 :         else if (!prm->isnull)
    8637                 :         {
    8638                 :             int16       typLen;
    8639 ECB             :             bool        typByVal;
    8640                 : 
    8641 GIC         573 :             get_typlenbyval(prm->ptype, &typLen, &typByVal);
    8642             573 :             if (!typByVal)
    8643             552 :                 prm->value = datumCopy(prm->value, typByVal, typLen);
    8644 ECB             :         }
    8645                 : 
    8646 CBC         573 :         MemoryContextSwitchTo(oldcontext);
    8647                 : 
    8648 GIC         573 :         exec_eval_cleanup(estate);
    8649 ECB             : 
    8650 GIC         573 :         i++;
    8651 ECB             :     }
    8652                 : 
    8653 CBC         291 :     return paramLI;
    8654                 : }
    8655                 : 
    8656 ECB             : /*
    8657                 :  * Open portal for dynamic query
    8658                 :  *
    8659                 :  * Caution: this resets the stmt_mcontext at exit.  We might eventually need
    8660                 :  * to move that responsibility to the callers, but currently no caller needs
    8661                 :  * to have statement-lifetime temp data that survives past this, so it's
    8662                 :  * simpler to do it here.
    8663                 :  */
    8664                 : static Portal
    8665 GIC        4579 : exec_dynquery_with_params(PLpgSQL_execstate *estate,
    8666                 :                           PLpgSQL_expr *dynquery,
    8667                 :                           List *params,
    8668 ECB             :                           const char *portalname,
    8669                 :                           int cursorOptions)
    8670                 : {
    8671                 :     Portal      portal;
    8672                 :     Datum       query;
    8673                 :     bool        isnull;
    8674                 :     Oid         restype;
    8675                 :     int32       restypmod;
    8676                 :     char       *querystr;
    8677                 :     SPIParseOpenOptions options;
    8678 GIC        4579 :     MemoryContext stmt_mcontext = get_stmt_mcontext(estate);
    8679                 : 
    8680                 :     /*
    8681 ECB             :      * Evaluate the string expression after the EXECUTE keyword. Its result is
    8682                 :      * the querystring we have to execute.
    8683                 :      */
    8684 GIC        4579 :     query = exec_eval_expr(estate, dynquery, &isnull, &restype, &restypmod);
    8685            4579 :     if (isnull)
    8686 UIC           0 :         ereport(ERROR,
    8687 ECB             :                 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
    8688                 :                  errmsg("query string argument of EXECUTE is null")));
    8689 EUB             : 
    8690                 :     /* Get the C-String representation */
    8691 GIC        4579 :     querystr = convert_value_to_string(estate, query, restype);
    8692                 : 
    8693                 :     /* copy it into the stmt_mcontext before we clean up */
    8694 CBC        4579 :     querystr = MemoryContextStrdup(stmt_mcontext, querystr);
    8695                 : 
    8696 GIC        4579 :     exec_eval_cleanup(estate);
    8697 ECB             : 
    8698                 :     /*
    8699                 :      * Open an implicit cursor for the query.  We use SPI_cursor_parse_open
    8700                 :      * even when there are no params, because this avoids making and freeing
    8701                 :      * one copy of the plan.
    8702                 :      */
    8703 GIC        4579 :     memset(&options, 0, sizeof(options));
    8704            4579 :     options.params = exec_eval_using_params(estate, params);
    8705            4579 :     options.cursorOptions = cursorOptions;
    8706 CBC        4579 :     options.read_only = estate->readonly_func;
    8707 ECB             : 
    8708 CBC        4579 :     portal = SPI_cursor_parse_open(portalname, querystr, &options);
    8709 ECB             : 
    8710 GIC        4579 :     if (portal == NULL)
    8711 LBC           0 :         elog(ERROR, "could not open implicit cursor for query \"%s\": %s",
    8712                 :              querystr, SPI_result_code_string(SPI_result));
    8713 ECB             : 
    8714 EUB             :     /* Release transient data */
    8715 GIC        4579 :     MemoryContextReset(stmt_mcontext);
    8716                 : 
    8717            4579 :     return portal;
    8718 ECB             : }
    8719                 : 
    8720                 : /*
    8721                 :  * Return a formatted string with information about an expression's parameters,
    8722                 :  * or NULL if the expression does not take any parameters.
    8723                 :  * The result is in the eval_mcontext.
    8724                 :  */
    8725                 : static char *
    8726 GIC          15 : format_expr_params(PLpgSQL_execstate *estate,
    8727                 :                    const PLpgSQL_expr *expr)
    8728                 : {
    8729 ECB             :     int         paramno;
    8730                 :     int         dno;
    8731                 :     StringInfoData paramstr;
    8732                 :     MemoryContext oldcontext;
    8733                 : 
    8734 GIC          15 :     if (!expr->paramnos)
    8735               3 :         return NULL;
    8736                 : 
    8737 CBC          12 :     oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
    8738 ECB             : 
    8739 GIC          12 :     initStringInfo(&paramstr);
    8740 CBC          12 :     paramno = 0;
    8741 GIC          12 :     dno = -1;
    8742 CBC          36 :     while ((dno = bms_next_member(expr->paramnos, dno)) >= 0)
    8743 ECB             :     {
    8744                 :         Datum       paramdatum;
    8745                 :         Oid         paramtypeid;
    8746                 :         bool        paramisnull;
    8747                 :         int32       paramtypmod;
    8748                 :         PLpgSQL_var *curvar;
    8749                 : 
    8750 GIC          24 :         curvar = (PLpgSQL_var *) estate->datums[dno];
    8751                 : 
    8752              24 :         exec_eval_datum(estate, (PLpgSQL_datum *) curvar,
    8753 ECB             :                         &paramtypeid, &paramtypmod,
    8754                 :                         &paramdatum, &paramisnull);
    8755                 : 
    8756 GIC          24 :         appendStringInfo(&paramstr, "%s%s = ",
    8757                 :                          paramno > 0 ? ", " : "",
    8758                 :                          curvar->refname);
    8759 ECB             : 
    8760 GIC          24 :         if (paramisnull)
    8761 UIC           0 :             appendStringInfoString(&paramstr, "NULL");
    8762                 :         else
    8763 CBC          24 :             appendStringInfoStringQuoted(&paramstr,
    8764 GBC          24 :                                          convert_value_to_string(estate,
    8765                 :                                                                  paramdatum,
    8766 ECB             :                                                                  paramtypeid),
    8767                 :                                          -1);
    8768                 : 
    8769 GIC          24 :         paramno++;
    8770                 :     }
    8771                 : 
    8772 CBC          12 :     MemoryContextSwitchTo(oldcontext);
    8773                 : 
    8774 GIC          12 :     return paramstr.data;
    8775 ECB             : }
    8776                 : 
    8777                 : /*
    8778                 :  * Return a formatted string with information about the parameter values,
    8779                 :  * or NULL if there are no parameters.
    8780                 :  * The result is in the eval_mcontext.
    8781                 :  */
    8782                 : static char *
    8783 GIC           9 : format_preparedparamsdata(PLpgSQL_execstate *estate,
    8784                 :                           ParamListInfo paramLI)
    8785                 : {
    8786 ECB             :     int         paramno;
    8787                 :     StringInfoData paramstr;
    8788                 :     MemoryContext oldcontext;
    8789                 : 
    8790 GIC           9 :     if (!paramLI)
    8791               3 :         return NULL;
    8792                 : 
    8793 CBC           6 :     oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
    8794 ECB             : 
    8795 GIC           6 :     initStringInfo(&paramstr);
    8796 CBC          15 :     for (paramno = 0; paramno < paramLI->numParams; paramno++)
    8797                 :     {
    8798               9 :         ParamExternData *prm = &paramLI->params[paramno];
    8799 ECB             : 
    8800                 :         /*
    8801                 :          * Note: for now, this is only used on ParamListInfos produced by
    8802                 :          * exec_eval_using_params(), so we don't worry about invoking the
    8803                 :          * paramFetch hook or skipping unused parameters.
    8804                 :          */
    8805 GIC           9 :         appendStringInfo(&paramstr, "%s$%d = ",
    8806                 :                          paramno > 0 ? ", " : "",
    8807                 :                          paramno + 1);
    8808 ECB             : 
    8809 GIC           9 :         if (prm->isnull)
    8810 UIC           0 :             appendStringInfoString(&paramstr, "NULL");
    8811                 :         else
    8812 CBC           9 :             appendStringInfoStringQuoted(&paramstr,
    8813 GBC           9 :                                          convert_value_to_string(estate,
    8814                 :                                                                  prm->value,
    8815 ECB             :                                                                  prm->ptype),
    8816                 :                                          -1);
    8817                 :     }
    8818                 : 
    8819 GIC           6 :     MemoryContextSwitchTo(oldcontext);
    8820                 : 
    8821               6 :     return paramstr.data;
    8822 ECB             : }
        

Generated by: LCOV version v1.16-55-g56c0a2a