LCOV - differential code coverage report
Current view: top level - src/backend/executor - execUtils.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 89.9 % 415 373 19 6 22 11 1 191 52 129 26 192 2 32
Current Date: 2023-04-08 17:13:01 Functions: 93.0 % 43 40 3 36 4 3 37 3
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 [..60] days: 100.0 % 6 6 6
Legend: Lines: hit not hit (60,120] days: 100.0 % 2 2 2
(120,180] days: 90.2 % 51 46 3 1 1 44 2 1
(240..) days: 89.6 % 356 319 5 21 11 1 191 127 26 191
Function coverage date bins:
[..60] days: 100.0 % 1 1 1
(120,180] days: 100.0 % 3 3 3
(240..) days: 46.8 % 77 36 3 36 3 35

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * execUtils.c
                                  4                 :  *    miscellaneous executor utility routines
                                  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/backend/executor/execUtils.c
                                 12                 :  *
                                 13                 :  *-------------------------------------------------------------------------
                                 14                 :  */
                                 15                 : /*
                                 16                 :  * INTERFACE ROUTINES
                                 17                 :  *      CreateExecutorState     Create/delete executor working state
                                 18                 :  *      FreeExecutorState
                                 19                 :  *      CreateExprContext
                                 20                 :  *      CreateStandaloneExprContext
                                 21                 :  *      FreeExprContext
                                 22                 :  *      ReScanExprContext
                                 23                 :  *
                                 24                 :  *      ExecAssignExprContext   Common code for plan node init routines.
                                 25                 :  *      etc
                                 26                 :  *
                                 27                 :  *      ExecOpenScanRelation    Common code for scan node init routines.
                                 28                 :  *
                                 29                 :  *      ExecInitRangeTable      Set up executor's range-table-related data.
                                 30                 :  *
                                 31                 :  *      ExecGetRangeTableRelation       Fetch Relation for a rangetable entry.
                                 32                 :  *
                                 33                 :  *      executor_errposition    Report syntactic position of an error.
                                 34                 :  *
                                 35                 :  *      RegisterExprContextCallback    Register function shutdown callback
                                 36                 :  *      UnregisterExprContextCallback  Deregister function shutdown callback
                                 37                 :  *
                                 38                 :  *      GetAttributeByName      Runtime extraction of columns from tuples.
                                 39                 :  *      GetAttributeByNum
                                 40                 :  *
                                 41                 :  *   NOTES
                                 42                 :  *      This file has traditionally been the place to stick misc.
                                 43                 :  *      executor support stuff that doesn't really go anyplace else.
                                 44                 :  */
                                 45                 : 
                                 46                 : #include "postgres.h"
                                 47                 : 
                                 48                 : #include "access/parallel.h"
                                 49                 : #include "access/relscan.h"
                                 50                 : #include "access/table.h"
                                 51                 : #include "access/tableam.h"
                                 52                 : #include "access/transam.h"
                                 53                 : #include "executor/executor.h"
                                 54                 : #include "executor/execPartition.h"
                                 55                 : #include "executor/nodeModifyTable.h"
                                 56                 : #include "jit/jit.h"
                                 57                 : #include "mb/pg_wchar.h"
                                 58                 : #include "miscadmin.h"
                                 59                 : #include "nodes/nodeFuncs.h"
                                 60                 : #include "parser/parsetree.h"
                                 61                 : #include "parser/parse_relation.h"
                                 62                 : #include "partitioning/partdesc.h"
                                 63                 : #include "storage/lmgr.h"
                                 64                 : #include "utils/builtins.h"
                                 65                 : #include "utils/memutils.h"
                                 66                 : #include "utils/rel.h"
                                 67                 : #include "utils/typcache.h"
                                 68                 : 
                                 69                 : 
                                 70                 : static bool tlist_matches_tupdesc(PlanState *ps, List *tlist, int varno, TupleDesc tupdesc);
                                 71                 : static void ShutdownExprContext(ExprContext *econtext, bool isCommit);
                                 72                 : static RTEPermissionInfo *GetResultRTEPermissionInfo(ResultRelInfo *relinfo, EState *estate);
                                 73                 : 
                                 74                 : 
                                 75                 : /* ----------------------------------------------------------------
                                 76                 :  *               Executor state and memory management functions
                                 77                 :  * ----------------------------------------------------------------
                                 78                 :  */
                                 79                 : 
                                 80                 : /* ----------------
                                 81                 :  *      CreateExecutorState
                                 82                 :  *
                                 83                 :  *      Create and initialize an EState node, which is the root of
                                 84                 :  *      working storage for an entire Executor invocation.
                                 85                 :  *
                                 86                 :  * Principally, this creates the per-query memory context that will be
                                 87                 :  * used to hold all working data that lives till the end of the query.
                                 88                 :  * Note that the per-query context will become a child of the caller's
                                 89                 :  * CurrentMemoryContext.
                                 90                 :  * ----------------
                                 91                 :  */
                                 92                 : EState *
 7420 tgl                        93 GIC      609142 : CreateExecutorState(void)
                                 94                 : {
 5885 tgl                        95 ECB             :     EState     *estate;
                                 96                 :     MemoryContext qcontext;
                                 97                 :     MemoryContext oldcontext;
                                 98                 : 
                                 99                 :     /*
                                100                 :      * Create the per-query context for this Executor run.
                                101                 :      */
 7420 tgl                       102 GIC      609142 :     qcontext = AllocSetContextCreate(CurrentMemoryContext,
                                103                 :                                      "ExecutorState",
 2416 tgl                       104 ECB             :                                      ALLOCSET_DEFAULT_SIZES);
                                105                 : 
                                106                 :     /*
                                107                 :      * Make the EState node within the per-query context.  This way, we don't
                                108                 :      * need a separate pfree() operation for it at shutdown.
                                109                 :      */
 7420 tgl                       110 GIC      609142 :     oldcontext = MemoryContextSwitchTo(qcontext);
                                111                 : 
 7420 tgl                       112 CBC      609142 :     estate = makeNode(EState);
                                113                 : 
 7420 tgl                       114 ECB             :     /*
                                115                 :      * Initialize all fields of the Executor State structure
                                116                 :      */
 7420 tgl                       117 GIC      609142 :     estate->es_direction = ForwardScanDirection;
 2118                           118          609142 :     estate->es_snapshot = InvalidSnapshot;   /* caller must initialize this */
 6784 tgl                       119 CBC      609142 :     estate->es_crosscheck_snapshot = InvalidSnapshot;    /* no crosscheck */
 7420                           120          609142 :     estate->es_range_table = NIL;
 1648                           121          609142 :     estate->es_range_table_size = 0;
                                122          609142 :     estate->es_relations = NULL;
 1644                           123          609142 :     estate->es_rowmarks = NULL;
   34 tgl                       124 GNC      609142 :     estate->es_rteperminfos = NIL;
 4913 tgl                       125 CBC      609142 :     estate->es_plannedstmt = NULL;
  129 alvherre                  126 GNC      609142 :     estate->es_part_prune_infos = NIL;
 7420 tgl                       127 ECB             : 
 4927 tgl                       128 CBC      609142 :     estate->es_junkFilter = NULL;
 4927 tgl                       129 ECB             : 
 5609 tgl                       130 CBC      609142 :     estate->es_output_cid = (CommandId) 0;
                                131                 : 
 7420                           132          609142 :     estate->es_result_relations = NULL;
  908 heikki.linnakangas        133 GIC      609142 :     estate->es_opened_result_relations = NIL;
 1886 rhaas                     134 CBC      609142 :     estate->es_tuple_routing_result_relations = NIL;
 5716 tgl                       135 GIC      609142 :     estate->es_trig_target_relations = NIL;
 6355 tgl                       136 ECB             : 
  122 efujita                   137 CBC      609142 :     estate->es_insert_pending_result_relations = NIL;
                                138          609142 :     estate->es_insert_pending_modifytables = NIL;
  122 efujita                   139 ECB             : 
 7420 tgl                       140 CBC      609142 :     estate->es_param_list_info = NULL;
 7420 tgl                       141 GIC      609142 :     estate->es_param_exec_vals = NULL;
 7420 tgl                       142 ECB             : 
 2200 kgrittn                   143 CBC      609142 :     estate->es_queryEnv = NULL;
                                144                 : 
 7420 tgl                       145          609142 :     estate->es_query_cxt = qcontext;
                                146                 : 
 4942                           147          609142 :     estate->es_tupleTable = NIL;
                                148                 : 
 7420                           149          609142 :     estate->es_processed = 0;
    3 michael                   150 GNC      609142 :     estate->es_total_processed = 0;
                                151                 : 
 4424 tgl                       152 CBC      609142 :     estate->es_top_eflags = 0;
                                153          609142 :     estate->es_instrument = 0;
 4424 tgl                       154 GIC      609142 :     estate->es_finished = false;
 7420 tgl                       155 ECB             : 
 7420 tgl                       156 CBC      609142 :     estate->es_exprcontexts = NIL;
 7420 tgl                       157 ECB             : 
 5885 tgl                       158 GIC      609142 :     estate->es_subplanstates = NIL;
 5885 tgl                       159 ECB             : 
 4426 tgl                       160 GIC      609142 :     estate->es_auxmodifytables = NIL;
 4426 tgl                       161 ECB             : 
 7420 tgl                       162 GIC      609142 :     estate->es_per_tuple_exprcontext = NULL;
 7420 tgl                       163 ECB             : 
 2237 rhaas                     164 GIC      609142 :     estate->es_sourceText = NULL;
 7420 tgl                       165 ECB             : 
 1990 rhaas                     166 GIC      609142 :     estate->es_use_parallel_mode = false;
 1990 rhaas                     167 ECB             : 
 1844 andres                    168 GIC      609142 :     estate->es_jit_flags = 0;
 1844 andres                    169 CBC      609142 :     estate->es_jit = NULL;
                                170                 : 
 7420 tgl                       171 ECB             :     /*
                                172                 :      * Return the executor state structure
                                173                 :      */
 7420 tgl                       174 GIC      609142 :     MemoryContextSwitchTo(oldcontext);
                                175                 : 
                                176          609142 :     return estate;
 7420 tgl                       177 ECB             : }
                                178                 : 
                                179                 : /* ----------------
                                180                 :  *      FreeExecutorState
                                181                 :  *
                                182                 :  *      Release an EState along with all remaining working storage.
                                183                 :  *
                                184                 :  * Note: this is not responsible for releasing non-memory resources, such as
                                185                 :  * open relations or buffer pins.  But it will shut down any still-active
                                186                 :  * ExprContexts within the EState and deallocate associated JITed expressions.
                                187                 :  * That is sufficient cleanup for situations where the EState has only been
                                188                 :  * used for expression evaluation, and not to run a complete Plan.
                                189                 :  *
                                190                 :  * This can be called in any memory context ... so long as it's not one
                                191                 :  * of the ones to be freed.
                                192                 :  * ----------------
                                193                 :  */
                                194                 : void
 7420 tgl                       195 GIC      594215 : FreeExecutorState(EState *estate)
                                196                 : {
                                197                 :     /*
 6385 bruce                     198 ECB             :      * Shut down and free any remaining ExprContexts.  We do this explicitly
                                199                 :      * to ensure that any remaining shutdown callbacks get called (since they
                                200                 :      * might need to release resources that aren't simply memory within the
                                201                 :      * per-query memory context).
                                202                 :      */
 7420 tgl                       203 GIC     1484069 :     while (estate->es_exprcontexts)
                                204                 :     {
                                205                 :         /*
 6385 bruce                     206 ECB             :          * XXX: seems there ought to be a faster way to implement this than
                                207                 :          * repeated list_delete(), no?
                                208                 :          */
 5013 tgl                       209 GIC      889854 :         FreeExprContext((ExprContext *) linitial(estate->es_exprcontexts),
                                210                 :                         true);
                                211                 :         /* FreeExprContext removed the list link for us */
 7420 tgl                       212 ECB             :     }
                                213                 : 
                                214                 :     /* release JIT context, if allocated */
 1719 andres                    215 GIC      594215 :     if (estate->es_jit)
                                216                 :     {
                                217             831 :         jit_release_context(estate->es_jit);
 1719 andres                    218 CBC         831 :         estate->es_jit = NULL;
                                219                 :     }
 1719 andres                    220 ECB             : 
 1494 rhaas                     221                 :     /* release partition directory, if allocated */
 1494 rhaas                     222 GIC      594215 :     if (estate->es_partition_directory)
                                223                 :     {
                                224            3103 :         DestroyPartitionDirectory(estate->es_partition_directory);
 1494 rhaas                     225 CBC        3103 :         estate->es_partition_directory = NULL;
                                226                 :     }
 1494 rhaas                     227 ECB             : 
 7420 tgl                       228                 :     /*
                                229                 :      * Free the per-query memory context, thereby releasing all working
                                230                 :      * memory, including the EState node itself.
                                231                 :      */
 5885 tgl                       232 GIC      594215 :     MemoryContextDelete(estate->es_query_cxt);
 9770 scrappy                   233          594215 : }
                                234                 : 
 1097 jdavis                    235 ECB             : /*
                                236                 :  * Internal implementation for CreateExprContext() and CreateWorkExprContext()
                                237                 :  * that allows control over the AllocSet parameters.
                                238                 :  */
                                239                 : static ExprContext *
 1097 jdavis                    240 GIC      952634 : CreateExprContextInternal(EState *estate, Size minContextSize,
                                241                 :                           Size initBlockSize, Size maxBlockSize)
                                242                 : {
 7420 tgl                       243 ECB             :     ExprContext *econtext;
                                244                 :     MemoryContext oldcontext;
                                245                 : 
                                246                 :     /* Create the ExprContext node within the per-query memory context */
 7420 tgl                       247 GIC      952634 :     oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
                                248                 : 
                                249          952634 :     econtext = makeNode(ExprContext);
 7420 tgl                       250 ECB             : 
                                251                 :     /* Initialize fields of ExprContext */
 7420 tgl                       252 CBC      952634 :     econtext->ecxt_scantuple = NULL;
 8306 tgl                       253 GIC      952634 :     econtext->ecxt_innertuple = NULL;
                                254          952634 :     econtext->ecxt_outertuple = NULL;
 7420 tgl                       255 ECB             : 
 7420 tgl                       256 CBC      952634 :     econtext->ecxt_per_query_memory = estate->es_query_cxt;
 8053 bruce                     257 ECB             : 
                                258                 :     /*
 7420 tgl                       259                 :      * Create working memory for expression evaluation in this context.
                                260                 :      */
 8306 tgl                       261 GIC      952634 :     econtext->ecxt_per_tuple_memory =
 7420                           262          952634 :         AllocSetContextCreate(estate->es_query_cxt,
                                263                 :                               "ExprContext",
 1097 jdavis                    264 ECB             :                               minContextSize,
                                265                 :                               initBlockSize,
                                266                 :                               maxBlockSize);
                                267                 : 
 7420 tgl                       268 GIC      952634 :     econtext->ecxt_param_exec_vals = estate->es_param_exec_vals;
                                269          952634 :     econtext->ecxt_param_list_info = estate->es_param_list_info;
                                270                 : 
 8306 tgl                       271 CBC      952634 :     econtext->ecxt_aggvalues = NULL;
                                272          952634 :     econtext->ecxt_aggnulls = NULL;
                                273                 : 
 6962                           274          952634 :     econtext->caseValue_datum = (Datum) 0;
                                275          952634 :     econtext->caseValue_isNull = true;
                                276                 : 
 7420                           277          952634 :     econtext->domainValue_datum = (Datum) 0;
                                278          952634 :     econtext->domainValue_isNull = true;
                                279                 : 
                                280          952634 :     econtext->ecxt_estate = estate;
 7420 tgl                       281 ECB             : 
 7637 tgl                       282 GIC      952634 :     econtext->ecxt_callbacks = NULL;
 8306 tgl                       283 ECB             : 
                                284                 :     /*
 6385 bruce                     285                 :      * Link the ExprContext into the EState to ensure it is shut down when the
                                286                 :      * EState is freed.  Because we use lcons(), shutdowns will occur in
                                287                 :      * reverse order of creation, which may not be essential but can't hurt.
                                288                 :      */
 7420 tgl                       289 GIC      952634 :     estate->es_exprcontexts = lcons(econtext, estate->es_exprcontexts);
                                290                 : 
                                291          952634 :     MemoryContextSwitchTo(oldcontext);
 7420 tgl                       292 ECB             : 
 8306 tgl                       293 GIC      952634 :     return econtext;
 8306 tgl                       294 ECB             : }
                                295                 : 
 1097 jdavis                    296                 : /* ----------------
                                297                 :  *      CreateExprContext
                                298                 :  *
                                299                 :  *      Create a context for expression evaluation within an EState.
                                300                 :  *
                                301                 :  * An executor run may require multiple ExprContexts (we usually make one
                                302                 :  * for each Plan node, and a separate one for per-output-tuple processing
                                303                 :  * such as constraint checking).  Each ExprContext has its own "per-tuple"
                                304                 :  * memory context.
                                305                 :  *
                                306                 :  * Note we make no assumption about the caller's memory context.
                                307                 :  * ----------------
                                308                 :  */
                                309                 : ExprContext *
 1097 jdavis                    310 GIC      948644 : CreateExprContext(EState *estate)
                                311                 : {
                                312          948644 :     return CreateExprContextInternal(estate, ALLOCSET_DEFAULT_SIZES);
 1097 jdavis                    313 ECB             : }
                                314                 : 
                                315                 : 
                                316                 : /* ----------------
                                317                 :  *      CreateWorkExprContext
                                318                 :  *
                                319                 :  * Like CreateExprContext, but specifies the AllocSet sizes to be reasonable
                                320                 :  * in proportion to work_mem. If the maximum block allocation size is too
                                321                 :  * large, it's easy to skip right past work_mem with a single allocation.
                                322                 :  * ----------------
                                323                 :  */
                                324                 : ExprContext *
 1097 jdavis                    325 GIC        3990 : CreateWorkExprContext(EState *estate)
                                326                 : {
 1060 tgl                       327            3990 :     Size        minContextSize = ALLOCSET_DEFAULT_MINSIZE;
 1060 tgl                       328 CBC        3990 :     Size        initBlockSize = ALLOCSET_DEFAULT_INITSIZE;
 1060 tgl                       329 GIC        3990 :     Size        maxBlockSize = ALLOCSET_DEFAULT_MAXSIZE;
 1097 jdavis                    330 ECB             : 
                                331                 :     /* choose the maxBlockSize to be no larger than 1/16 of work_mem */
 1097 jdavis                    332 CBC       24210 :     while (16 * maxBlockSize > work_mem * 1024L)
 1097 jdavis                    333 GIC       20220 :         maxBlockSize >>= 1;
                                334                 : 
 1097 jdavis                    335 CBC        3990 :     if (maxBlockSize < ALLOCSET_DEFAULT_INITSIZE)
                                336              39 :         maxBlockSize = ALLOCSET_DEFAULT_INITSIZE;
                                337                 : 
                                338            3990 :     return CreateExprContextInternal(estate, minContextSize,
 1097 jdavis                    339 ECB             :                                      initBlockSize, maxBlockSize);
                                340                 : }
                                341                 : 
                                342                 : /* ----------------
                                343                 :  *      CreateStandaloneExprContext
                                344                 :  *
                                345                 :  *      Create a context for standalone expression evaluation.
                                346                 :  *
                                347                 :  * An ExprContext made this way can be used for evaluation of expressions
                                348                 :  * that contain no Params, subplans, or Var references (it might work to
                                349                 :  * put tuple references into the scantuple field, but it seems unwise).
                                350                 :  *
                                351                 :  * The ExprContext struct is allocated in the caller's current memory
                                352                 :  * context, which also becomes its "per query" context.
                                353                 :  *
                                354                 :  * It is caller's responsibility to free the ExprContext when done,
                                355                 :  * or at least ensure that any shutdown callbacks have been called
                                356                 :  * (ReScanExprContext() is suitable).  Otherwise, non-memory resources
                                357                 :  * might be leaked.
                                358                 :  * ----------------
                                359                 :  */
                                360                 : ExprContext *
 6092 tgl                       361 GIC        5757 : CreateStandaloneExprContext(void)
                                362                 : {
                                363                 :     ExprContext *econtext;
 6092 tgl                       364 ECB             : 
                                365                 :     /* Create the ExprContext node within the caller's memory context */
 6092 tgl                       366 GIC        5757 :     econtext = makeNode(ExprContext);
                                367                 : 
                                368                 :     /* Initialize fields of ExprContext */
 6092 tgl                       369 CBC        5757 :     econtext->ecxt_scantuple = NULL;
 6092 tgl                       370 GIC        5757 :     econtext->ecxt_innertuple = NULL;
                                371            5757 :     econtext->ecxt_outertuple = NULL;
 6092 tgl                       372 ECB             : 
 6092 tgl                       373 CBC        5757 :     econtext->ecxt_per_query_memory = CurrentMemoryContext;
 6092 tgl                       374 ECB             : 
                                375                 :     /*
                                376                 :      * Create working memory for expression evaluation in this context.
                                377                 :      */
 6092 tgl                       378 GIC        5757 :     econtext->ecxt_per_tuple_memory =
                                379            5757 :         AllocSetContextCreate(CurrentMemoryContext,
                                380                 :                               "ExprContext",
 2416 tgl                       381 ECB             :                               ALLOCSET_DEFAULT_SIZES);
 6092                           382                 : 
 6092 tgl                       383 GIC        5757 :     econtext->ecxt_param_exec_vals = NULL;
                                384            5757 :     econtext->ecxt_param_list_info = NULL;
                                385                 : 
 6092 tgl                       386 CBC        5757 :     econtext->ecxt_aggvalues = NULL;
                                387            5757 :     econtext->ecxt_aggnulls = NULL;
                                388                 : 
                                389            5757 :     econtext->caseValue_datum = (Datum) 0;
                                390            5757 :     econtext->caseValue_isNull = true;
                                391                 : 
                                392            5757 :     econtext->domainValue_datum = (Datum) 0;
                                393            5757 :     econtext->domainValue_isNull = true;
                                394                 : 
                                395            5757 :     econtext->ecxt_estate = NULL;
 6092 tgl                       396 ECB             : 
 6092 tgl                       397 GIC        5757 :     econtext->ecxt_callbacks = NULL;
 6092 tgl                       398 ECB             : 
 6092 tgl                       399 GIC        5757 :     return econtext;
 6092 tgl                       400 ECB             : }
                                401                 : 
 7420                           402                 : /* ----------------
                                403                 :  *      FreeExprContext
                                404                 :  *
                                405                 :  *      Free an expression context, including calling any remaining
                                406                 :  *      shutdown callbacks.
                                407                 :  *
                                408                 :  * Since we free the temporary context used for expression evaluation,
                                409                 :  * any previously computed pass-by-reference expression result will go away!
                                410                 :  *
                                411                 :  * If isCommit is false, we are being called in error cleanup, and should
                                412                 :  * not call callbacks but only release memory.  (It might be better to call
                                413                 :  * the callbacks and pass the isCommit flag to them, but that would require
                                414                 :  * more invasive code changes than currently seems justified.)
                                415                 :  *
                                416                 :  * Note we make no assumption about the caller's memory context.
                                417                 :  * ----------------
                                418                 :  */
                                419                 : void
 5013 tgl                       420 GIC      935636 : FreeExprContext(ExprContext *econtext, bool isCommit)
                                421                 : {
                                422                 :     EState     *estate;
 7420 tgl                       423 ECB             : 
                                424                 :     /* Call any registered callbacks */
 5013 tgl                       425 GIC      935636 :     ShutdownExprContext(econtext, isCommit);
                                426                 :     /* And clean up the memory used */
 8306                           427          935636 :     MemoryContextDelete(econtext->ecxt_per_tuple_memory);
 6092 tgl                       428 ECB             :     /* Unlink self from owning EState, if any */
 7420 tgl                       429 GIC      935636 :     estate = econtext->ecxt_estate;
 6092 tgl                       430 CBC      935636 :     if (estate)
 6092 tgl                       431 GIC      935636 :         estate->es_exprcontexts = list_delete_ptr(estate->es_exprcontexts,
 6092 tgl                       432 ECB             :                                                   econtext);
 7420                           433                 :     /* And delete the ExprContext node */
 8306 tgl                       434 CBC      935636 :     pfree(econtext);
 9770 scrappy                   435 GIC      935636 : }
                                436                 : 
 7052 tgl                       437 ECB             : /*
                                438                 :  * ReScanExprContext
                                439                 :  *
                                440                 :  *      Reset an expression context in preparation for a rescan of its
                                441                 :  *      plan node.  This requires calling any registered shutdown callbacks,
                                442                 :  *      since any partially complete set-returning-functions must be canceled.
                                443                 :  *
                                444                 :  * Note we make no assumption about the caller's memory context.
                                445                 :  */
                                446                 : void
 7052 tgl                       447 GIC     2012784 : ReScanExprContext(ExprContext *econtext)
                                448                 : {
                                449                 :     /* Call any registered callbacks */
 5013 tgl                       450 CBC     2012784 :     ShutdownExprContext(econtext, true);
                                451                 :     /* And clean up the memory used */
 7052 tgl                       452 GIC     2012784 :     MemoryContextReset(econtext->ecxt_per_tuple_memory);
 7052 tgl                       453 CBC     2012784 : }
                                454                 : 
 8112 tgl                       455 ECB             : /*
                                456                 :  * Build a per-output-tuple ExprContext for an EState.
                                457                 :  *
                                458                 :  * This is normally invoked via GetPerTupleExprContext() macro,
                                459                 :  * not directly.
                                460                 :  */
                                461                 : ExprContext *
 8112 tgl                       462 GIC      356389 : MakePerTupleExprContext(EState *estate)
                                463                 : {
                                464          356389 :     if (estate->es_per_tuple_exprcontext == NULL)
 7420 tgl                       465 CBC      356389 :         estate->es_per_tuple_exprcontext = CreateExprContext(estate);
                                466                 : 
 8112                           467          356389 :     return estate->es_per_tuple_exprcontext;
 8112 tgl                       468 ECB             : }
                                469                 : 
 7420                           470                 : 
                                471                 : /* ----------------------------------------------------------------
                                472                 :  *               miscellaneous node-init support functions
                                473                 :  *
                                474                 :  * Note: all of these are expected to be called with CurrentMemoryContext
                                475                 :  * equal to the per-query memory context.
                                476                 :  * ----------------------------------------------------------------
                                477                 :  */
                                478                 : 
                                479                 : /* ----------------
                                480                 :  *      ExecAssignExprContext
                                481                 :  *
                                482                 :  *      This initializes the ps_ExprContext field.  It is only necessary
                                483                 :  *      to do this for nodes which use ExecQual or ExecProject
                                484                 :  *      because those routines require an econtext. Other nodes that
                                485                 :  *      don't have to evaluate expressions don't need to do this.
                                486                 :  * ----------------
                                487                 :  */
                                488                 : void
 7184 bruce                     489 GIC      538683 : ExecAssignExprContext(EState *estate, PlanState *planstate)
                                490                 : {
 7420 tgl                       491          538683 :     planstate->ps_ExprContext = CreateExprContext(estate);
 7420 tgl                       492 CBC      538683 : }
                                493                 : 
 9770 scrappy                   494 ECB             : /* ----------------
 9345 bruce                     495                 :  *      ExecGetResultType
                                496                 :  * ----------------
                                497                 :  */
                                498                 : TupleDesc
 7184 bruce                     499 GIC      641496 : ExecGetResultType(PlanState *planstate)
                                500                 : {
 1612 andres                    501          641496 :     return planstate->ps_ResultTupleDesc;
 9770 scrappy                   502 ECB             : }
                                503                 : 
 1606 andres                    504                 : /*
                                505                 :  * ExecGetResultSlotOps - information about node's type of result slot
                                506                 :  */
                                507                 : const TupleTableSlotOps *
 1606 andres                    508 GIC      240729 : ExecGetResultSlotOps(PlanState *planstate, bool *isfixed)
                                509                 : {
                                510          240729 :     if (planstate->resultopsset && planstate->resultops)
 1606 andres                    511 ECB             :     {
 1606 andres                    512 GIC      240023 :         if (isfixed)
 1606 andres                    513 CBC      218677 :             *isfixed = planstate->resultopsfixed;
 1606 andres                    514 GIC      240023 :         return planstate->resultops;
 1606 andres                    515 ECB             :     }
                                516                 : 
 1606 andres                    517 CBC         706 :     if (isfixed)
                                518                 :     {
 1606 andres                    519 GIC         688 :         if (planstate->resultopsset)
 1606 andres                    520 CBC         688 :             *isfixed = planstate->resultopsfixed;
 1606 andres                    521 UIC           0 :         else if (planstate->ps_ResultTupleSlot)
 1606 andres                    522 LBC           0 :             *isfixed = TTS_FIXED(planstate->ps_ResultTupleSlot);
 1606 andres                    523 ECB             :         else
 1606 andres                    524 UBC           0 :             *isfixed = false;
 1606 andres                    525 EUB             :     }
                                526                 : 
 1606 andres                    527 GBC         706 :     if (!planstate->ps_ResultTupleSlot)
 1606 andres                    528 GIC         706 :         return &TTSOpsVirtual;
                                529                 : 
 1606 andres                    530 LBC           0 :     return planstate->ps_ResultTupleSlot->tts_ops;
 1606 andres                    531 ECB             : }
                                532                 : 
 5120 tgl                       533 EUB             : 
                                534                 : /* ----------------
                                535                 :  *      ExecAssignProjectionInfo
                                536                 :  *
                                537                 :  * forms the projection information from the node's targetlist
                                538                 :  *
                                539                 :  * Notes for inputDesc are same as for ExecBuildProjectionInfo: supply it
                                540                 :  * for a relation-scan node, can pass NULL for upper-level nodes
                                541                 :  * ----------------
                                542                 :  */
                                543                 : void
 5910 tgl                       544 GIC      321760 : ExecAssignProjectionInfo(PlanState *planstate,
                                545                 :                          TupleDesc inputDesc)
                                546                 : {
 7392 tgl                       547 CBC      321725 :     planstate->ps_ProjInfo =
 2217 andres                    548 GIC      321760 :         ExecBuildProjectionInfo(planstate->plan->targetlist,
                                549                 :                                 planstate->ps_ExprContext,
 5910 tgl                       550 ECB             :                                 planstate->ps_ResultTupleSlot,
 2217 andres                    551                 :                                 planstate,
                                552                 :                                 inputDesc);
 9770 scrappy                   553 GIC      321725 : }
                                554                 : 
                                555                 : 
 1961 rhaas                     556 ECB             : /* ----------------
                                557                 :  *      ExecConditionalAssignProjectionInfo
                                558                 :  *
                                559                 :  * as ExecAssignProjectionInfo, but store NULL rather than building projection
                                560                 :  * info if no projection is required
                                561                 :  * ----------------
                                562                 :  */
                                563                 : void
 1961 rhaas                     564 GIC      210337 : ExecConditionalAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc,
                                565                 :                                     int varno)
                                566                 : {
 1961 rhaas                     567 CBC      210337 :     if (tlist_matches_tupdesc(planstate,
 1961 rhaas                     568 GIC      210337 :                               planstate->plan->targetlist,
                                569                 :                               varno,
 1961 rhaas                     570 ECB             :                               inputDesc))
 1606 andres                    571                 :     {
 1961 rhaas                     572 GIC      109463 :         planstate->ps_ProjInfo = NULL;
 1606 andres                    573          109463 :         planstate->resultopsset = planstate->scanopsset;
                                574          109463 :         planstate->resultopsfixed = planstate->scanopsfixed;
 1606 andres                    575 CBC      109463 :         planstate->resultops = planstate->scanops;
 1606 andres                    576 ECB             :     }
 1961 rhaas                     577                 :     else
 1612 andres                    578                 :     {
 1612 andres                    579 GIC      100874 :         if (!planstate->ps_ResultTupleSlot)
                                580                 :         {
 1606                           581          100874 :             ExecInitResultSlot(planstate, &TTSOpsVirtual);
 1606 andres                    582 CBC      100874 :             planstate->resultops = &TTSOpsVirtual;
 1606 andres                    583 GIC      100874 :             planstate->resultopsfixed = true;
 1606 andres                    584 CBC      100874 :             planstate->resultopsset = true;
 1606 andres                    585 ECB             :         }
 1961 rhaas                     586 CBC      100874 :         ExecAssignProjectionInfo(planstate, inputDesc);
 1612 andres                    587 ECB             :     }
 1961 rhaas                     588 GIC      210337 : }
 1961 rhaas                     589 ECB             : 
                                590                 : static bool
  571 tgl                       591 CBC      210337 : tlist_matches_tupdesc(PlanState *ps, List *tlist, int varno, TupleDesc tupdesc)
                                592                 : {
 1961 rhaas                     593 GIC      210337 :     int         numattrs = tupdesc->natts;
 1961 rhaas                     594 ECB             :     int         attrno;
 1961 rhaas                     595 GIC      210337 :     ListCell   *tlist_item = list_head(tlist);
 1961 rhaas                     596 ECB             : 
                                597                 :     /* Check the tlist attributes */
 1961 rhaas                     598 CBC     1445430 :     for (attrno = 1; attrno <= numattrs; attrno++)
                                599                 :     {
 1961 rhaas                     600 GIC     1330048 :         Form_pg_attribute att_tup = TupleDescAttr(tupdesc, attrno - 1);
 1961 rhaas                     601 ECB             :         Var        *var;
                                602                 : 
 1961 rhaas                     603 CBC     1330048 :         if (tlist_item == NULL)
 1961 rhaas                     604 GIC       15106 :             return false;       /* tlist too short */
                                605         1314942 :         var = (Var *) ((TargetEntry *) lfirst(tlist_item))->expr;
 1961 rhaas                     606 CBC     1314942 :         if (!var || !IsA(var, Var))
                                607           29680 :             return false;       /* tlist item not a Var */
 1961 rhaas                     608 ECB             :         /* if these Asserts fail, planner messed up */
 1961 rhaas                     609 CBC     1285262 :         Assert(var->varno == varno);
                                610         1285262 :         Assert(var->varlevelsup == 0);
 1961 rhaas                     611 GIC     1285262 :         if (var->varattno != attrno)
 1961 rhaas                     612 CBC       50025 :             return false;       /* out of order */
                                613         1235237 :         if (att_tup->attisdropped)
 1961 rhaas                     614 LBC           0 :             return false;       /* table contains dropped columns */
 1838 andrew                    615 CBC     1235237 :         if (att_tup->atthasmissing)
                                616             141 :             return false;       /* table contains cols with missing values */
 1961 rhaas                     617 EUB             : 
 1961 rhaas                     618 ECB             :         /*
                                619                 :          * Note: usually the Var's type should match the tupdesc exactly, but
                                620                 :          * in situations involving unions of columns that have different
                                621                 :          * typmods, the Var may have come from above the union and hence have
                                622                 :          * typmod -1.  This is a legitimate situation since the Var still
                                623                 :          * describes the column, just not as exactly as the tupdesc does. We
                                624                 :          * could change the planner to prevent it, but it'd then insert
                                625                 :          * projection steps just to convert from specific typmod to typmod -1,
                                626                 :          * which is pretty silly.
                                627                 :          */
 1961 rhaas                     628 GIC     1235096 :         if (var->vartype != att_tup->atttypid ||
                                629         1235093 :             (var->vartypmod != att_tup->atttypmod &&
                                630               3 :              var->vartypmod != -1))
 1961 rhaas                     631 CBC           3 :             return false;       /* type mismatch */
 1961 rhaas                     632 ECB             : 
 1364 tgl                       633 CBC     1235093 :         tlist_item = lnext(tlist, tlist_item);
 1961 rhaas                     634 ECB             :     }
                                635                 : 
 1961 rhaas                     636 CBC      115382 :     if (tlist_item)
 1961 rhaas                     637 GIC        5919 :         return false;           /* tlist too long */
                                638                 : 
 1961 rhaas                     639 CBC      109463 :     return true;
 1961 rhaas                     640 ECB             : }
                                641                 : 
 8786 bruce                     642                 : /* ----------------
                                643                 :  *      ExecFreeExprContext
                                644                 :  *
                                645                 :  * A plan node's ExprContext should be freed explicitly during executor
                                646                 :  * shutdown because there may be shutdown callbacks to call.  (Other resources
                                647                 :  * made by the above routines, such as projection info, don't need to be freed
                                648                 :  * explicitly because they're just memory in the per-query memory context.)
                                649                 :  *
                                650                 :  * However ... there is no particular need to do it during ExecEndNode,
                                651                 :  * because FreeExecutorState will free any remaining ExprContexts within
                                652                 :  * the EState.  Letting FreeExecutorState do it allows the ExprContexts to
                                653                 :  * be freed in reverse order of creation, rather than order of creation as
                                654                 :  * will happen if we delete them here, which saves O(N^2) work in the list
                                655                 :  * cleanup inside FreeExprContext.
                                656                 :  * ----------------
                                657                 :  */
                                658                 : void
 7184 bruce                     659 GIC      442939 : ExecFreeExprContext(PlanState *planstate)
                                660                 : {
                                661                 :     /*
 6385 bruce                     662 ECB             :      * Per above discussion, don't actually delete the ExprContext. We do
                                663                 :      * unlink it from the plan node, though.
                                664                 :      */
 7430 tgl                       665 GIC      442939 :     planstate->ps_ExprContext = NULL;
 8786 bruce                     666          442939 : }
                                667                 : 
 1878 andres                    668 ECB             : 
 9770 scrappy                   669                 : /* ----------------------------------------------------------------
                                670                 :  *                Scan node support
                                671                 :  * ----------------------------------------------------------------
                                672                 :  */
                                673                 : 
                                674                 : /* ----------------
                                675                 :  *      ExecAssignScanType
                                676                 :  * ----------------
                                677                 :  */
                                678                 : void
 6141 tgl                       679 GIC         327 : ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc)
                                680                 : {
 7430                           681             327 :     TupleTableSlot *slot = scanstate->ss_ScanTupleSlot;
 9345 bruce                     682 ECB             : 
 6141 tgl                       683 GIC         327 :     ExecSetSlotDescriptor(slot, tupDesc);
 9770 scrappy                   684 CBC         327 : }
                                685                 : 
 9770 scrappy                   686 ECB             : /* ----------------
 1392 michael                   687                 :  *      ExecCreateScanSlotFromOuterPlan
                                688                 :  * ----------------
                                689                 :  */
                                690                 : void
 1606 andres                    691 GIC       51125 : ExecCreateScanSlotFromOuterPlan(EState *estate,
                                692                 :                                 ScanState *scanstate,
                                693                 :                                 const TupleTableSlotOps *tts_ops)
 9770 scrappy                   694 ECB             : {
                                695                 :     PlanState  *outerPlan;
                                696                 :     TupleDesc   tupDesc;
                                697                 : 
 7430 tgl                       698 GIC       51125 :     outerPlan = outerPlanState(scanstate);
 7279                           699           51125 :     tupDesc = ExecGetResultType(outerPlan);
                                700                 : 
 1606 andres                    701 CBC       51125 :     ExecInitScanTupleSlot(estate, scanstate, tupDesc, tts_ops);
 9770 scrappy                   702           51125 : }
                                703                 : 
 6336 tgl                       704 ECB             : /* ----------------------------------------------------------------
                                705                 :  *      ExecRelationIsTargetRelation
                                706                 :  *
                                707                 :  *      Detect whether a relation (identified by rangetable index)
                                708                 :  *      is one of the target relations of the query.
                                709                 :  *
                                710                 :  * Note: This is currently no longer used in core.  We keep it around
                                711                 :  * because FDWs may wish to use it to determine if their foreign table
                                712                 :  * is a target relation.
                                713                 :  * ----------------------------------------------------------------
                                714                 :  */
                                715                 : bool
 6336 tgl                       716 UIC           0 : ExecRelationIsTargetRelation(EState *estate, Index scanrelid)
                                717                 : {
  908 heikki.linnakangas        718               0 :     return list_member_int(estate->es_plannedstmt->resultRelations, scanrelid);
 6336 tgl                       719 EUB             : }
                                720                 : 
 6337                           721                 : /* ----------------------------------------------------------------
                                722                 :  *      ExecOpenScanRelation
                                723                 :  *
                                724                 :  *      Open the heap relation to be scanned by a base-level scan plan node.
                                725                 :  *      This should be called during the node's ExecInit routine.
                                726                 :  * ----------------------------------------------------------------
                                727                 :  */
                                728                 : Relation
 3634 tgl                       729 GIC      172025 : ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags)
                                730                 : {
                                731                 :     Relation    rel;
 6337 tgl                       732 ECB             : 
                                733                 :     /* Open the relation. */
 1648 tgl                       734 GIC      172025 :     rel = ExecGetRangeTableRelation(estate, scanrelid);
                                735                 : 
                                736                 :     /*
 3634 tgl                       737 ECB             :      * Complain if we're attempting a scan of an unscannable relation, except
                                738                 :      * when the query won't actually be run.  This is a slightly klugy place
                                739                 :      * to do this, perhaps, but there is no better place.
                                740                 :      */
 3634 tgl                       741 GIC      172025 :     if ((eflags & (EXEC_FLAG_EXPLAIN_ONLY | EXEC_FLAG_WITH_NO_DATA)) == 0 &&
                                742          158722 :         !RelationIsScannable(rel))
                                743               6 :         ereport(ERROR,
 3634 tgl                       744 ECB             :                 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
                                745                 :                  errmsg("materialized view \"%s\" has not been populated",
                                746                 :                         RelationGetRelationName(rel)),
                                747                 :                  errhint("Use the REFRESH MATERIALIZED VIEW command.")));
                                748                 : 
 3634 tgl                       749 GIC      172019 :     return rel;
                                750                 : }
                                751                 : 
 1648 tgl                       752 ECB             : /*
                                753                 :  * ExecInitRangeTable
                                754                 :  *      Set up executor's range-table-related data
                                755                 :  *
                                756                 :  * In addition to the range table proper, initialize arrays that are
                                757                 :  * indexed by rangetable index.
                                758                 :  */
                                759                 : void
   34 tgl                       760 GNC      414272 : ExecInitRangeTable(EState *estate, List *rangeTable, List *permInfos)
                                761                 : {
                                762                 :     /* Remember the range table List as-is */
 1648 tgl                       763 CBC      414272 :     estate->es_range_table = rangeTable;
                                764                 : 
                                765                 :     /* ... and the RTEPermissionInfo List too */
   34 tgl                       766 GNC      414272 :     estate->es_rteperminfos = permInfos;
                                767                 : 
                                768                 :     /* Set size of associated arrays */
 1648 tgl                       769 CBC      414272 :     estate->es_range_table_size = list_length(rangeTable);
                                770                 : 
                                771                 :     /*
 1648 tgl                       772 ECB             :      * Allocate an array to store an open Relation corresponding to each
                                773                 :      * rangetable entry, and initialize entries to NULL.  Relations are opened
                                774                 :      * and stored here as needed.
                                775                 :      */
 1648 tgl                       776 GIC      414272 :     estate->es_relations = (Relation *)
                                777          414272 :         palloc0(estate->es_range_table_size * sizeof(Relation));
                                778                 : 
                                779                 :     /*
                                780                 :      * es_result_relations and es_rowmarks are also parallel to
                                781                 :      * es_range_table, but are allocated only if needed.
 1644 tgl                       782 ECB             :      */
  908 heikki.linnakangas        783 CBC      414272 :     estate->es_result_relations = NULL;
 1644 tgl                       784 GIC      414272 :     estate->es_rowmarks = NULL;
 1648                           785          414272 : }
                                786                 : 
                                787                 : /*
                                788                 :  * ExecGetRangeTableRelation
 1648 tgl                       789 ECB             :  *      Open the Relation for a range table entry, if not already done
 6337                           790                 :  *
 1648                           791                 :  * The Relations will be closed again in ExecEndPlan().
                                792                 :  */
                                793                 : Relation
 1648 tgl                       794 GIC      248256 : ExecGetRangeTableRelation(EState *estate, Index rti)
                                795                 : {
                                796                 :     Relation    rel;
                                797                 : 
                                798          248256 :     Assert(rti > 0 && rti <= estate->es_range_table_size);
                                799                 : 
 1648 tgl                       800 CBC      248256 :     rel = estate->es_relations[rti - 1];
 1648 tgl                       801 GIC      248256 :     if (rel == NULL)
                                802                 :     {
                                803                 :         /* First time through, so open the relation */
 1648 tgl                       804 CBC      226313 :         RangeTblEntry *rte = exec_rt_fetch(rti, estate);
                                805                 : 
                                806          226313 :         Assert(rte->rtekind == RTE_RELATION);
 1648 tgl                       807 ECB             : 
 1646 tgl                       808 GIC      226313 :         if (!IsParallelWorker())
                                809                 :         {
 1646 tgl                       810 ECB             :             /*
                                811                 :              * In a normal query, we should already have the appropriate lock,
                                812                 :              * but verify that through an Assert.  Since there's already an
                                813                 :              * Assert inside table_open that insists on holding some lock, it
                                814                 :              * seems sufficient to check this only when rellockmode is higher
                                815                 :              * than the minimum.
                                816                 :              */
 1539 andres                    817 GIC      224050 :             rel = table_open(rte->relid, NoLock);
 1646 tgl                       818          224050 :             Assert(rte->rellockmode == AccessShareLock ||
                                819                 :                    CheckRelationLockedByMe(rel, rte->rellockmode, false));
                                820                 :         }
                                821                 :         else
                                822                 :         {
 1646 tgl                       823 ECB             :             /*
                                824                 :              * If we are a parallel worker, we need to obtain our own local
                                825                 :              * lock on the relation.  This ensures sane behavior in case the
                                826                 :              * parent process exits before we do.
                                827                 :              */
 1539 andres                    828 GIC        2263 :             rel = table_open(rte->relid, rte->rellockmode);
                                829                 :         }
                                830                 : 
 1646 tgl                       831          226313 :         estate->es_relations[rti - 1] = rel;
                                832                 :     }
                                833                 : 
 1648 tgl                       834 CBC      248256 :     return rel;
                                835                 : }
                                836                 : 
  908 heikki.linnakangas        837 ECB             : /*
                                838                 :  * ExecInitResultRelation
                                839                 :  *      Open relation given by the passed-in RT index and fill its
                                840                 :  *      ResultRelInfo node
                                841                 :  *
                                842                 :  * Here, we also save the ResultRelInfo in estate->es_result_relations array
                                843                 :  * such that it can be accessed later using the RT index.
                                844                 :  */
                                845                 : void
  908 heikki.linnakangas        846 GIC       71295 : ExecInitResultRelation(EState *estate, ResultRelInfo *resultRelInfo,
                                847                 :                        Index rti)
                                848                 : {
                                849                 :     Relation    resultRelationDesc;
                                850                 : 
                                851           71295 :     resultRelationDesc = ExecGetRangeTableRelation(estate, rti);
  908 heikki.linnakangas        852 CBC       71295 :     InitResultRelInfo(resultRelInfo,
                                853                 :                       resultRelationDesc,
                                854                 :                       rti,
                                855                 :                       NULL,
                                856                 :                       estate->es_instrument);
  908 heikki.linnakangas        857 ECB             : 
  908 heikki.linnakangas        858 CBC       71295 :     if (estate->es_result_relations == NULL)
  908 heikki.linnakangas        859 GIC       66553 :         estate->es_result_relations = (ResultRelInfo **)
                                860           66553 :             palloc0(estate->es_range_table_size * sizeof(ResultRelInfo *));
                                861           71295 :     estate->es_result_relations[rti - 1] = resultRelInfo;
                                862                 : 
                                863                 :     /*
  908 heikki.linnakangas        864 ECB             :      * Saving in the list allows to avoid needlessly traversing the whole
                                865                 :      * array when only a few of its entries are possibly non-NULL.
                                866                 :      */
  908 heikki.linnakangas        867 CBC       71295 :     estate->es_opened_result_relations =
  908 heikki.linnakangas        868 GIC       71295 :         lappend(estate->es_opened_result_relations, resultRelInfo);
                                869           71295 : }
                                870                 : 
                                871                 : /*
                                872                 :  * UpdateChangedParamSet
 7364 tgl                       873 ECB             :  *      Add changed parameters to a plan node's chgParam set
                                874                 :  */
 9173 bruce                     875                 : void
 7184 bruce                     876 GIC      474470 : UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
                                877                 : {
                                878                 :     Bitmapset  *parmset;
                                879                 : 
                                880                 :     /*
                                881                 :      * The plan node only depends on params listed in its allParam set. Don't
 6385 bruce                     882 ECB             :      * include anything else into its chgParam set.
                                883                 :      */
 7364 tgl                       884 GIC      474470 :     parmset = bms_intersect(node->plan->allParam, newchg);
   38 tgl                       885 GNC      474470 :     node->chgParam = bms_join(node->chgParam, parmset);
 9186 vadim4o                   886 GIC      474470 : }
                                887                 : 
                                888                 : /*
                                889                 :  * executor_errposition
                                890                 :  *      Report an execution-time cursor position, if possible.
                                891                 :  *
                                892                 :  * This is expected to be used within an ereport() call.  The return value
                                893                 :  * is a dummy (always 0, in fact).
                                894                 :  *
                                895                 :  * The locations stored in parsetrees are byte offsets into the source string.
                                896                 :  * We have to convert them to 1-based character indexes for reporting to
                                897                 :  * clients.  (We do things this way to avoid unnecessary overhead in the
                                898                 :  * normal non-error case: computing character indexes would be much more
                                899                 :  * expensive than storing token offsets.)
 2182 tgl                       900 EUB             :  */
                                901                 : int
 2182 tgl                       902 UIC           0 : executor_errposition(EState *estate, int location)
                                903                 : {
                                904                 :     int         pos;
 2182 tgl                       905 EUB             : 
                                906                 :     /* No-op if location was not provided */
 2182 tgl                       907 UIC           0 :     if (location < 0)
 1110 tgl                       908 UBC           0 :         return 0;
 2182 tgl                       909 EUB             :     /* Can't do anything if source text is not available */
 2182 tgl                       910 UIC           0 :     if (estate == NULL || estate->es_sourceText == NULL)
 1110 tgl                       911 UBC           0 :         return 0;
                                912                 :     /* Convert offset to character number */
 2182                           913               0 :     pos = pg_mbstrlen_with_len(estate->es_sourceText, location) + 1;
                                914                 :     /* And pass it to the ereport mechanism */
 1110 tgl                       915 UIC           0 :     return errposition(pos);
                                916                 : }
                                917                 : 
                                918                 : /*
                                919                 :  * Register a shutdown callback in an ExprContext.
                                920                 :  *
                                921                 :  * Shutdown callbacks will be called (in reverse order of registration)
                                922                 :  * when the ExprContext is deleted or rescanned.  This provides a hook
                                923                 :  * for functions called in the context to do any cleanup needed --- it's
                                924                 :  * particularly useful for functions returning sets.  Note that the
                                925                 :  * callback will *not* be called in the event that execution is aborted
                                926                 :  * by an error.
 7637 tgl                       927 ECB             :  */
                                928                 : void
 7637 tgl                       929 GIC      123404 : RegisterExprContextCallback(ExprContext *econtext,
                                930                 :                             ExprContextCallbackFunction function,
                                931                 :                             Datum arg)
                                932                 : {
                                933                 :     ExprContext_CB *ecxt_callback;
                                934                 : 
 7637 tgl                       935 ECB             :     /* Save the info in appropriate memory context */
                                936                 :     ecxt_callback = (ExprContext_CB *)
 7637 tgl                       937 GIC      123404 :         MemoryContextAlloc(econtext->ecxt_per_query_memory,
 7637 tgl                       938 ECB             :                            sizeof(ExprContext_CB));
                                939                 : 
 7637 tgl                       940 GIC      123404 :     ecxt_callback->function = function;
                                941          123404 :     ecxt_callback->arg = arg;
 7637 tgl                       942 ECB             : 
                                943                 :     /* link to front of list for appropriate execution order */
 7637 tgl                       944 CBC      123404 :     ecxt_callback->next = econtext->ecxt_callbacks;
 7637 tgl                       945 GIC      123404 :     econtext->ecxt_callbacks = ecxt_callback;
                                946          123404 : }
                                947                 : 
                                948                 : /*
                                949                 :  * Deregister a shutdown callback in an ExprContext.
                                950                 :  *
                                951                 :  * Any list entries matching the function and arg will be removed.
                                952                 :  * This can be used if it's no longer necessary to call the callback.
 7637 tgl                       953 ECB             :  */
                                954                 : void
 7637 tgl                       955 GIC       81046 : UnregisterExprContextCallback(ExprContext *econtext,
                                956                 :                               ExprContextCallbackFunction function,
                                957                 :                               Datum arg)
                                958                 : {
                                959                 :     ExprContext_CB **prev_callback;
 7522 bruce                     960 ECB             :     ExprContext_CB *ecxt_callback;
                                961                 : 
 7637 tgl                       962 CBC       81046 :     prev_callback = &econtext->ecxt_callbacks;
                                963                 : 
                                964          244146 :     while ((ecxt_callback = *prev_callback) != NULL)
                                965                 :     {
                                966          163100 :         if (ecxt_callback->function == function && ecxt_callback->arg == arg)
 7637 tgl                       967 ECB             :         {
 7637 tgl                       968 GIC       81046 :             *prev_callback = ecxt_callback->next;
                                969           81046 :             pfree(ecxt_callback);
 7637 tgl                       970 ECB             :         }
                                971                 :         else
 7637 tgl                       972 CBC       82054 :             prev_callback = &ecxt_callback->next;
                                973                 :     }
 7637 tgl                       974 GIC       81046 : }
                                975                 : 
                                976                 : /*
                                977                 :  * Call all the shutdown callbacks registered in an ExprContext.
                                978                 :  *
                                979                 :  * The callback list is emptied (important in case this is only a rescan
                                980                 :  * reset, and not deletion of the ExprContext).
                                981                 :  *
                                982                 :  * If isCommit is false, just clean the callback list but don't call 'em.
                                983                 :  * (See comment for FreeExprContext.)
 7637 tgl                       984 ECB             :  */
                                985                 : static void
 5013 tgl                       986 GIC     2948420 : ShutdownExprContext(ExprContext *econtext, bool isCommit)
                                987                 : {
                                988                 :     ExprContext_CB *ecxt_callback;
                                989                 :     MemoryContext oldcontext;
 7420 tgl                       990 ECB             : 
                                991                 :     /* Fast path in normal case where there's nothing to do. */
 7420 tgl                       992 GIC     2948420 :     if (econtext->ecxt_callbacks == NULL)
                                993         2906670 :         return;
                                994                 : 
                                995                 :     /*
                                996                 :      * Call the callbacks in econtext's per-tuple context.  This ensures that
 6385 bruce                     997 ECB             :      * any memory they might leak will get cleaned up.
                                998                 :      */
 7420 tgl                       999 GIC       41750 :     oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
                               1000                 : 
                               1001                 :     /*
 7637 tgl                      1002 ECB             :      * Call each callback function in reverse registration order.
                               1003                 :      */
 7637 tgl                      1004 CBC       83702 :     while ((ecxt_callback = econtext->ecxt_callbacks) != NULL)
 7637 tgl                      1005 ECB             :     {
 7637 tgl                      1006 CBC       41952 :         econtext->ecxt_callbacks = ecxt_callback->next;
 5013                          1007           41952 :         if (isCommit)
 2040 peter_e                  1008 GIC       41952 :             ecxt_callback->function(ecxt_callback->arg);
 7637 tgl                      1009           41952 :         pfree(ecxt_callback);
 7637 tgl                      1010 ECB             :     }
                               1011                 : 
 7420 tgl                      1012 GIC       41750 :     MemoryContextSwitchTo(oldcontext);
                               1013                 : }
                               1014                 : 
                               1015                 : /*
                               1016                 :  *      GetAttributeByName
                               1017                 :  *      GetAttributeByNum
                               1018                 :  *
                               1019                 :  *      These functions return the value of the requested attribute
                               1020                 :  *      out of the given tuple Datum.
                               1021                 :  *      C functions which take a tuple as an argument are expected
                               1022                 :  *      to use these.  Ex: overpaid(EMP) might call GetAttributeByNum().
                               1023                 :  *      Note: these are actually rather slow because they do a typcache
                               1024                 :  *      lookup on each call.
 2217 andres                   1025 ECB             :  */
                               1026                 : Datum
 2217 andres                   1027 GIC          18 : GetAttributeByName(HeapTupleHeader tuple, const char *attname, bool *isNull)
                               1028                 : {
                               1029                 :     AttrNumber  attrno;
                               1030                 :     Datum       result;
                               1031                 :     Oid         tupType;
                               1032                 :     int32       tupTypmod;
                               1033                 :     TupleDesc   tupDesc;
                               1034                 :     HeapTupleData tmptup;
 2217 andres                   1035 ECB             :     int         i;
 2217 andres                   1036 EUB             : 
 2217 andres                   1037 GIC          18 :     if (attname == NULL)
 2217 andres                   1038 LBC           0 :         elog(ERROR, "invalid attribute name");
 2217 andres                   1039 EUB             : 
 2217 andres                   1040 GIC          18 :     if (isNull == NULL)
 2217 andres                   1041 LBC           0 :         elog(ERROR, "a NULL isNull pointer was passed");
                               1042                 : 
 2217 andres                   1043 GIC          18 :     if (tuple == NULL)
 2217 andres                   1044 EUB             :     {
                               1045                 :         /* Kinda bogus but compatible with old behavior... */
 2217 andres                   1046 UIC           0 :         *isNull = true;
                               1047               0 :         return (Datum) 0;
 2217 andres                   1048 ECB             :     }
                               1049                 : 
 2217 andres                   1050 CBC          18 :     tupType = HeapTupleHeaderGetTypeId(tuple);
 2217 andres                   1051 GIC          18 :     tupTypmod = HeapTupleHeaderGetTypMod(tuple);
 2217 andres                   1052 CBC          18 :     tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
 2217 andres                   1053 ECB             : 
 2217 andres                   1054 GIC          18 :     attrno = InvalidAttrNumber;
 2217 andres                   1055 CBC          72 :     for (i = 0; i < tupDesc->natts; i++)
                               1056                 :     {
 2058                          1057              72 :         Form_pg_attribute att = TupleDescAttr(tupDesc, i);
                               1058                 : 
                               1059              72 :         if (namestrcmp(&(att->attname), attname) == 0)
 2217 andres                   1060 ECB             :         {
 2058 andres                   1061 GIC          18 :             attrno = att->attnum;
 2217                          1062              18 :             break;
                               1063                 :         }
 2217 andres                   1064 ECB             :     }
 2217 andres                   1065 EUB             : 
 2217 andres                   1066 GIC          18 :     if (attrno == InvalidAttrNumber)
 2217 andres                   1067 UIC           0 :         elog(ERROR, "attribute \"%s\" does not exist", attname);
                               1068                 : 
                               1069                 :     /*
                               1070                 :      * heap_getattr needs a HeapTuple not a bare HeapTupleHeader.  We set all
                               1071                 :      * the fields in the struct just in case user tries to inspect system
 2217 andres                   1072 ECB             :      * columns.
                               1073                 :      */
 2217 andres                   1074 CBC          18 :     tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
                               1075              18 :     ItemPointerSetInvalid(&(tmptup.t_self));
 2217 andres                   1076 GIC          18 :     tmptup.t_tableOid = InvalidOid;
 2217 andres                   1077 CBC          18 :     tmptup.t_data = tuple;
                               1078                 : 
 2217 andres                   1079 GIC          18 :     result = heap_getattr(&tmptup,
                               1080                 :                           attrno,
                               1081                 :                           tupDesc,
 2217 andres                   1082 ECB             :                           isNull);
                               1083                 : 
 2217 andres                   1084 CBC          18 :     ReleaseTupleDesc(tupDesc);
                               1085                 : 
 2217 andres                   1086 GIC          18 :     return result;
                               1087                 : }
 2217 andres                   1088 EUB             : 
                               1089                 : Datum
 2217 andres                   1090 UIC           0 : GetAttributeByNum(HeapTupleHeader tuple,
                               1091                 :                   AttrNumber attrno,
                               1092                 :                   bool *isNull)
                               1093                 : {
                               1094                 :     Datum       result;
                               1095                 :     Oid         tupType;
                               1096                 :     int32       tupTypmod;
                               1097                 :     TupleDesc   tupDesc;
 2217 andres                   1098 EUB             :     HeapTupleData tmptup;
                               1099                 : 
 2217 andres                   1100 UIC           0 :     if (!AttributeNumberIsValid(attrno))
 2217 andres                   1101 UBC           0 :         elog(ERROR, "invalid attribute number %d", attrno);
 2217 andres                   1102 EUB             : 
 2217 andres                   1103 UIC           0 :     if (isNull == NULL)
 2217 andres                   1104 UBC           0 :         elog(ERROR, "a NULL isNull pointer was passed");
                               1105                 : 
 2217 andres                   1106 UIC           0 :     if (tuple == NULL)
 2217 andres                   1107 EUB             :     {
                               1108                 :         /* Kinda bogus but compatible with old behavior... */
 2217 andres                   1109 UIC           0 :         *isNull = true;
                               1110               0 :         return (Datum) 0;
 2217 andres                   1111 EUB             :     }
                               1112                 : 
 2217 andres                   1113 UBC           0 :     tupType = HeapTupleHeaderGetTypeId(tuple);
 2217 andres                   1114 UIC           0 :     tupTypmod = HeapTupleHeaderGetTypMod(tuple);
                               1115               0 :     tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
                               1116                 : 
                               1117                 :     /*
                               1118                 :      * heap_getattr needs a HeapTuple not a bare HeapTupleHeader.  We set all
                               1119                 :      * the fields in the struct just in case user tries to inspect system
 2217 andres                   1120 EUB             :      * columns.
                               1121                 :      */
 2217 andres                   1122 UBC           0 :     tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
                               1123               0 :     ItemPointerSetInvalid(&(tmptup.t_self));
 2217 andres                   1124 UIC           0 :     tmptup.t_tableOid = InvalidOid;
 2217 andres                   1125 UBC           0 :     tmptup.t_data = tuple;
                               1126                 : 
 2217 andres                   1127 UIC           0 :     result = heap_getattr(&tmptup,
                               1128                 :                           attrno,
                               1129                 :                           tupDesc,
 2217 andres                   1130 EUB             :                           isNull);
                               1131                 : 
 2217 andres                   1132 UBC           0 :     ReleaseTupleDesc(tupDesc);
                               1133                 : 
 2217 andres                   1134 UIC           0 :     return result;
                               1135                 : }
                               1136                 : 
                               1137                 : /*
                               1138                 :  * Number of items in a tlist (including any resjunk items!)
 2217 andres                   1139 ECB             :  */
                               1140                 : int
 2217 andres                   1141 GIC      569995 : ExecTargetListLength(List *targetlist)
 2217 andres                   1142 ECB             : {
                               1143                 :     /* This used to be more complex, but fjoins are dead */
 2217 andres                   1144 GIC      569995 :     return list_length(targetlist);
                               1145                 : }
                               1146                 : 
                               1147                 : /*
                               1148                 :  * Number of items in a tlist, not including any resjunk items
 2217 andres                   1149 ECB             :  */
                               1150                 : int
 2217 andres                   1151 CBC       80402 : ExecCleanTargetListLength(List *targetlist)
                               1152                 : {
 2217 andres                   1153 GIC       80402 :     int         len = 0;
 2217 andres                   1154 ECB             :     ListCell   *tl;
                               1155                 : 
 2217 andres                   1156 CBC      264933 :     foreach(tl, targetlist)
                               1157                 :     {
 2190 tgl                      1158          184531 :         TargetEntry *curTle = lfirst_node(TargetEntry, tl);
 2217 andres                   1159 ECB             : 
 2217 andres                   1160 GIC      184531 :         if (!curTle->resjunk)
 2217 andres                   1161 CBC      171067 :             len++;
                               1162                 :     }
 2217 andres                   1163 GIC       80402 :     return len;
                               1164                 : }
                               1165                 : 
                               1166                 : /*
                               1167                 :  * Return a relInfo's tuple slot for a trigger's OLD tuples.
 1503 andres                   1168 ECB             :  */
                               1169                 : TupleTableSlot *
 1503 andres                   1170 CBC       11145 : ExecGetTriggerOldSlot(EState *estate, ResultRelInfo *relInfo)
                               1171                 : {
                               1172           11145 :     if (relInfo->ri_TrigOldSlot == NULL)
 1503 andres                   1173 ECB             :     {
 1503 andres                   1174 GIC        4475 :         Relation    rel = relInfo->ri_RelationDesc;
 1503 andres                   1175 CBC        4475 :         MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
 1503 andres                   1176 ECB             : 
 1503 andres                   1177 GIC        4475 :         relInfo->ri_TrigOldSlot =
                               1178            4475 :             ExecInitExtraTupleSlot(estate,
                               1179                 :                                    RelationGetDescr(rel),
 1490 andres                   1180 ECB             :                                    table_slot_callbacks(rel));
                               1181                 : 
 1503 andres                   1182 GIC        4475 :         MemoryContextSwitchTo(oldcontext);
 1503 andres                   1183 ECB             :     }
                               1184                 : 
 1503 andres                   1185 GIC       11145 :     return relInfo->ri_TrigOldSlot;
                               1186                 : }
                               1187                 : 
                               1188                 : /*
                               1189                 :  * Return a relInfo's tuple slot for a trigger's NEW tuples.
 1503 andres                   1190 ECB             :  */
                               1191                 : TupleTableSlot *
 1503 andres                   1192 CBC        1593 : ExecGetTriggerNewSlot(EState *estate, ResultRelInfo *relInfo)
                               1193                 : {
                               1194            1593 :     if (relInfo->ri_TrigNewSlot == NULL)
 1503 andres                   1195 ECB             :     {
 1503 andres                   1196 GIC         956 :         Relation    rel = relInfo->ri_RelationDesc;
 1503 andres                   1197 CBC         956 :         MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
 1503 andres                   1198 ECB             : 
 1503 andres                   1199 GIC         956 :         relInfo->ri_TrigNewSlot =
                               1200             956 :             ExecInitExtraTupleSlot(estate,
                               1201                 :                                    RelationGetDescr(rel),
 1490 andres                   1202 ECB             :                                    table_slot_callbacks(rel));
                               1203                 : 
 1503 andres                   1204 GIC         956 :         MemoryContextSwitchTo(oldcontext);
 1503 andres                   1205 ECB             :     }
                               1206                 : 
 1503 andres                   1207 GIC        1593 :     return relInfo->ri_TrigNewSlot;
                               1208                 : }
                               1209                 : 
                               1210                 : /*
                               1211                 :  * Return a relInfo's tuple slot for processing returning tuples.
 1503 andres                   1212 ECB             :  */
                               1213                 : TupleTableSlot *
 1503 andres                   1214 CBC         545 : ExecGetReturningSlot(EState *estate, ResultRelInfo *relInfo)
                               1215                 : {
                               1216             545 :     if (relInfo->ri_ReturningSlot == NULL)
 1503 andres                   1217 ECB             :     {
 1503 andres                   1218 GIC         241 :         Relation    rel = relInfo->ri_RelationDesc;
 1503 andres                   1219 CBC         241 :         MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
 1503 andres                   1220 ECB             : 
 1503 andres                   1221 GIC         241 :         relInfo->ri_ReturningSlot =
                               1222             241 :             ExecInitExtraTupleSlot(estate,
                               1223                 :                                    RelationGetDescr(rel),
 1490 andres                   1224 ECB             :                                    table_slot_callbacks(rel));
                               1225                 : 
 1503 andres                   1226 GIC         241 :         MemoryContextSwitchTo(oldcontext);
 1503 andres                   1227 ECB             :     }
                               1228                 : 
 1503 andres                   1229 GIC         545 :     return relInfo->ri_ReturningSlot;
                               1230                 : }
                               1231                 : 
                               1232                 : /*
                               1233                 :  * Return the map needed to convert given child result relation's tuples to
                               1234                 :  * the rowtype of the query's main target ("root") relation.  Note that a
                               1235                 :  * NULL result is valid and means that no conversion is needed.
  733 tgl                      1236 ECB             :  */
                               1237                 : TupleConversionMap *
  733 tgl                      1238 GIC       33772 : ExecGetChildToRootMap(ResultRelInfo *resultRelInfo)
  733 tgl                      1239 ECB             : {
                               1240                 :     /* If we didn't already do so, compute the map for this child. */
  733 tgl                      1241 CBC       33772 :     if (!resultRelInfo->ri_ChildToRootMapValid)
                               1242                 :     {
                               1243             752 :         ResultRelInfo *rootRelInfo = resultRelInfo->ri_RootResultRelInfo;
  733 tgl                      1244 ECB             : 
  733 tgl                      1245 CBC         752 :         if (rootRelInfo)
                               1246             566 :             resultRelInfo->ri_ChildToRootMap =
  733 tgl                      1247 GIC         566 :                 convert_tuples_by_name(RelationGetDescr(resultRelInfo->ri_RelationDesc),
  733 tgl                      1248 CBC         566 :                                        RelationGetDescr(rootRelInfo->ri_RelationDesc));
                               1249                 :         else                    /* this isn't a child result rel */
                               1250             186 :             resultRelInfo->ri_ChildToRootMap = NULL;
                               1251                 : 
  733 tgl                      1252 GIC         752 :         resultRelInfo->ri_ChildToRootMapValid = true;
  733 tgl                      1253 ECB             :     }
                               1254                 : 
  733 tgl                      1255 GIC       33772 :     return resultRelInfo->ri_ChildToRootMap;
                               1256                 : }
                               1257                 : 
                               1258                 : /*
                               1259                 :  * Returns the map needed to convert given root result relation's tuples to
                               1260                 :  * the rowtype of the given child relation.  Note that a NULL result is valid
                               1261                 :  * and means that no conversion is needed.
                               1262                 :  */
                               1263                 : TupleConversionMap *
  128 alvherre                 1264 GNC      472699 : ExecGetRootToChildMap(ResultRelInfo *resultRelInfo, EState *estate)
                               1265                 : {
                               1266                 :     /* Mustn't get called for a non-child result relation. */
                               1267          472699 :     Assert(resultRelInfo->ri_RootResultRelInfo);
                               1268                 : 
                               1269                 :     /* If we didn't already do so, compute the map for this child. */
                               1270          472699 :     if (!resultRelInfo->ri_RootToChildMapValid)
                               1271                 :     {
                               1272            4331 :         ResultRelInfo *rootRelInfo = resultRelInfo->ri_RootResultRelInfo;
                               1273            4331 :         TupleDesc   indesc = RelationGetDescr(rootRelInfo->ri_RelationDesc);
                               1274            4331 :         TupleDesc   outdesc = RelationGetDescr(resultRelInfo->ri_RelationDesc);
                               1275            4331 :         Relation    childrel = resultRelInfo->ri_RelationDesc;
                               1276                 :         AttrMap    *attrMap;
                               1277                 :         MemoryContext oldcontext;
                               1278                 : 
                               1279                 :         /*
                               1280                 :          * When this child table is not a partition (!relispartition), it may
                               1281                 :          * have columns that are not present in the root table, which we ask
                               1282                 :          * to ignore by passing true for missing_ok.
                               1283                 :          */
                               1284            4331 :         oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
                               1285            4331 :         attrMap = build_attrmap_by_name_if_req(indesc, outdesc,
                               1286            4331 :                                                !childrel->rd_rel->relispartition);
                               1287            4331 :         if (attrMap)
                               1288             689 :             resultRelInfo->ri_RootToChildMap =
                               1289             689 :                 convert_tuples_by_name_attrmap(indesc, outdesc, attrMap);
                               1290            4331 :         MemoryContextSwitchTo(oldcontext);
                               1291            4331 :         resultRelInfo->ri_RootToChildMapValid = true;
                               1292                 :     }
                               1293                 : 
                               1294          472699 :     return resultRelInfo->ri_RootToChildMap;
                               1295                 : }
                               1296                 : 
                               1297                 : /* Return a bitmap representing columns being inserted */
                               1298                 : Bitmapset *
  790 heikki.linnakangas       1299 GIC         536 : ExecGetInsertedCols(ResultRelInfo *relinfo, EState *estate)
                               1300                 : {
  124 alvherre                 1301 GNC         536 :     RTEPermissionInfo *perminfo = GetResultRTEPermissionInfo(relinfo, estate);
  790 heikki.linnakangas       1302 ECB             : 
  124 alvherre                 1303 GNC         536 :     if (perminfo == NULL)
  124 alvherre                 1304 UIC           0 :         return NULL;
                               1305                 : 
                               1306                 :     /* Map the columns to child's attribute numbers if needed. */
  124 alvherre                 1307 GNC         536 :     if (relinfo->ri_RootResultRelInfo)
                               1308                 :     {
  128                          1309              59 :         TupleConversionMap *map = ExecGetRootToChildMap(relinfo, estate);
                               1310                 : 
  124                          1311              59 :         if (map)
  124 alvherre                 1312 UNC           0 :             return execute_attr_map_cols(map->attrMap, perminfo->insertedCols);
                               1313                 :     }
                               1314                 : 
  124 alvherre                 1315 GNC         536 :     return perminfo->insertedCols;
                               1316                 : }
                               1317                 : 
  790 heikki.linnakangas       1318 ECB             : /* Return a bitmap representing columns being updated */
                               1319                 : Bitmapset *
  790 heikki.linnakangas       1320 CBC       29963 : ExecGetUpdatedCols(ResultRelInfo *relinfo, EState *estate)
                               1321                 : {
  124 alvherre                 1322 GNC       29963 :     RTEPermissionInfo *perminfo = GetResultRTEPermissionInfo(relinfo, estate);
  790 heikki.linnakangas       1323 ECB             : 
  124 alvherre                 1324 GNC       29963 :     if (perminfo == NULL)
  124 alvherre                 1325 LBC           0 :         return NULL;
                               1326                 : 
                               1327                 :     /* Map the columns to child's attribute numbers if needed. */
  124 alvherre                 1328 GNC       29963 :     if (relinfo->ri_RootResultRelInfo)
                               1329                 :     {
  128                          1330             833 :         TupleConversionMap *map = ExecGetRootToChildMap(relinfo, estate);
                               1331                 : 
  124                          1332             833 :         if (map)
                               1333             243 :             return execute_attr_map_cols(map->attrMap, perminfo->updatedCols);
                               1334                 :     }
                               1335                 : 
                               1336           29720 :     return perminfo->updatedCols;
                               1337                 : }
  790 heikki.linnakangas       1338 ECB             : 
  790 heikki.linnakangas       1339 EUB             : /* Return a bitmap representing generated columns being updated */
                               1340                 : Bitmapset *
  790 heikki.linnakangas       1341 GIC       29334 : ExecGetExtraUpdatedCols(ResultRelInfo *relinfo, EState *estate)
  790 heikki.linnakangas       1342 ECB             : {
                               1343                 :     /* Compute the info if we didn't already */
   34 tgl                      1344 GNC       29334 :     if (relinfo->ri_GeneratedExprsU == NULL)
   84                          1345           29277 :         ExecInitStoredGenerated(relinfo, estate, CMD_UPDATE);
   94                          1346           29334 :     return relinfo->ri_extraUpdatedCols;
                               1347                 : }
                               1348                 : 
  790 heikki.linnakangas       1349 ECB             : /* Return columns being updated, including generated columns */
                               1350                 : Bitmapset *
  790 heikki.linnakangas       1351 CBC        7071 : ExecGetAllUpdatedCols(ResultRelInfo *relinfo, EState *estate)
  790 heikki.linnakangas       1352 ECB             : {
  790 heikki.linnakangas       1353 GIC        7071 :     return bms_union(ExecGetUpdatedCols(relinfo, estate),
                               1354            7071 :                      ExecGetExtraUpdatedCols(relinfo, estate));
                               1355                 : }
                               1356                 : 
                               1357                 : /*
                               1358                 :  * GetResultRTEPermissionInfo
                               1359                 :  *      Looks up RTEPermissionInfo for ExecGet*Cols() routines
                               1360                 :  */
                               1361                 : static RTEPermissionInfo *
  124 alvherre                 1362 GNC       30668 : GetResultRTEPermissionInfo(ResultRelInfo *relinfo, EState *estate)
                               1363                 : {
                               1364                 :     Index       rti;
                               1365                 :     RangeTblEntry *rte;
                               1366           30668 :     RTEPermissionInfo *perminfo = NULL;
                               1367                 : 
                               1368           30668 :     if (relinfo->ri_RootResultRelInfo)
                               1369                 :     {
                               1370                 :         /*
                               1371                 :          * For inheritance child result relations (a partition routing target
                               1372                 :          * of an INSERT or a child UPDATE target), this returns the root
                               1373                 :          * parent's RTE to fetch the RTEPermissionInfo because that's the only
                               1374                 :          * one that has one assigned.
                               1375                 :          */
                               1376             939 :         rti = relinfo->ri_RootResultRelInfo->ri_RangeTableIndex;
                               1377                 :     }
                               1378           29729 :     else if (relinfo->ri_RangeTableIndex != 0)
                               1379                 :     {
                               1380                 :         /*
                               1381                 :          * Non-child result relation should have their own RTEPermissionInfo.
                               1382                 :          */
                               1383           29729 :         rti = relinfo->ri_RangeTableIndex;
                               1384                 :     }
                               1385                 :     else
                               1386                 :     {
                               1387                 :         /*
                               1388                 :          * The relation isn't in the range table and it isn't a partition
                               1389                 :          * routing target.  This ResultRelInfo must've been created only for
                               1390                 :          * firing triggers and the relation is not being inserted into.  (See
                               1391                 :          * ExecGetTriggerResultRel.)
                               1392                 :          */
  124 alvherre                 1393 UNC           0 :         rti = 0;
                               1394                 :     }
                               1395                 : 
  124 alvherre                 1396 GNC       30668 :     if (rti > 0)
                               1397                 :     {
                               1398           30668 :         rte = exec_rt_fetch(rti, estate);
                               1399           30668 :         perminfo = getRTEPermissionInfo(estate->es_rteperminfos, rte);
                               1400                 :     }
                               1401                 : 
                               1402           30668 :     return perminfo;
                               1403                 : }
                               1404                 : 
                               1405                 : /*
                               1406                 :  * GetResultRelCheckAsUser
                               1407                 :  *      Returns the user to modify passed-in result relation as
                               1408                 :  *
                               1409                 :  * The user is chosen by looking up the relation's or, if a child table, its
                               1410                 :  * root parent's RTEPermissionInfo.
                               1411                 :  */
                               1412                 : Oid
                               1413             169 : ExecGetResultRelCheckAsUser(ResultRelInfo *relInfo, EState *estate)
                               1414                 : {
                               1415             169 :     RTEPermissionInfo *perminfo = GetResultRTEPermissionInfo(relInfo, estate);
                               1416                 : 
                               1417                 :     /* XXX - maybe ok to return GetUserId() in this case? */
                               1418             169 :     if (perminfo == NULL)
  124 alvherre                 1419 UNC           0 :         elog(ERROR, "no RTEPermissionInfo found for result relation with OID %u",
                               1420                 :              RelationGetRelid(relInfo->ri_RelationDesc));
                               1421                 : 
  124 alvherre                 1422 GNC         169 :     return perminfo->checkAsUser ? perminfo->checkAsUser : GetUserId();
                               1423                 : }
        

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