LCOV - code coverage report
Current view: top level - src/backend/executor - execUtils.c (source / functions) Hit Total Coverage
Test: PostgreSQL 13devel Lines: 284 325 87.4 %
Date: 2019-11-22 07:06:56 Functions: 29 32 90.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * execUtils.c
       4             :  *    miscellaneous executor utility routines
       5             :  *
       6             :  * Portions Copyright (c) 1996-2019, 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 "jit/jit.h"
      55             : #include "mb/pg_wchar.h"
      56             : #include "nodes/nodeFuncs.h"
      57             : #include "parser/parsetree.h"
      58             : #include "partitioning/partdesc.h"
      59             : #include "storage/lmgr.h"
      60             : #include "utils/builtins.h"
      61             : #include "utils/memutils.h"
      62             : #include "utils/rel.h"
      63             : #include "utils/typcache.h"
      64             : 
      65             : 
      66             : static bool tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc);
      67             : static void ShutdownExprContext(ExprContext *econtext, bool isCommit);
      68             : 
      69             : 
      70             : /* ----------------------------------------------------------------
      71             :  *               Executor state and memory management functions
      72             :  * ----------------------------------------------------------------
      73             :  */
      74             : 
      75             : /* ----------------
      76             :  *      CreateExecutorState
      77             :  *
      78             :  *      Create and initialize an EState node, which is the root of
      79             :  *      working storage for an entire Executor invocation.
      80             :  *
      81             :  * Principally, this creates the per-query memory context that will be
      82             :  * used to hold all working data that lives till the end of the query.
      83             :  * Note that the per-query context will become a child of the caller's
      84             :  * CurrentMemoryContext.
      85             :  * ----------------
      86             :  */
      87             : EState *
      88      533406 : CreateExecutorState(void)
      89             : {
      90             :     EState     *estate;
      91             :     MemoryContext qcontext;
      92             :     MemoryContext oldcontext;
      93             : 
      94             :     /*
      95             :      * Create the per-query context for this Executor run.
      96             :      */
      97      533406 :     qcontext = AllocSetContextCreate(CurrentMemoryContext,
      98             :                                      "ExecutorState",
      99             :                                      ALLOCSET_DEFAULT_SIZES);
     100             : 
     101             :     /*
     102             :      * Make the EState node within the per-query context.  This way, we don't
     103             :      * need a separate pfree() operation for it at shutdown.
     104             :      */
     105      533406 :     oldcontext = MemoryContextSwitchTo(qcontext);
     106             : 
     107      533406 :     estate = makeNode(EState);
     108             : 
     109             :     /*
     110             :      * Initialize all fields of the Executor State structure
     111             :      */
     112      533406 :     estate->es_direction = ForwardScanDirection;
     113      533406 :     estate->es_snapshot = InvalidSnapshot;   /* caller must initialize this */
     114      533406 :     estate->es_crosscheck_snapshot = InvalidSnapshot;    /* no crosscheck */
     115      533406 :     estate->es_range_table = NIL;
     116      533406 :     estate->es_range_table_size = 0;
     117      533406 :     estate->es_relations = NULL;
     118      533406 :     estate->es_rowmarks = NULL;
     119      533406 :     estate->es_plannedstmt = NULL;
     120             : 
     121      533406 :     estate->es_junkFilter = NULL;
     122             : 
     123      533406 :     estate->es_output_cid = (CommandId) 0;
     124             : 
     125      533406 :     estate->es_result_relations = NULL;
     126      533406 :     estate->es_num_result_relations = 0;
     127      533406 :     estate->es_result_relation_info = NULL;
     128             : 
     129      533406 :     estate->es_root_result_relations = NULL;
     130      533406 :     estate->es_num_root_result_relations = 0;
     131             : 
     132      533406 :     estate->es_tuple_routing_result_relations = NIL;
     133             : 
     134      533406 :     estate->es_trig_target_relations = NIL;
     135             : 
     136      533406 :     estate->es_param_list_info = NULL;
     137      533406 :     estate->es_param_exec_vals = NULL;
     138             : 
     139      533406 :     estate->es_queryEnv = NULL;
     140             : 
     141      533406 :     estate->es_query_cxt = qcontext;
     142             : 
     143      533406 :     estate->es_tupleTable = NIL;
     144             : 
     145      533406 :     estate->es_processed = 0;
     146             : 
     147      533406 :     estate->es_top_eflags = 0;
     148      533406 :     estate->es_instrument = 0;
     149      533406 :     estate->es_finished = false;
     150             : 
     151      533406 :     estate->es_exprcontexts = NIL;
     152             : 
     153      533406 :     estate->es_subplanstates = NIL;
     154             : 
     155      533406 :     estate->es_auxmodifytables = NIL;
     156             : 
     157      533406 :     estate->es_per_tuple_exprcontext = NULL;
     158             : 
     159      533406 :     estate->es_sourceText = NULL;
     160             : 
     161      533406 :     estate->es_use_parallel_mode = false;
     162             : 
     163      533406 :     estate->es_jit_flags = 0;
     164      533406 :     estate->es_jit = NULL;
     165             : 
     166             :     /*
     167             :      * Return the executor state structure
     168             :      */
     169      533406 :     MemoryContextSwitchTo(oldcontext);
     170             : 
     171      533406 :     return estate;
     172             : }
     173             : 
     174             : /* ----------------
     175             :  *      FreeExecutorState
     176             :  *
     177             :  *      Release an EState along with all remaining working storage.
     178             :  *
     179             :  * Note: this is not responsible for releasing non-memory resources, such as
     180             :  * open relations or buffer pins.  But it will shut down any still-active
     181             :  * ExprContexts within the EState and deallocate associated JITed expressions.
     182             :  * That is sufficient cleanup for situations where the EState has only been
     183             :  * used for expression evaluation, and not to run a complete Plan.
     184             :  *
     185             :  * This can be called in any memory context ... so long as it's not one
     186             :  * of the ones to be freed.
     187             :  * ----------------
     188             :  */
     189             : void
     190      517890 : FreeExecutorState(EState *estate)
     191             : {
     192             :     /*
     193             :      * Shut down and free any remaining ExprContexts.  We do this explicitly
     194             :      * to ensure that any remaining shutdown callbacks get called (since they
     195             :      * might need to release resources that aren't simply memory within the
     196             :      * per-query memory context).
     197             :      */
     198     1930396 :     while (estate->es_exprcontexts)
     199             :     {
     200             :         /*
     201             :          * XXX: seems there ought to be a faster way to implement this than
     202             :          * repeated list_delete(), no?
     203             :          */
     204      894616 :         FreeExprContext((ExprContext *) linitial(estate->es_exprcontexts),
     205             :                         true);
     206             :         /* FreeExprContext removed the list link for us */
     207             :     }
     208             : 
     209             :     /* release JIT context, if allocated */
     210      517890 :     if (estate->es_jit)
     211             :     {
     212         848 :         jit_release_context(estate->es_jit);
     213         848 :         estate->es_jit = NULL;
     214             :     }
     215             : 
     216             :     /* release partition directory, if allocated */
     217      517890 :     if (estate->es_partition_directory)
     218             :     {
     219        1906 :         DestroyPartitionDirectory(estate->es_partition_directory);
     220        1906 :         estate->es_partition_directory = NULL;
     221             :     }
     222             : 
     223             :     /*
     224             :      * Free the per-query memory context, thereby releasing all working
     225             :      * memory, including the EState node itself.
     226             :      */
     227      517890 :     MemoryContextDelete(estate->es_query_cxt);
     228      517890 : }
     229             : 
     230             : /* ----------------
     231             :  *      CreateExprContext
     232             :  *
     233             :  *      Create a context for expression evaluation within an EState.
     234             :  *
     235             :  * An executor run may require multiple ExprContexts (we usually make one
     236             :  * for each Plan node, and a separate one for per-output-tuple processing
     237             :  * such as constraint checking).  Each ExprContext has its own "per-tuple"
     238             :  * memory context.
     239             :  *
     240             :  * Note we make no assumption about the caller's memory context.
     241             :  * ----------------
     242             :  */
     243             : ExprContext *
     244      982124 : CreateExprContext(EState *estate)
     245             : {
     246             :     ExprContext *econtext;
     247             :     MemoryContext oldcontext;
     248             : 
     249             :     /* Create the ExprContext node within the per-query memory context */
     250      982124 :     oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
     251             : 
     252      982124 :     econtext = makeNode(ExprContext);
     253             : 
     254             :     /* Initialize fields of ExprContext */
     255      982124 :     econtext->ecxt_scantuple = NULL;
     256      982124 :     econtext->ecxt_innertuple = NULL;
     257      982124 :     econtext->ecxt_outertuple = NULL;
     258             : 
     259      982124 :     econtext->ecxt_per_query_memory = estate->es_query_cxt;
     260             : 
     261             :     /*
     262             :      * Create working memory for expression evaluation in this context.
     263             :      */
     264      982124 :     econtext->ecxt_per_tuple_memory =
     265      982124 :         AllocSetContextCreate(estate->es_query_cxt,
     266             :                               "ExprContext",
     267             :                               ALLOCSET_DEFAULT_SIZES);
     268             : 
     269      982124 :     econtext->ecxt_param_exec_vals = estate->es_param_exec_vals;
     270      982124 :     econtext->ecxt_param_list_info = estate->es_param_list_info;
     271             : 
     272      982124 :     econtext->ecxt_aggvalues = NULL;
     273      982124 :     econtext->ecxt_aggnulls = NULL;
     274             : 
     275      982124 :     econtext->caseValue_datum = (Datum) 0;
     276      982124 :     econtext->caseValue_isNull = true;
     277             : 
     278      982124 :     econtext->domainValue_datum = (Datum) 0;
     279      982124 :     econtext->domainValue_isNull = true;
     280             : 
     281      982124 :     econtext->ecxt_estate = estate;
     282             : 
     283      982124 :     econtext->ecxt_callbacks = NULL;
     284             : 
     285             :     /*
     286             :      * Link the ExprContext into the EState to ensure it is shut down when the
     287             :      * EState is freed.  Because we use lcons(), shutdowns will occur in
     288             :      * reverse order of creation, which may not be essential but can't hurt.
     289             :      */
     290      982124 :     estate->es_exprcontexts = lcons(econtext, estate->es_exprcontexts);
     291             : 
     292      982124 :     MemoryContextSwitchTo(oldcontext);
     293             : 
     294      982124 :     return econtext;
     295             : }
     296             : 
     297             : /* ----------------
     298             :  *      CreateStandaloneExprContext
     299             :  *
     300             :  *      Create a context for standalone expression evaluation.
     301             :  *
     302             :  * An ExprContext made this way can be used for evaluation of expressions
     303             :  * that contain no Params, subplans, or Var references (it might work to
     304             :  * put tuple references into the scantuple field, but it seems unwise).
     305             :  *
     306             :  * The ExprContext struct is allocated in the caller's current memory
     307             :  * context, which also becomes its "per query" context.
     308             :  *
     309             :  * It is caller's responsibility to free the ExprContext when done,
     310             :  * or at least ensure that any shutdown callbacks have been called
     311             :  * (ReScanExprContext() is suitable).  Otherwise, non-memory resources
     312             :  * might be leaked.
     313             :  * ----------------
     314             :  */
     315             : ExprContext *
     316        5690 : CreateStandaloneExprContext(void)
     317             : {
     318             :     ExprContext *econtext;
     319             : 
     320             :     /* Create the ExprContext node within the caller's memory context */
     321        5690 :     econtext = makeNode(ExprContext);
     322             : 
     323             :     /* Initialize fields of ExprContext */
     324        5690 :     econtext->ecxt_scantuple = NULL;
     325        5690 :     econtext->ecxt_innertuple = NULL;
     326        5690 :     econtext->ecxt_outertuple = NULL;
     327             : 
     328        5690 :     econtext->ecxt_per_query_memory = CurrentMemoryContext;
     329             : 
     330             :     /*
     331             :      * Create working memory for expression evaluation in this context.
     332             :      */
     333        5690 :     econtext->ecxt_per_tuple_memory =
     334        5690 :         AllocSetContextCreate(CurrentMemoryContext,
     335             :                               "ExprContext",
     336             :                               ALLOCSET_DEFAULT_SIZES);
     337             : 
     338        5690 :     econtext->ecxt_param_exec_vals = NULL;
     339        5690 :     econtext->ecxt_param_list_info = NULL;
     340             : 
     341        5690 :     econtext->ecxt_aggvalues = NULL;
     342        5690 :     econtext->ecxt_aggnulls = NULL;
     343             : 
     344        5690 :     econtext->caseValue_datum = (Datum) 0;
     345        5690 :     econtext->caseValue_isNull = true;
     346             : 
     347        5690 :     econtext->domainValue_datum = (Datum) 0;
     348        5690 :     econtext->domainValue_isNull = true;
     349             : 
     350        5690 :     econtext->ecxt_estate = NULL;
     351             : 
     352        5690 :     econtext->ecxt_callbacks = NULL;
     353             : 
     354        5690 :     return econtext;
     355             : }
     356             : 
     357             : /* ----------------
     358             :  *      FreeExprContext
     359             :  *
     360             :  *      Free an expression context, including calling any remaining
     361             :  *      shutdown callbacks.
     362             :  *
     363             :  * Since we free the temporary context used for expression evaluation,
     364             :  * any previously computed pass-by-reference expression result will go away!
     365             :  *
     366             :  * If isCommit is false, we are being called in error cleanup, and should
     367             :  * not call callbacks but only release memory.  (It might be better to call
     368             :  * the callbacks and pass the isCommit flag to them, but that would require
     369             :  * more invasive code changes than currently seems justified.)
     370             :  *
     371             :  * Note we make no assumption about the caller's memory context.
     372             :  * ----------------
     373             :  */
     374             : void
     375      964096 : FreeExprContext(ExprContext *econtext, bool isCommit)
     376             : {
     377             :     EState     *estate;
     378             : 
     379             :     /* Call any registered callbacks */
     380      964096 :     ShutdownExprContext(econtext, isCommit);
     381             :     /* And clean up the memory used */
     382      964096 :     MemoryContextDelete(econtext->ecxt_per_tuple_memory);
     383             :     /* Unlink self from owning EState, if any */
     384      964096 :     estate = econtext->ecxt_estate;
     385      964096 :     if (estate)
     386      964096 :         estate->es_exprcontexts = list_delete_ptr(estate->es_exprcontexts,
     387             :                                                   econtext);
     388             :     /* And delete the ExprContext node */
     389      964096 :     pfree(econtext);
     390      964096 : }
     391             : 
     392             : /*
     393             :  * ReScanExprContext
     394             :  *
     395             :  *      Reset an expression context in preparation for a rescan of its
     396             :  *      plan node.  This requires calling any registered shutdown callbacks,
     397             :  *      since any partially complete set-returning-functions must be canceled.
     398             :  *
     399             :  * Note we make no assumption about the caller's memory context.
     400             :  */
     401             : void
     402     8960308 : ReScanExprContext(ExprContext *econtext)
     403             : {
     404             :     /* Call any registered callbacks */
     405     8960308 :     ShutdownExprContext(econtext, true);
     406             :     /* And clean up the memory used */
     407     8960308 :     MemoryContextReset(econtext->ecxt_per_tuple_memory);
     408     8960308 : }
     409             : 
     410             : /*
     411             :  * Build a per-output-tuple ExprContext for an EState.
     412             :  *
     413             :  * This is normally invoked via GetPerTupleExprContext() macro,
     414             :  * not directly.
     415             :  */
     416             : ExprContext *
     417      199530 : MakePerTupleExprContext(EState *estate)
     418             : {
     419      199530 :     if (estate->es_per_tuple_exprcontext == NULL)
     420      199530 :         estate->es_per_tuple_exprcontext = CreateExprContext(estate);
     421             : 
     422      199530 :     return estate->es_per_tuple_exprcontext;
     423             : }
     424             : 
     425             : 
     426             : /* ----------------------------------------------------------------
     427             :  *               miscellaneous node-init support functions
     428             :  *
     429             :  * Note: all of these are expected to be called with CurrentMemoryContext
     430             :  * equal to the per-query memory context.
     431             :  * ----------------------------------------------------------------
     432             :  */
     433             : 
     434             : /* ----------------
     435             :  *      ExecAssignExprContext
     436             :  *
     437             :  *      This initializes the ps_ExprContext field.  It is only necessary
     438             :  *      to do this for nodes which use ExecQual or ExecProject
     439             :  *      because those routines require an econtext. Other nodes that
     440             :  *      don't have to evaluate expressions don't need to do this.
     441             :  * ----------------
     442             :  */
     443             : void
     444      702670 : ExecAssignExprContext(EState *estate, PlanState *planstate)
     445             : {
     446      702670 :     planstate->ps_ExprContext = CreateExprContext(estate);
     447      702670 : }
     448             : 
     449             : /* ----------------
     450             :  *      ExecGetResultType
     451             :  * ----------------
     452             :  */
     453             : TupleDesc
     454      917154 : ExecGetResultType(PlanState *planstate)
     455             : {
     456      917154 :     return planstate->ps_ResultTupleDesc;
     457             : }
     458             : 
     459             : /*
     460             :  * ExecGetResultSlotOps - information about node's type of result slot
     461             :  */
     462             : const TupleTableSlotOps *
     463      349884 : ExecGetResultSlotOps(PlanState *planstate, bool *isfixed)
     464             : {
     465      349884 :     if (planstate->resultopsset && planstate->resultops)
     466             :     {
     467      349080 :         if (isfixed)
     468      317714 :             *isfixed = planstate->resultopsfixed;
     469      349080 :         return planstate->resultops;
     470             :     }
     471             : 
     472         804 :     if (isfixed)
     473             :     {
     474         784 :         if (planstate->resultopsset)
     475         784 :             *isfixed = planstate->resultopsfixed;
     476           0 :         else if (planstate->ps_ResultTupleSlot)
     477           0 :             *isfixed = TTS_FIXED(planstate->ps_ResultTupleSlot);
     478             :         else
     479           0 :             *isfixed = false;
     480             :     }
     481             : 
     482         804 :     if (!planstate->ps_ResultTupleSlot)
     483         804 :         return &TTSOpsVirtual;
     484             : 
     485           0 :     return planstate->ps_ResultTupleSlot->tts_ops;
     486             : }
     487             : 
     488             : 
     489             : /* ----------------
     490             :  *      ExecAssignProjectionInfo
     491             :  *
     492             :  * forms the projection information from the node's targetlist
     493             :  *
     494             :  * Notes for inputDesc are same as for ExecBuildProjectionInfo: supply it
     495             :  * for a relation-scan node, can pass NULL for upper-level nodes
     496             :  * ----------------
     497             :  */
     498             : void
     499      448328 : ExecAssignProjectionInfo(PlanState *planstate,
     500             :                          TupleDesc inputDesc)
     501             : {
     502      448298 :     planstate->ps_ProjInfo =
     503      448328 :         ExecBuildProjectionInfo(planstate->plan->targetlist,
     504             :                                 planstate->ps_ExprContext,
     505             :                                 planstate->ps_ResultTupleSlot,
     506             :                                 planstate,
     507             :                                 inputDesc);
     508      448298 : }
     509             : 
     510             : 
     511             : /* ----------------
     512             :  *      ExecConditionalAssignProjectionInfo
     513             :  *
     514             :  * as ExecAssignProjectionInfo, but store NULL rather than building projection
     515             :  * info if no projection is required
     516             :  * ----------------
     517             :  */
     518             : void
     519      269754 : ExecConditionalAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc,
     520             :                                     Index varno)
     521             : {
     522      269754 :     if (tlist_matches_tupdesc(planstate,
     523      269754 :                               planstate->plan->targetlist,
     524             :                               varno,
     525             :                               inputDesc))
     526             :     {
     527      120236 :         planstate->ps_ProjInfo = NULL;
     528      120236 :         planstate->resultopsset = planstate->scanopsset;
     529      120236 :         planstate->resultopsfixed = planstate->scanopsfixed;
     530      120236 :         planstate->resultops = planstate->scanops;
     531             :     }
     532             :     else
     533             :     {
     534      149518 :         if (!planstate->ps_ResultTupleSlot)
     535             :         {
     536      149518 :             ExecInitResultSlot(planstate, &TTSOpsVirtual);
     537      149518 :             planstate->resultops = &TTSOpsVirtual;
     538      149518 :             planstate->resultopsfixed = true;
     539      149518 :             planstate->resultopsset = true;
     540             :         }
     541      149518 :         ExecAssignProjectionInfo(planstate, inputDesc);
     542             :     }
     543      269754 : }
     544             : 
     545             : static bool
     546      269754 : tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc)
     547             : {
     548      269754 :     int         numattrs = tupdesc->natts;
     549             :     int         attrno;
     550      269754 :     ListCell   *tlist_item = list_head(tlist);
     551             : 
     552             :     /* Check the tlist attributes */
     553     1726036 :     for (attrno = 1; attrno <= numattrs; attrno++)
     554             :     {
     555     1600456 :         Form_pg_attribute att_tup = TupleDescAttr(tupdesc, attrno - 1);
     556             :         Var        *var;
     557             : 
     558     1600456 :         if (tlist_item == NULL)
     559       23424 :             return false;       /* tlist too short */
     560     1577032 :         var = (Var *) ((TargetEntry *) lfirst(tlist_item))->expr;
     561     1577032 :         if (!var || !IsA(var, Var))
     562       48192 :             return false;       /* tlist item not a Var */
     563             :         /* if these Asserts fail, planner messed up */
     564             :         Assert(var->varno == varno);
     565             :         Assert(var->varlevelsup == 0);
     566     1528840 :         if (var->varattno != attrno)
     567       72358 :             return false;       /* out of order */
     568     1456482 :         if (att_tup->attisdropped)
     569           0 :             return false;       /* table contains dropped columns */
     570     1456482 :         if (att_tup->atthasmissing)
     571         196 :             return false;       /* table contains cols with missing values */
     572             : 
     573             :         /*
     574             :          * Note: usually the Var's type should match the tupdesc exactly, but
     575             :          * in situations involving unions of columns that have different
     576             :          * typmods, the Var may have come from above the union and hence have
     577             :          * typmod -1.  This is a legitimate situation since the Var still
     578             :          * describes the column, just not as exactly as the tupdesc does. We
     579             :          * could change the planner to prevent it, but it'd then insert
     580             :          * projection steps just to convert from specific typmod to typmod -1,
     581             :          * which is pretty silly.
     582             :          */
     583     2912568 :         if (var->vartype != att_tup->atttypid ||
     584     1456286 :             (var->vartypmod != att_tup->atttypmod &&
     585           4 :              var->vartypmod != -1))
     586           4 :             return false;       /* type mismatch */
     587             : 
     588     1456282 :         tlist_item = lnext(tlist, tlist_item);
     589             :     }
     590             : 
     591      125580 :     if (tlist_item)
     592        5344 :         return false;           /* tlist too long */
     593             : 
     594      120236 :     return true;
     595             : }
     596             : 
     597             : /* ----------------
     598             :  *      ExecFreeExprContext
     599             :  *
     600             :  * A plan node's ExprContext should be freed explicitly during executor
     601             :  * shutdown because there may be shutdown callbacks to call.  (Other resources
     602             :  * made by the above routines, such as projection info, don't need to be freed
     603             :  * explicitly because they're just memory in the per-query memory context.)
     604             :  *
     605             :  * However ... there is no particular need to do it during ExecEndNode,
     606             :  * because FreeExecutorState will free any remaining ExprContexts within
     607             :  * the EState.  Letting FreeExecutorState do it allows the ExprContexts to
     608             :  * be freed in reverse order of creation, rather than order of creation as
     609             :  * will happen if we delete them here, which saves O(N^2) work in the list
     610             :  * cleanup inside FreeExprContext.
     611             :  * ----------------
     612             :  */
     613             : void
     614      579730 : ExecFreeExprContext(PlanState *planstate)
     615             : {
     616             :     /*
     617             :      * Per above discussion, don't actually delete the ExprContext. We do
     618             :      * unlink it from the plan node, though.
     619             :      */
     620      579730 :     planstate->ps_ExprContext = NULL;
     621      579730 : }
     622             : 
     623             : 
     624             : /* ----------------------------------------------------------------
     625             :  *                Scan node support
     626             :  * ----------------------------------------------------------------
     627             :  */
     628             : 
     629             : /* ----------------
     630             :  *      ExecAssignScanType
     631             :  * ----------------
     632             :  */
     633             : void
     634         312 : ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc)
     635             : {
     636         312 :     TupleTableSlot *slot = scanstate->ss_ScanTupleSlot;
     637             : 
     638         312 :     ExecSetSlotDescriptor(slot, tupDesc);
     639         312 : }
     640             : 
     641             : /* ----------------
     642             :  *      ExecCreateScanSlotFromOuterPlan
     643             :  * ----------------
     644             :  */
     645             : void
     646       65326 : ExecCreateScanSlotFromOuterPlan(EState *estate,
     647             :                                 ScanState *scanstate,
     648             :                                 const TupleTableSlotOps *tts_ops)
     649             : {
     650             :     PlanState  *outerPlan;
     651             :     TupleDesc   tupDesc;
     652             : 
     653       65326 :     outerPlan = outerPlanState(scanstate);
     654       65326 :     tupDesc = ExecGetResultType(outerPlan);
     655             : 
     656       65326 :     ExecInitScanTupleSlot(estate, scanstate, tupDesc, tts_ops);
     657       65326 : }
     658             : 
     659             : /* ----------------------------------------------------------------
     660             :  *      ExecRelationIsTargetRelation
     661             :  *
     662             :  *      Detect whether a relation (identified by rangetable index)
     663             :  *      is one of the target relations of the query.
     664             :  *
     665             :  * Note: This is currently no longer used in core.  We keep it around
     666             :  * because FDWs may wish to use it to determine if their foreign table
     667             :  * is a target relation.
     668             :  * ----------------------------------------------------------------
     669             :  */
     670             : bool
     671           0 : ExecRelationIsTargetRelation(EState *estate, Index scanrelid)
     672             : {
     673             :     ResultRelInfo *resultRelInfos;
     674             :     int         i;
     675             : 
     676           0 :     resultRelInfos = estate->es_result_relations;
     677           0 :     for (i = 0; i < estate->es_num_result_relations; i++)
     678             :     {
     679           0 :         if (resultRelInfos[i].ri_RangeTableIndex == scanrelid)
     680           0 :             return true;
     681             :     }
     682           0 :     return false;
     683             : }
     684             : 
     685             : /* ----------------------------------------------------------------
     686             :  *      ExecOpenScanRelation
     687             :  *
     688             :  *      Open the heap relation to be scanned by a base-level scan plan node.
     689             :  *      This should be called during the node's ExecInit routine.
     690             :  * ----------------------------------------------------------------
     691             :  */
     692             : Relation
     693      228992 : ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags)
     694             : {
     695             :     Relation    rel;
     696             : 
     697             :     /* Open the relation. */
     698      228992 :     rel = ExecGetRangeTableRelation(estate, scanrelid);
     699             : 
     700             :     /*
     701             :      * Complain if we're attempting a scan of an unscannable relation, except
     702             :      * when the query won't actually be run.  This is a slightly klugy place
     703             :      * to do this, perhaps, but there is no better place.
     704             :      */
     705      444138 :     if ((eflags & (EXEC_FLAG_EXPLAIN_ONLY | EXEC_FLAG_WITH_NO_DATA)) == 0 &&
     706      215146 :         !RelationIsScannable(rel))
     707           8 :         ereport(ERROR,
     708             :                 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
     709             :                  errmsg("materialized view \"%s\" has not been populated",
     710             :                         RelationGetRelationName(rel)),
     711             :                  errhint("Use the REFRESH MATERIALIZED VIEW command.")));
     712             : 
     713      228984 :     return rel;
     714             : }
     715             : 
     716             : /*
     717             :  * ExecInitRangeTable
     718             :  *      Set up executor's range-table-related data
     719             :  *
     720             :  * In addition to the range table proper, initialize arrays that are
     721             :  * indexed by rangetable index.
     722             :  */
     723             : void
     724      351714 : ExecInitRangeTable(EState *estate, List *rangeTable)
     725             : {
     726             :     /* Remember the range table List as-is */
     727      351714 :     estate->es_range_table = rangeTable;
     728             : 
     729             :     /* Set size of associated arrays */
     730      351714 :     estate->es_range_table_size = list_length(rangeTable);
     731             : 
     732             :     /*
     733             :      * Allocate an array to store an open Relation corresponding to each
     734             :      * rangetable entry, and initialize entries to NULL.  Relations are opened
     735             :      * and stored here as needed.
     736             :      */
     737      351714 :     estate->es_relations = (Relation *)
     738      351714 :         palloc0(estate->es_range_table_size * sizeof(Relation));
     739             : 
     740             :     /*
     741             :      * es_rowmarks is also parallel to the es_range_table, but it's allocated
     742             :      * only if needed.
     743             :      */
     744      351714 :     estate->es_rowmarks = NULL;
     745      351714 : }
     746             : 
     747             : /*
     748             :  * ExecGetRangeTableRelation
     749             :  *      Open the Relation for a range table entry, if not already done
     750             :  *
     751             :  * The Relations will be closed again in ExecEndPlan().
     752             :  */
     753             : Relation
     754      312568 : ExecGetRangeTableRelation(EState *estate, Index rti)
     755             : {
     756             :     Relation    rel;
     757             : 
     758             :     Assert(rti > 0 && rti <= estate->es_range_table_size);
     759             : 
     760      312568 :     rel = estate->es_relations[rti - 1];
     761      312568 :     if (rel == NULL)
     762             :     {
     763             :         /* First time through, so open the relation */
     764      290924 :         RangeTblEntry *rte = exec_rt_fetch(rti, estate);
     765             : 
     766             :         Assert(rte->rtekind == RTE_RELATION);
     767             : 
     768      290924 :         if (!IsParallelWorker())
     769             :         {
     770             :             /*
     771             :              * In a normal query, we should already have the appropriate lock,
     772             :              * but verify that through an Assert.  Since there's already an
     773             :              * Assert inside table_open that insists on holding some lock, it
     774             :              * seems sufficient to check this only when rellockmode is higher
     775             :              * than the minimum.
     776             :              */
     777      288236 :             rel = table_open(rte->relid, NoLock);
     778             :             Assert(rte->rellockmode == AccessShareLock ||
     779             :                    CheckRelationLockedByMe(rel, rte->rellockmode, false));
     780             :         }
     781             :         else
     782             :         {
     783             :             /*
     784             :              * If we are a parallel worker, we need to obtain our own local
     785             :              * lock on the relation.  This ensures sane behavior in case the
     786             :              * parent process exits before we do.
     787             :              */
     788        2688 :             rel = table_open(rte->relid, rte->rellockmode);
     789             :         }
     790             : 
     791      290924 :         estate->es_relations[rti - 1] = rel;
     792             :     }
     793             : 
     794      312568 :     return rel;
     795             : }
     796             : 
     797             : /*
     798             :  * UpdateChangedParamSet
     799             :  *      Add changed parameters to a plan node's chgParam set
     800             :  */
     801             : void
     802     3836216 : UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
     803             : {
     804             :     Bitmapset  *parmset;
     805             : 
     806             :     /*
     807             :      * The plan node only depends on params listed in its allParam set. Don't
     808             :      * include anything else into its chgParam set.
     809             :      */
     810     3836216 :     parmset = bms_intersect(node->plan->allParam, newchg);
     811             : 
     812             :     /*
     813             :      * Keep node->chgParam == NULL if there's not actually any members; this
     814             :      * allows the simplest possible tests in executor node files.
     815             :      */
     816     3836216 :     if (!bms_is_empty(parmset))
     817     3758506 :         node->chgParam = bms_join(node->chgParam, parmset);
     818             :     else
     819       77710 :         bms_free(parmset);
     820     3836216 : }
     821             : 
     822             : /*
     823             :  * executor_errposition
     824             :  *      Report an execution-time cursor position, if possible.
     825             :  *
     826             :  * This is expected to be used within an ereport() call.  The return value
     827             :  * is a dummy (always 0, in fact).
     828             :  *
     829             :  * The locations stored in parsetrees are byte offsets into the source string.
     830             :  * We have to convert them to 1-based character indexes for reporting to
     831             :  * clients.  (We do things this way to avoid unnecessary overhead in the
     832             :  * normal non-error case: computing character indexes would be much more
     833             :  * expensive than storing token offsets.)
     834             :  */
     835             : int
     836           0 : executor_errposition(EState *estate, int location)
     837             : {
     838             :     int         pos;
     839             : 
     840             :     /* No-op if location was not provided */
     841           0 :     if (location < 0)
     842           0 :         return 0;
     843             :     /* Can't do anything if source text is not available */
     844           0 :     if (estate == NULL || estate->es_sourceText == NULL)
     845           0 :         return 0;
     846             :     /* Convert offset to character number */
     847           0 :     pos = pg_mbstrlen_with_len(estate->es_sourceText, location) + 1;
     848             :     /* And pass it to the ereport mechanism */
     849           0 :     return errposition(pos);
     850             : }
     851             : 
     852             : /*
     853             :  * Register a shutdown callback in an ExprContext.
     854             :  *
     855             :  * Shutdown callbacks will be called (in reverse order of registration)
     856             :  * when the ExprContext is deleted or rescanned.  This provides a hook
     857             :  * for functions called in the context to do any cleanup needed --- it's
     858             :  * particularly useful for functions returning sets.  Note that the
     859             :  * callback will *not* be called in the event that execution is aborted
     860             :  * by an error.
     861             :  */
     862             : void
     863     1440682 : RegisterExprContextCallback(ExprContext *econtext,
     864             :                             ExprContextCallbackFunction function,
     865             :                             Datum arg)
     866             : {
     867             :     ExprContext_CB *ecxt_callback;
     868             : 
     869             :     /* Save the info in appropriate memory context */
     870     1440682 :     ecxt_callback = (ExprContext_CB *)
     871     1440682 :         MemoryContextAlloc(econtext->ecxt_per_query_memory,
     872             :                            sizeof(ExprContext_CB));
     873             : 
     874     1440682 :     ecxt_callback->function = function;
     875     1440682 :     ecxt_callback->arg = arg;
     876             : 
     877             :     /* link to front of list for appropriate execution order */
     878     1440682 :     ecxt_callback->next = econtext->ecxt_callbacks;
     879     1440682 :     econtext->ecxt_callbacks = ecxt_callback;
     880     1440682 : }
     881             : 
     882             : /*
     883             :  * Deregister a shutdown callback in an ExprContext.
     884             :  *
     885             :  * Any list entries matching the function and arg will be removed.
     886             :  * This can be used if it's no longer necessary to call the callback.
     887             :  */
     888             : void
     889     1393840 : UnregisterExprContextCallback(ExprContext *econtext,
     890             :                               ExprContextCallbackFunction function,
     891             :                               Datum arg)
     892             : {
     893             :     ExprContext_CB **prev_callback;
     894             :     ExprContext_CB *ecxt_callback;
     895             : 
     896     1393840 :     prev_callback = &econtext->ecxt_callbacks;
     897             : 
     898     4248644 :     while ((ecxt_callback = *prev_callback) != NULL)
     899             :     {
     900     1460964 :         if (ecxt_callback->function == function && ecxt_callback->arg == arg)
     901             :         {
     902     1393840 :             *prev_callback = ecxt_callback->next;
     903     1393840 :             pfree(ecxt_callback);
     904             :         }
     905             :         else
     906       67124 :             prev_callback = &ecxt_callback->next;
     907             :     }
     908     1393840 : }
     909             : 
     910             : /*
     911             :  * Call all the shutdown callbacks registered in an ExprContext.
     912             :  *
     913             :  * The callback list is emptied (important in case this is only a rescan
     914             :  * reset, and not deletion of the ExprContext).
     915             :  *
     916             :  * If isCommit is false, just clean the callback list but don't call 'em.
     917             :  * (See comment for FreeExprContext.)
     918             :  */
     919             : static void
     920     9924404 : ShutdownExprContext(ExprContext *econtext, bool isCommit)
     921             : {
     922             :     ExprContext_CB *ecxt_callback;
     923             :     MemoryContext oldcontext;
     924             : 
     925             :     /* Fast path in normal case where there's nothing to do. */
     926     9924404 :     if (econtext->ecxt_callbacks == NULL)
     927     9879344 :         return;
     928             : 
     929             :     /*
     930             :      * Call the callbacks in econtext's per-tuple context.  This ensures that
     931             :      * any memory they might leak will get cleaned up.
     932             :      */
     933       45060 :     oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
     934             : 
     935             :     /*
     936             :      * Call each callback function in reverse registration order.
     937             :      */
     938      136334 :     while ((ecxt_callback = econtext->ecxt_callbacks) != NULL)
     939             :     {
     940       46214 :         econtext->ecxt_callbacks = ecxt_callback->next;
     941       46214 :         if (isCommit)
     942       46214 :             ecxt_callback->function(ecxt_callback->arg);
     943       46214 :         pfree(ecxt_callback);
     944             :     }
     945             : 
     946       45060 :     MemoryContextSwitchTo(oldcontext);
     947             : }
     948             : 
     949             : /*
     950             :  *      GetAttributeByName
     951             :  *      GetAttributeByNum
     952             :  *
     953             :  *      These functions return the value of the requested attribute
     954             :  *      out of the given tuple Datum.
     955             :  *      C functions which take a tuple as an argument are expected
     956             :  *      to use these.  Ex: overpaid(EMP) might call GetAttributeByNum().
     957             :  *      Note: these are actually rather slow because they do a typcache
     958             :  *      lookup on each call.
     959             :  */
     960             : Datum
     961          24 : GetAttributeByName(HeapTupleHeader tuple, const char *attname, bool *isNull)
     962             : {
     963             :     AttrNumber  attrno;
     964             :     Datum       result;
     965             :     Oid         tupType;
     966             :     int32       tupTypmod;
     967             :     TupleDesc   tupDesc;
     968             :     HeapTupleData tmptup;
     969             :     int         i;
     970             : 
     971          24 :     if (attname == NULL)
     972           0 :         elog(ERROR, "invalid attribute name");
     973             : 
     974          24 :     if (isNull == NULL)
     975           0 :         elog(ERROR, "a NULL isNull pointer was passed");
     976             : 
     977          24 :     if (tuple == NULL)
     978             :     {
     979             :         /* Kinda bogus but compatible with old behavior... */
     980           0 :         *isNull = true;
     981           0 :         return (Datum) 0;
     982             :     }
     983             : 
     984          24 :     tupType = HeapTupleHeaderGetTypeId(tuple);
     985          24 :     tupTypmod = HeapTupleHeaderGetTypMod(tuple);
     986          24 :     tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
     987             : 
     988          24 :     attrno = InvalidAttrNumber;
     989          96 :     for (i = 0; i < tupDesc->natts; i++)
     990             :     {
     991          96 :         Form_pg_attribute att = TupleDescAttr(tupDesc, i);
     992             : 
     993          96 :         if (namestrcmp(&(att->attname), attname) == 0)
     994             :         {
     995          24 :             attrno = att->attnum;
     996          24 :             break;
     997             :         }
     998             :     }
     999             : 
    1000          24 :     if (attrno == InvalidAttrNumber)
    1001           0 :         elog(ERROR, "attribute \"%s\" does not exist", attname);
    1002             : 
    1003             :     /*
    1004             :      * heap_getattr needs a HeapTuple not a bare HeapTupleHeader.  We set all
    1005             :      * the fields in the struct just in case user tries to inspect system
    1006             :      * columns.
    1007             :      */
    1008          24 :     tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
    1009          24 :     ItemPointerSetInvalid(&(tmptup.t_self));
    1010          24 :     tmptup.t_tableOid = InvalidOid;
    1011          24 :     tmptup.t_data = tuple;
    1012             : 
    1013          24 :     result = heap_getattr(&tmptup,
    1014             :                           attrno,
    1015             :                           tupDesc,
    1016             :                           isNull);
    1017             : 
    1018          24 :     ReleaseTupleDesc(tupDesc);
    1019             : 
    1020          24 :     return result;
    1021             : }
    1022             : 
    1023             : Datum
    1024           0 : GetAttributeByNum(HeapTupleHeader tuple,
    1025             :                   AttrNumber attrno,
    1026             :                   bool *isNull)
    1027             : {
    1028             :     Datum       result;
    1029             :     Oid         tupType;
    1030             :     int32       tupTypmod;
    1031             :     TupleDesc   tupDesc;
    1032             :     HeapTupleData tmptup;
    1033             : 
    1034           0 :     if (!AttributeNumberIsValid(attrno))
    1035           0 :         elog(ERROR, "invalid attribute number %d", attrno);
    1036             : 
    1037           0 :     if (isNull == NULL)
    1038           0 :         elog(ERROR, "a NULL isNull pointer was passed");
    1039             : 
    1040           0 :     if (tuple == NULL)
    1041             :     {
    1042             :         /* Kinda bogus but compatible with old behavior... */
    1043           0 :         *isNull = true;
    1044           0 :         return (Datum) 0;
    1045             :     }
    1046             : 
    1047           0 :     tupType = HeapTupleHeaderGetTypeId(tuple);
    1048           0 :     tupTypmod = HeapTupleHeaderGetTypMod(tuple);
    1049           0 :     tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
    1050             : 
    1051             :     /*
    1052             :      * heap_getattr needs a HeapTuple not a bare HeapTupleHeader.  We set all
    1053             :      * the fields in the struct just in case user tries to inspect system
    1054             :      * columns.
    1055             :      */
    1056           0 :     tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
    1057           0 :     ItemPointerSetInvalid(&(tmptup.t_self));
    1058           0 :     tmptup.t_tableOid = InvalidOid;
    1059           0 :     tmptup.t_data = tuple;
    1060             : 
    1061           0 :     result = heap_getattr(&tmptup,
    1062             :                           attrno,
    1063             :                           tupDesc,
    1064             :                           isNull);
    1065             : 
    1066           0 :     ReleaseTupleDesc(tupDesc);
    1067             : 
    1068           0 :     return result;
    1069             : }
    1070             : 
    1071             : /*
    1072             :  * Number of items in a tlist (including any resjunk items!)
    1073             :  */
    1074             : int
    1075      748156 : ExecTargetListLength(List *targetlist)
    1076             : {
    1077             :     /* This used to be more complex, but fjoins are dead */
    1078      748156 :     return list_length(targetlist);
    1079             : }
    1080             : 
    1081             : /*
    1082             :  * Number of items in a tlist, not including any resjunk items
    1083             :  */
    1084             : int
    1085       90920 : ExecCleanTargetListLength(List *targetlist)
    1086             : {
    1087       90920 :     int         len = 0;
    1088             :     ListCell   *tl;
    1089             : 
    1090      342494 :     foreach(tl, targetlist)
    1091             :     {
    1092      251574 :         TargetEntry *curTle = lfirst_node(TargetEntry, tl);
    1093             : 
    1094      251574 :         if (!curTle->resjunk)
    1095      221544 :             len++;
    1096             :     }
    1097       90920 :     return len;
    1098             : }
    1099             : 
    1100             : /*
    1101             :  * Return a relInfo's tuple slot for a trigger's OLD tuples.
    1102             :  */
    1103             : TupleTableSlot *
    1104      958638 : ExecGetTriggerOldSlot(EState *estate, ResultRelInfo *relInfo)
    1105             : {
    1106      958638 :     if (relInfo->ri_TrigOldSlot == NULL)
    1107             :     {
    1108       14910 :         Relation    rel = relInfo->ri_RelationDesc;
    1109       14910 :         MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
    1110             : 
    1111       14910 :         relInfo->ri_TrigOldSlot =
    1112       14910 :             ExecInitExtraTupleSlot(estate,
    1113             :                                    RelationGetDescr(rel),
    1114             :                                    table_slot_callbacks(rel));
    1115             : 
    1116       14910 :         MemoryContextSwitchTo(oldcontext);
    1117             :     }
    1118             : 
    1119      958638 :     return relInfo->ri_TrigOldSlot;
    1120             : }
    1121             : 
    1122             : /*
    1123             :  * Return a relInfo's tuple slot for a trigger's NEW tuples.
    1124             :  */
    1125             : TupleTableSlot *
    1126        1654 : ExecGetTriggerNewSlot(EState *estate, ResultRelInfo *relInfo)
    1127             : {
    1128        1654 :     if (relInfo->ri_TrigNewSlot == NULL)
    1129             :     {
    1130         988 :         Relation    rel = relInfo->ri_RelationDesc;
    1131         988 :         MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
    1132             : 
    1133         988 :         relInfo->ri_TrigNewSlot =
    1134         988 :             ExecInitExtraTupleSlot(estate,
    1135             :                                    RelationGetDescr(rel),
    1136             :                                    table_slot_callbacks(rel));
    1137             : 
    1138         988 :         MemoryContextSwitchTo(oldcontext);
    1139             :     }
    1140             : 
    1141        1654 :     return relInfo->ri_TrigNewSlot;
    1142             : }
    1143             : 
    1144             : /*
    1145             :  * Return a relInfo's tuple slot for processing returning tuples.
    1146             :  */
    1147             : TupleTableSlot *
    1148         808 : ExecGetReturningSlot(EState *estate, ResultRelInfo *relInfo)
    1149             : {
    1150         808 :     if (relInfo->ri_ReturningSlot == NULL)
    1151             :     {
    1152         326 :         Relation    rel = relInfo->ri_RelationDesc;
    1153         326 :         MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
    1154             : 
    1155         326 :         relInfo->ri_ReturningSlot =
    1156         326 :             ExecInitExtraTupleSlot(estate,
    1157             :                                    RelationGetDescr(rel),
    1158             :                                    table_slot_callbacks(rel));
    1159             : 
    1160         326 :         MemoryContextSwitchTo(oldcontext);
    1161             :     }
    1162             : 
    1163         808 :     return relInfo->ri_ReturningSlot;
    1164             : }

Generated by: LCOV version 1.13