LCOV - differential code coverage report
Current view: top level - src/backend/executor - execProcnode.c (source / functions) Coverage Total Hit UBC GNC CBC DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 94.8 % 388 368 20 1 367 1
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 9 9 1 8
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (180,240] days: 100.0 % 4 4 1 3
Legend: Lines: hit not hit (240..) days: 94.8 % 384 364 20 364
Function coverage date bins:
(180,240] days: 100.0 % 1 1 1
(240..) days: 100.0 % 8 8 1 7

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * execProcnode.c
                                  4                 :  *   contains dispatch functions which call the appropriate "initialize",
                                  5                 :  *   "get a tuple", and "cleanup" routines for the given node type.
                                  6                 :  *   If the node has children, then it will presumably call ExecInitNode,
                                  7                 :  *   ExecProcNode, or ExecEndNode on its subnodes and do the appropriate
                                  8                 :  *   processing.
                                  9                 :  *
                                 10                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
                                 11                 :  * Portions Copyright (c) 1994, Regents of the University of California
                                 12                 :  *
                                 13                 :  *
                                 14                 :  * IDENTIFICATION
                                 15                 :  *    src/backend/executor/execProcnode.c
                                 16                 :  *
                                 17                 :  *-------------------------------------------------------------------------
                                 18                 :  */
                                 19                 : /*
                                 20                 :  *   NOTES
                                 21                 :  *      This used to be three files.  It is now all combined into
                                 22                 :  *      one file so that it is easier to keep the dispatch routines
                                 23                 :  *      in sync when new nodes are added.
                                 24                 :  *
                                 25                 :  *   EXAMPLE
                                 26                 :  *      Suppose we want the age of the manager of the shoe department and
                                 27                 :  *      the number of employees in that department.  So we have the query:
                                 28                 :  *
                                 29                 :  *              select DEPT.no_emps, EMP.age
                                 30                 :  *              from DEPT, EMP
                                 31                 :  *              where EMP.name = DEPT.mgr and
                                 32                 :  *                    DEPT.name = "shoe"
                                 33                 :  *
                                 34                 :  *      Suppose the planner gives us the following plan:
                                 35                 :  *
                                 36                 :  *                      Nest Loop (DEPT.mgr = EMP.name)
                                 37                 :  *                      /       \
                                 38                 :  *                     /         \
                                 39                 :  *                 Seq Scan     Seq Scan
                                 40                 :  *                  DEPT          EMP
                                 41                 :  *              (name = "shoe")
                                 42                 :  *
                                 43                 :  *      ExecutorStart() is called first.
                                 44                 :  *      It calls InitPlan() which calls ExecInitNode() on
                                 45                 :  *      the root of the plan -- the nest loop node.
                                 46                 :  *
                                 47                 :  *    * ExecInitNode() notices that it is looking at a nest loop and
                                 48                 :  *      as the code below demonstrates, it calls ExecInitNestLoop().
                                 49                 :  *      Eventually this calls ExecInitNode() on the right and left subplans
                                 50                 :  *      and so forth until the entire plan is initialized.  The result
                                 51                 :  *      of ExecInitNode() is a plan state tree built with the same structure
                                 52                 :  *      as the underlying plan tree.
                                 53                 :  *
                                 54                 :  *    * Then when ExecutorRun() is called, it calls ExecutePlan() which calls
                                 55                 :  *      ExecProcNode() repeatedly on the top node of the plan state tree.
                                 56                 :  *      Each time this happens, ExecProcNode() will end up calling
                                 57                 :  *      ExecNestLoop(), which calls ExecProcNode() on its subplans.
                                 58                 :  *      Each of these subplans is a sequential scan so ExecSeqScan() is
                                 59                 :  *      called.  The slots returned by ExecSeqScan() may contain
                                 60                 :  *      tuples which contain the attributes ExecNestLoop() uses to
                                 61                 :  *      form the tuples it returns.
                                 62                 :  *
                                 63                 :  *    * Eventually ExecSeqScan() stops returning tuples and the nest
                                 64                 :  *      loop join ends.  Lastly, ExecutorEnd() calls ExecEndNode() which
                                 65                 :  *      calls ExecEndNestLoop() which in turn calls ExecEndNode() on
                                 66                 :  *      its subplans which result in ExecEndSeqScan().
                                 67                 :  *
                                 68                 :  *      This should show how the executor works by having
                                 69                 :  *      ExecInitNode(), ExecProcNode() and ExecEndNode() dispatch
                                 70                 :  *      their work to the appropriate node support routines which may
                                 71                 :  *      in turn call these routines themselves on their subplans.
                                 72                 :  */
                                 73                 : #include "postgres.h"
                                 74                 : 
                                 75                 : #include "executor/executor.h"
                                 76                 : #include "executor/nodeAgg.h"
                                 77                 : #include "executor/nodeAppend.h"
                                 78                 : #include "executor/nodeBitmapAnd.h"
                                 79                 : #include "executor/nodeBitmapHeapscan.h"
                                 80                 : #include "executor/nodeBitmapIndexscan.h"
                                 81                 : #include "executor/nodeBitmapOr.h"
                                 82                 : #include "executor/nodeCtescan.h"
                                 83                 : #include "executor/nodeCustom.h"
                                 84                 : #include "executor/nodeForeignscan.h"
                                 85                 : #include "executor/nodeFunctionscan.h"
                                 86                 : #include "executor/nodeGather.h"
                                 87                 : #include "executor/nodeGatherMerge.h"
                                 88                 : #include "executor/nodeGroup.h"
                                 89                 : #include "executor/nodeHash.h"
                                 90                 : #include "executor/nodeHashjoin.h"
                                 91                 : #include "executor/nodeIncrementalSort.h"
                                 92                 : #include "executor/nodeIndexonlyscan.h"
                                 93                 : #include "executor/nodeIndexscan.h"
                                 94                 : #include "executor/nodeLimit.h"
                                 95                 : #include "executor/nodeLockRows.h"
                                 96                 : #include "executor/nodeMaterial.h"
                                 97                 : #include "executor/nodeMemoize.h"
                                 98                 : #include "executor/nodeMergeAppend.h"
                                 99                 : #include "executor/nodeMergejoin.h"
                                100                 : #include "executor/nodeModifyTable.h"
                                101                 : #include "executor/nodeNamedtuplestorescan.h"
                                102                 : #include "executor/nodeNestloop.h"
                                103                 : #include "executor/nodeProjectSet.h"
                                104                 : #include "executor/nodeRecursiveunion.h"
                                105                 : #include "executor/nodeResult.h"
                                106                 : #include "executor/nodeSamplescan.h"
                                107                 : #include "executor/nodeSeqscan.h"
                                108                 : #include "executor/nodeSetOp.h"
                                109                 : #include "executor/nodeSort.h"
                                110                 : #include "executor/nodeSubplan.h"
                                111                 : #include "executor/nodeSubqueryscan.h"
                                112                 : #include "executor/nodeTableFuncscan.h"
                                113                 : #include "executor/nodeTidrangescan.h"
                                114                 : #include "executor/nodeTidscan.h"
                                115                 : #include "executor/nodeUnique.h"
                                116                 : #include "executor/nodeValuesscan.h"
                                117                 : #include "executor/nodeWindowAgg.h"
                                118                 : #include "executor/nodeWorktablescan.h"
                                119                 : #include "miscadmin.h"
                                120                 : #include "nodes/nodeFuncs.h"
                                121                 : 
                                122                 : static TupleTableSlot *ExecProcNodeFirst(PlanState *node);
                                123                 : static TupleTableSlot *ExecProcNodeInstr(PlanState *node);
                                124                 : static bool ExecShutdownNode_walker(PlanState *node, void *context);
                                125                 : 
                                126                 : 
                                127                 : /* ------------------------------------------------------------------------
                                128                 :  *      ExecInitNode
                                129                 :  *
                                130                 :  *      Recursively initializes all the nodes in the plan tree rooted
                                131                 :  *      at 'node'.
                                132                 :  *
                                133                 :  *      Inputs:
                                134                 :  *        'node' is the current node of the plan produced by the query planner
                                135                 :  *        'estate' is the shared execution state for the plan tree
                                136                 :  *        'eflags' is a bitwise OR of flag bits described in executor.h
                                137                 :  *
                                138                 :  *      Returns a PlanState node corresponding to the given Plan node.
                                139                 :  * ------------------------------------------------------------------------
                                140                 :  */
                                141                 : PlanState *
 6249 tgl                       142 CBC      712398 : ExecInitNode(Plan *node, EState *estate, int eflags)
                                143                 : {
                                144                 :     PlanState  *result;
                                145                 :     List       *subps;
                                146                 :     ListCell   *l;
                                147                 : 
                                148                 :     /*
                                149                 :      * do nothing when we get to the end of a leaf on tree.
                                150                 :      */
 9345 bruce                     151          712398 :     if (node == NULL)
 7430 tgl                       152          143915 :         return NULL;
                                153                 : 
                                154                 :     /*
                                155                 :      * Make sure there's enough stack available. Need to check here, in
                                156                 :      * addition to ExecProcNode() (via ExecProcNodeFirst()), to ensure the
                                157                 :      * stack isn't overrun while initializing the node tree.
                                158                 :      */
 2092 andres                    159          568483 :     check_stack_depth();
                                160                 : 
 9345 bruce                     161          568483 :     switch (nodeTag(node))
                                162                 :     {
                                163                 :             /*
                                164                 :              * control nodes
                                165                 :              */
 9344                           166          147688 :         case T_Result:
 6249 tgl                       167          147688 :             result = (PlanState *) ExecInitResult((Result *) node,
                                168                 :                                                   estate, eflags);
 9344 bruce                     169          147653 :             break;
                                170                 : 
 2272 andres                    171            3505 :         case T_ProjectSet:
                                172            3505 :             result = (PlanState *) ExecInitProjectSet((ProjectSet *) node,
                                173                 :                                                       estate, eflags);
                                174            3503 :             break;
                                175                 : 
 4929 tgl                       176           65639 :         case T_ModifyTable:
                                177           65639 :             result = (PlanState *) ExecInitModifyTable((ModifyTable *) node,
                                178                 :                                                        estate, eflags);
                                179           65505 :             break;
                                180                 : 
 9344 bruce                     181            6518 :         case T_Append:
 6249 tgl                       182            6518 :             result = (PlanState *) ExecInitAppend((Append *) node,
                                183                 :                                                   estate, eflags);
 9344 bruce                     184            6518 :             break;
                                185                 : 
 4560 tgl                       186             207 :         case T_MergeAppend:
                                187             207 :             result = (PlanState *) ExecInitMergeAppend((MergeAppend *) node,
                                188                 :                                                        estate, eflags);
                                189             207 :             break;
                                190                 : 
 5300                           191             354 :         case T_RecursiveUnion:
                                192             354 :             result = (PlanState *) ExecInitRecursiveUnion((RecursiveUnion *) node,
                                193                 :                                                           estate, eflags);
                                194             354 :             break;
                                195                 : 
 6564                           196              38 :         case T_BitmapAnd:
 6249                           197              38 :             result = (PlanState *) ExecInitBitmapAnd((BitmapAnd *) node,
                                198                 :                                                      estate, eflags);
 6564                           199              38 :             break;
                                200                 : 
                                201             111 :         case T_BitmapOr:
 6249                           202             111 :             result = (PlanState *) ExecInitBitmapOr((BitmapOr *) node,
                                203                 :                                                     estate, eflags);
 6564                           204             111 :             break;
                                205                 : 
                                206                 :             /*
                                207                 :              * scan nodes
                                208                 :              */
 9344 bruce                     209           93562 :         case T_SeqScan:
 6249 tgl                       210           93562 :             result = (PlanState *) ExecInitSeqScan((SeqScan *) node,
                                211                 :                                                    estate, eflags);
 9344 bruce                     212           93556 :             break;
                                213                 : 
 2886 simon                     214             126 :         case T_SampleScan:
                                215             126 :             result = (PlanState *) ExecInitSampleScan((SampleScan *) node,
                                216                 :                                                       estate, eflags);
                                217             126 :             break;
                                218                 : 
 9344 bruce                     219           60051 :         case T_IndexScan:
 6249 tgl                       220           60051 :             result = (PlanState *) ExecInitIndexScan((IndexScan *) node,
                                221                 :                                                      estate, eflags);
 9344 bruce                     222           60051 :             break;
                                223                 : 
 4198 tgl                       224            6527 :         case T_IndexOnlyScan:
                                225            6527 :             result = (PlanState *) ExecInitIndexOnlyScan((IndexOnlyScan *) node,
                                226                 :                                                          estate, eflags);
                                227            6527 :             break;
                                228                 : 
 6564                           229           10774 :         case T_BitmapIndexScan:
 6249                           230           10774 :             result = (PlanState *) ExecInitBitmapIndexScan((BitmapIndexScan *) node,
                                231                 :                                                            estate, eflags);
 6564                           232           10774 :             break;
                                233                 : 
                                234           10598 :         case T_BitmapHeapScan:
 6249                           235           10598 :             result = (PlanState *) ExecInitBitmapHeapScan((BitmapHeapScan *) node,
                                236                 :                                                           estate, eflags);
 6564                           237           10598 :             break;
                                238                 : 
 8227                           239             359 :         case T_TidScan:
 6249                           240             359 :             result = (PlanState *) ExecInitTidScan((TidScan *) node,
                                241                 :                                                    estate, eflags);
 8227                           242             359 :             break;
                                243                 : 
  771 drowley                   244             101 :         case T_TidRangeScan:
                                245             101 :             result = (PlanState *) ExecInitTidRangeScan((TidRangeScan *) node,
                                246                 :                                                         estate, eflags);
                                247             101 :             break;
                                248                 : 
 8227 tgl                       249            4701 :         case T_SubqueryScan:
 6249                           250            4701 :             result = (PlanState *) ExecInitSubqueryScan((SubqueryScan *) node,
                                251                 :                                                         estate, eflags);
 8227                           252            4701 :             break;
                                253                 : 
 7637                           254           26789 :         case T_FunctionScan:
 6249                           255           26789 :             result = (PlanState *) ExecInitFunctionScan((FunctionScan *) node,
                                256                 :                                                         estate, eflags);
 7637                           257           26785 :             break;
                                258                 : 
 2223 alvherre                  259             108 :         case T_TableFuncScan:
                                260             108 :             result = (PlanState *) ExecInitTableFuncScan((TableFuncScan *) node,
                                261                 :                                                          estate, eflags);
                                262             108 :             break;
                                263                 : 
 6094 mail                      264            3958 :         case T_ValuesScan:
                                265            3958 :             result = (PlanState *) ExecInitValuesScan((ValuesScan *) node,
                                266                 :                                                       estate, eflags);
                                267            3958 :             break;
                                268                 : 
 5300 tgl                       269            1242 :         case T_CteScan:
                                270            1242 :             result = (PlanState *) ExecInitCteScan((CteScan *) node,
                                271                 :                                                    estate, eflags);
                                272            1242 :             break;
                                273                 : 
 2200 kgrittn                   274             330 :         case T_NamedTuplestoreScan:
                                275             330 :             result = (PlanState *) ExecInitNamedTuplestoreScan((NamedTuplestoreScan *) node,
                                276                 :                                                                estate, eflags);
                                277             330 :             break;
                                278                 : 
 5300 tgl                       279             354 :         case T_WorkTableScan:
                                280             354 :             result = (PlanState *) ExecInitWorkTableScan((WorkTableScan *) node,
                                281                 :                                                          estate, eflags);
                                282             354 :             break;
                                283                 : 
 4431                           284             951 :         case T_ForeignScan:
                                285             951 :             result = (PlanState *) ExecInitForeignScan((ForeignScan *) node,
                                286                 :                                                        estate, eflags);
                                287             943 :             break;
                                288                 : 
 3075 rhaas                     289 UBC           0 :         case T_CustomScan:
                                290               0 :             result = (PlanState *) ExecInitCustomScan((CustomScan *) node,
                                291                 :                                                       estate, eflags);
                                292               0 :             break;
                                293                 : 
                                294                 :             /*
                                295                 :              * join nodes
                                296                 :              */
 9344 bruce                     297 CBC       34215 :         case T_NestLoop:
 6249 tgl                       298           34215 :             result = (PlanState *) ExecInitNestLoop((NestLoop *) node,
                                299                 :                                                     estate, eflags);
 9344 bruce                     300           34215 :             break;
                                301                 : 
                                302            2325 :         case T_MergeJoin:
 6249 tgl                       303            2325 :             result = (PlanState *) ExecInitMergeJoin((MergeJoin *) node,
                                304                 :                                                      estate, eflags);
 8227                           305            2325 :             break;
                                306                 : 
                                307           14214 :         case T_HashJoin:
 6249                           308           14214 :             result = (PlanState *) ExecInitHashJoin((HashJoin *) node,
                                309                 :                                                     estate, eflags);
 8227                           310           14214 :             break;
                                311                 : 
                                312                 :             /*
                                313                 :              * materialization nodes
                                314                 :              */
 9344 bruce                     315            1826 :         case T_Material:
 6249 tgl                       316            1826 :             result = (PlanState *) ExecInitMaterial((Material *) node,
                                317                 :                                                     estate, eflags);
 9344 bruce                     318            1826 :             break;
                                319                 : 
                                320           26053 :         case T_Sort:
 6249 tgl                       321           26053 :             result = (PlanState *) ExecInitSort((Sort *) node,
                                322                 :                                                 estate, eflags);
 9344 bruce                     323           26050 :             break;
                                324                 : 
 1098 tomas.vondra              325             297 :         case T_IncrementalSort:
                                326             297 :             result = (PlanState *) ExecInitIncrementalSort((IncrementalSort *) node,
                                327                 :                                                            estate, eflags);
                                328             297 :             break;
                                329                 : 
  634 drowley                   330             508 :         case T_Memoize:
                                331             508 :             result = (PlanState *) ExecInitMemoize((Memoize *) node, estate,
                                332                 :                                                    eflags);
  737                           333             508 :             break;
                                334                 : 
 7430 tgl                       335             111 :         case T_Group:
 6249                           336             111 :             result = (PlanState *) ExecInitGroup((Group *) node,
                                337                 :                                                  estate, eflags);
 9344 bruce                     338             111 :             break;
                                339                 : 
 7430 tgl                       340           21244 :         case T_Agg:
 6249                           341           21244 :             result = (PlanState *) ExecInitAgg((Agg *) node,
                                342                 :                                                estate, eflags);
 8221                           343           21241 :             break;
                                344                 : 
 5215                           345            1089 :         case T_WindowAgg:
                                346            1089 :             result = (PlanState *) ExecInitWindowAgg((WindowAgg *) node,
                                347                 :                                                      estate, eflags);
                                348            1089 :             break;
                                349                 : 
 7430                           350             793 :         case T_Unique:
 6249                           351             793 :             result = (PlanState *) ExecInitUnique((Unique *) node,
                                352                 :                                                   estate, eflags);
 8200                           353             793 :             break;
                                354                 : 
 2748 rhaas                     355             479 :         case T_Gather:
                                356             479 :             result = (PlanState *) ExecInitGather((Gather *) node,
                                357                 :                                                   estate, eflags);
                                358             479 :             break;
                                359                 : 
 2222                           360             138 :         case T_GatherMerge:
                                361             138 :             result = (PlanState *) ExecInitGatherMerge((GatherMerge *) node,
                                362                 :                                                        estate, eflags);
                                363             138 :             break;
                                364                 : 
 7430 tgl                       365           14214 :         case T_Hash:
 6249                           366           14214 :             result = (PlanState *) ExecInitHash((Hash *) node,
                                367                 :                                                 estate, eflags);
 9344 bruce                     368           14214 :             break;
                                369                 : 
 7430 tgl                       370             303 :         case T_SetOp:
 6249                           371             303 :             result = (PlanState *) ExecInitSetOp((SetOp *) node,
                                372                 :                                                  estate, eflags);
 7430                           373             303 :             break;
                                374                 : 
 4927                           375            3511 :         case T_LockRows:
                                376            3511 :             result = (PlanState *) ExecInitLockRows((LockRows *) node,
                                377                 :                                                     estate, eflags);
                                378            3511 :             break;
                                379                 : 
 7430                           380            2572 :         case T_Limit:
 6249                           381            2572 :             result = (PlanState *) ExecInitLimit((Limit *) node,
                                382                 :                                                  estate, eflags);
 9344 bruce                     383            2572 :             break;
                                384                 : 
 9344 bruce                     385 UBC           0 :         default:
 7202 tgl                       386               0 :             elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
                                387                 :             result = NULL;      /* keep compiler quiet */
                                388                 :             break;
                                389                 :     }
                                390                 : 
 1943 andres                    391 CBC      568288 :     ExecSetExecProcNode(result, result->ExecProcNode);
                                392                 : 
                                393                 :     /*
                                394                 :      * Initialize any initPlans present in this node.  The planner put them in
                                395                 :      * a separate list for us.
                                396                 :      */
 7430 tgl                       397          568288 :     subps = NIL;
 6892 neilc                     398          577059 :     foreach(l, node->initPlan)
                                399                 :     {
                                400            8771 :         SubPlan    *subplan = (SubPlan *) lfirst(l);
                                401                 :         SubPlanState *sstate;
                                402                 : 
 7421 tgl                       403            8771 :         Assert(IsA(subplan, SubPlan));
 5885                           404            8771 :         sstate = ExecInitSubPlan(subplan, result);
 7422                           405            8771 :         subps = lappend(subps, sstate);
                                406                 :     }
 7430                           407          568288 :     result->initPlan = subps;
                                408                 : 
                                409                 :     /* Set up instrumentation for this node if requested */
                                410          568288 :     if (estate->es_instrument)
  697 efujita                   411            4934 :         result->instrument = InstrAlloc(1, estate->es_instrument,
                                412            4934 :                                         result->async_capable);
                                413                 : 
 9345 bruce                     414          568288 :     return result;
                                415                 : }
                                416                 : 
                                417                 : 
                                418                 : /*
                                419                 :  * If a node wants to change its ExecProcNode function after ExecInitNode()
                                420                 :  * has finished, it should do so with this function.  That way any wrapper
                                421                 :  * functions can be reinstalled, without the node having to know how that
                                422                 :  * works.
                                423                 :  */
                                424                 : void
 1943 andres                    425          568492 : ExecSetExecProcNode(PlanState *node, ExecProcNodeMtd function)
                                426                 : {
                                427                 :     /*
                                428                 :      * Add a wrapper around the ExecProcNode callback that checks stack depth
                                429                 :      * during the first execution and maybe adds an instrumentation wrapper.
                                430                 :      * When the callback is changed after execution has already begun that
                                431                 :      * means we'll superfluously execute ExecProcNodeFirst, but that seems ok.
                                432                 :      */
                                433          568492 :     node->ExecProcNodeReal = function;
                                434          568492 :     node->ExecProcNode = ExecProcNodeFirst;
                                435          568492 : }
                                436                 : 
                                437                 : 
                                438                 : /*
                                439                 :  * ExecProcNode wrapper that performs some one-time checks, before calling
                                440                 :  * the relevant node method (possibly via an instrumentation wrapper).
                                441                 :  */
                                442                 : static TupleTableSlot *
 2092                           443          490250 : ExecProcNodeFirst(PlanState *node)
                                444                 : {
                                445                 :     /*
                                446                 :      * Perform stack depth check during the first execution of the node.  We
                                447                 :      * only do so the first time round because it turns out to not be cheap on
                                448                 :      * some common architectures (eg. x86).  This relies on the assumption
                                449                 :      * that ExecProcNode calls for a given plan node will always be made at
                                450                 :      * roughly the same stack depth.
                                451                 :      */
                                452          490250 :     check_stack_depth();
                                453                 : 
                                454                 :     /*
                                455                 :      * If instrumentation is required, change the wrapper to one that just
                                456                 :      * does instrumentation.  Otherwise we can dispense with all wrappers and
                                457                 :      * have ExecProcNode() directly call the relevant function from now on.
                                458                 :      */
 7873 tgl                       459          490250 :     if (node->instrument)
 2092 andres                    460            3780 :         node->ExecProcNode = ExecProcNodeInstr;
                                461                 :     else
                                462          486470 :         node->ExecProcNode = node->ExecProcNodeReal;
                                463                 : 
                                464          490250 :     return node->ExecProcNode(node);
                                465                 : }
                                466                 : 
                                467                 : 
                                468                 : /*
                                469                 :  * ExecProcNode wrapper that performs instrumentation calls.  By keeping
                                470                 :  * this a separate function, we avoid overhead in the normal case where
                                471                 :  * no instrumentation is wanted.
                                472                 :  */
                                473                 : static TupleTableSlot *
                                474         6599964 : ExecProcNodeInstr(PlanState *node)
                                475                 : {
                                476                 :     TupleTableSlot *result;
                                477                 : 
                                478         6599964 :     InstrStartNode(node->instrument);
                                479                 : 
                                480         6599964 :     result = node->ExecProcNodeReal(node);
                                481                 : 
                                482         6599958 :     InstrStopNode(node->instrument, TupIsNull(result) ? 0.0 : 1.0);
                                483                 : 
 9345 bruce                     484         6599958 :     return result;
                                485                 : }
                                486                 : 
                                487                 : 
                                488                 : /* ----------------------------------------------------------------
                                489                 :  *      MultiExecProcNode
                                490                 :  *
                                491                 :  *      Execute a node that doesn't return individual tuples
                                492                 :  *      (it might return a hashtable, bitmap, etc).  Caller should
                                493                 :  *      check it got back the expected kind of Node.
                                494                 :  *
                                495                 :  * This has essentially the same responsibilities as ExecProcNode,
                                496                 :  * but it does not do InstrStartNode/InstrStopNode (mainly because
                                497                 :  * it can't tell how many returned tuples to count).  Each per-node
                                498                 :  * function must provide its own instrumentation support.
                                499                 :  * ----------------------------------------------------------------
                                500                 :  */
                                501                 : Node *
 6567 tgl                       502           18685 : MultiExecProcNode(PlanState *node)
                                503                 : {
                                504                 :     Node       *result;
                                505                 : 
 2092 andres                    506           18685 :     check_stack_depth();
                                507                 : 
 6567 tgl                       508           18685 :     CHECK_FOR_INTERRUPTS();
                                509                 : 
                                510           18685 :     if (node->chgParam != NULL) /* something changed */
 4654                           511            2157 :         ExecReScan(node);       /* let ReScan handle this */
                                512                 : 
 6567                           513           18685 :     switch (nodeTag(node))
                                514                 :     {
                                515                 :             /*
                                516                 :              * Only node types that actually support multiexec will be listed
                                517                 :              */
                                518                 : 
                                519            9886 :         case T_HashState:
                                520            9886 :             result = MultiExecHash((HashState *) node);
                                521            9886 :             break;
                                522                 : 
 6564                           523            8691 :         case T_BitmapIndexScanState:
                                524            8691 :             result = MultiExecBitmapIndexScan((BitmapIndexScanState *) node);
                                525            8691 :             break;
                                526                 : 
                                527              26 :         case T_BitmapAndState:
                                528              26 :             result = MultiExecBitmapAnd((BitmapAndState *) node);
                                529              26 :             break;
                                530                 : 
                                531              82 :         case T_BitmapOrState:
                                532              82 :             result = MultiExecBitmapOr((BitmapOrState *) node);
                                533              82 :             break;
                                534                 : 
 6567 tgl                       535 UBC           0 :         default:
                                536               0 :             elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
                                537                 :             result = NULL;
                                538                 :             break;
                                539                 :     }
                                540                 : 
 6567 tgl                       541 CBC       18685 :     return result;
                                542                 : }
                                543                 : 
                                544                 : 
                                545                 : /* ----------------------------------------------------------------
                                546                 :  *      ExecEndNode
                                547                 :  *
                                548                 :  *      Recursively cleans up all the nodes in the plan rooted
                                549                 :  *      at 'node'.
                                550                 :  *
                                551                 :  *      After this operation, the query plan will not be able to be
                                552                 :  *      processed any further.  This should be called only after
                                553                 :  *      the query plan has been fully executed.
                                554                 :  * ----------------------------------------------------------------
                                555                 :  */
                                556                 : void
 7184 bruce                     557          689750 : ExecEndNode(PlanState *node)
                                558                 : {
                                559                 :     /*
                                560                 :      * do nothing when we get to the end of a leaf on tree.
                                561                 :      */
 9345                           562          689750 :     if (node == NULL)
                                563          136181 :         return;
                                564                 : 
                                565                 :     /*
                                566                 :      * Make sure there's enough stack available. Need to check here, in
                                567                 :      * addition to ExecProcNode() (via ExecProcNodeFirst()), because it's not
                                568                 :      * guaranteed that ExecProcNode() is reached for all nodes.
                                569                 :      */
 2092 andres                    570          553569 :     check_stack_depth();
                                571                 : 
 7364 tgl                       572          553569 :     if (node->chgParam != NULL)
                                573                 :     {
                                574            2916 :         bms_free(node->chgParam);
                                575            2916 :         node->chgParam = NULL;
                                576                 :     }
                                577                 : 
 9345 bruce                     578          553569 :     switch (nodeTag(node))
                                579                 :     {
                                580                 :             /*
                                581                 :              * control nodes
                                582                 :              */
 7430 tgl                       583          139971 :         case T_ResultState:
                                584          139971 :             ExecEndResult((ResultState *) node);
 9344 bruce                     585          139971 :             break;
                                586                 : 
 2272 andres                    587            3197 :         case T_ProjectSetState:
                                588            3197 :             ExecEndProjectSet((ProjectSetState *) node);
                                589            3197 :             break;
                                590                 : 
 4929 tgl                       591           63676 :         case T_ModifyTableState:
                                592           63676 :             ExecEndModifyTable((ModifyTableState *) node);
                                593           63676 :             break;
                                594                 : 
 7430                           595            6379 :         case T_AppendState:
                                596            6379 :             ExecEndAppend((AppendState *) node);
 9344 bruce                     597            6379 :             break;
                                598                 : 
 4560 tgl                       599             207 :         case T_MergeAppendState:
                                600             207 :             ExecEndMergeAppend((MergeAppendState *) node);
                                601             207 :             break;
                                602                 : 
 5300                           603             354 :         case T_RecursiveUnionState:
                                604             354 :             ExecEndRecursiveUnion((RecursiveUnionState *) node);
                                605             354 :             break;
                                606                 : 
 6564                           607              38 :         case T_BitmapAndState:
                                608              38 :             ExecEndBitmapAnd((BitmapAndState *) node);
                                609              38 :             break;
                                610                 : 
                                611             111 :         case T_BitmapOrState:
                                612             111 :             ExecEndBitmapOr((BitmapOrState *) node);
                                613             111 :             break;
                                614                 : 
                                615                 :             /*
                                616                 :              * scan nodes
                                617                 :              */
 7430                           618           92457 :         case T_SeqScanState:
                                619           92457 :             ExecEndSeqScan((SeqScanState *) node);
 9344 bruce                     620           92457 :             break;
                                621                 : 
 2886 simon                     622             106 :         case T_SampleScanState:
                                623             106 :             ExecEndSampleScan((SampleScanState *) node);
                                624             106 :             break;
                                625                 : 
 2748 rhaas                     626             476 :         case T_GatherState:
                                627             476 :             ExecEndGather((GatherState *) node);
                                628             476 :             break;
                                629                 : 
 2222                           630             138 :         case T_GatherMergeState:
                                631             138 :             ExecEndGatherMerge((GatherMergeState *) node);
                                632             138 :             break;
                                633                 : 
 7430 tgl                       634           59728 :         case T_IndexScanState:
                                635           59728 :             ExecEndIndexScan((IndexScanState *) node);
 9344 bruce                     636           59728 :             break;
                                637                 : 
 4198 tgl                       638            6458 :         case T_IndexOnlyScanState:
                                639            6458 :             ExecEndIndexOnlyScan((IndexOnlyScanState *) node);
                                640            6458 :             break;
                                641                 : 
 6564                           642           10743 :         case T_BitmapIndexScanState:
                                643           10743 :             ExecEndBitmapIndexScan((BitmapIndexScanState *) node);
                                644           10743 :             break;
                                645                 : 
                                646           10567 :         case T_BitmapHeapScanState:
                                647           10567 :             ExecEndBitmapHeapScan((BitmapHeapScanState *) node);
                                648           10567 :             break;
                                649                 : 
 7430                           650             299 :         case T_TidScanState:
                                651             299 :             ExecEndTidScan((TidScanState *) node);
 8227                           652             299 :             break;
                                653                 : 
  771 drowley                   654             101 :         case T_TidRangeScanState:
                                655             101 :             ExecEndTidRangeScan((TidRangeScanState *) node);
                                656             101 :             break;
                                657                 : 
 7430 tgl                       658            4701 :         case T_SubqueryScanState:
                                659            4701 :             ExecEndSubqueryScan((SubqueryScanState *) node);
 8227                           660            4701 :             break;
                                661                 : 
 7430                           662           24172 :         case T_FunctionScanState:
                                663           24172 :             ExecEndFunctionScan((FunctionScanState *) node);
 7637                           664           24172 :             break;
                                665                 : 
 2223 alvherre                  666              99 :         case T_TableFuncScanState:
                                667              99 :             ExecEndTableFuncScan((TableFuncScanState *) node);
                                668              99 :             break;
                                669                 : 
 6094 mail                      670            3894 :         case T_ValuesScanState:
                                671            3894 :             ExecEndValuesScan((ValuesScanState *) node);
                                672            3894 :             break;
                                673                 : 
 5300 tgl                       674            1229 :         case T_CteScanState:
                                675            1229 :             ExecEndCteScan((CteScanState *) node);
                                676            1229 :             break;
                                677                 : 
 2200 kgrittn                   678             330 :         case T_NamedTuplestoreScanState:
                                679             330 :             ExecEndNamedTuplestoreScan((NamedTuplestoreScanState *) node);
                                680             330 :             break;
                                681                 : 
 5300 tgl                       682             354 :         case T_WorkTableScanState:
                                683             354 :             ExecEndWorkTableScan((WorkTableScanState *) node);
                                684             354 :             break;
                                685                 : 
 4431                           686             920 :         case T_ForeignScanState:
                                687             920 :             ExecEndForeignScan((ForeignScanState *) node);
                                688             920 :             break;
                                689                 : 
 3075 rhaas                     690 UBC           0 :         case T_CustomScanState:
                                691               0 :             ExecEndCustomScan((CustomScanState *) node);
                                692               0 :             break;
                                693                 : 
                                694                 :             /*
                                695                 :              * join nodes
                                696                 :              */
 7430 tgl                       697 CBC       34118 :         case T_NestLoopState:
                                698           34118 :             ExecEndNestLoop((NestLoopState *) node);
 9344 bruce                     699           34118 :             break;
                                700                 : 
 7430 tgl                       701            2322 :         case T_MergeJoinState:
                                702            2322 :             ExecEndMergeJoin((MergeJoinState *) node);
 8227                           703            2322 :             break;
                                704                 : 
 7430                           705           14172 :         case T_HashJoinState:
                                706           14172 :             ExecEndHashJoin((HashJoinState *) node);
 8227                           707           14172 :             break;
                                708                 : 
                                709                 :             /*
                                710                 :              * materialization nodes
                                711                 :              */
 7430                           712            1795 :         case T_MaterialState:
                                713            1795 :             ExecEndMaterial((MaterialState *) node);
 9344 bruce                     714            1795 :             break;
                                715                 : 
 7430 tgl                       716           26011 :         case T_SortState:
                                717           26011 :             ExecEndSort((SortState *) node);
 9344 bruce                     718           26011 :             break;
                                719                 : 
 1098 tomas.vondra              720             297 :         case T_IncrementalSortState:
                                721             297 :             ExecEndIncrementalSort((IncrementalSortState *) node);
                                722             297 :             break;
                                723                 : 
  634 drowley                   724             508 :         case T_MemoizeState:
                                725             508 :             ExecEndMemoize((MemoizeState *) node);
  737                           726             508 :             break;
                                727                 : 
 7430 tgl                       728             111 :         case T_GroupState:
                                729             111 :             ExecEndGroup((GroupState *) node);
 9344 bruce                     730             111 :             break;
                                731                 : 
 7430 tgl                       732           21188 :         case T_AggState:
                                733           21188 :             ExecEndAgg((AggState *) node);
 8221                           734           21188 :             break;
                                735                 : 
 5215                           736            1065 :         case T_WindowAggState:
                                737            1065 :             ExecEndWindowAgg((WindowAggState *) node);
                                738            1065 :             break;
                                739                 : 
 7430                           740             793 :         case T_UniqueState:
                                741             793 :             ExecEndUnique((UniqueState *) node);
 8200                           742             793 :             break;
                                743                 : 
 7430                           744           14172 :         case T_HashState:
                                745           14172 :             ExecEndHash((HashState *) node);
 9344 bruce                     746           14172 :             break;
                                747                 : 
 7430 tgl                       748             303 :         case T_SetOpState:
                                749             303 :             ExecEndSetOp((SetOpState *) node);
                                750             303 :             break;
                                751                 : 
 4927                           752            3468 :         case T_LockRowsState:
                                753            3468 :             ExecEndLockRows((LockRowsState *) node);
                                754            3468 :             break;
                                755                 : 
 7430                           756            2541 :         case T_LimitState:
                                757            2541 :             ExecEndLimit((LimitState *) node);
 9344 bruce                     758            2541 :             break;
                                759                 : 
 9344 bruce                     760 UBC           0 :         default:
 7202 tgl                       761               0 :             elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
                                762                 :             break;
                                763                 :     }
                                764                 : }
                                765                 : 
                                766                 : /*
                                767                 :  * ExecShutdownNode
                                768                 :  *
                                769                 :  * Give execution nodes a chance to stop asynchronous resource consumption
                                770                 :  * and release any resources still held.
                                771                 :  */
                                772                 : void
 2748 rhaas                     773 CBC      249029 : ExecShutdownNode(PlanState *node)
                                774                 : {
  202 tgl                       775 GNC      249029 :     (void) ExecShutdownNode_walker(node, NULL);
  202 tgl                       776 CBC      249029 : }
                                777                 : 
                                778                 : static bool
                                779          530185 : ExecShutdownNode_walker(PlanState *node, void *context)
                                780                 : {
 2748 rhaas                     781          530185 :     if (node == NULL)
 2748 rhaas                     782 UBC           0 :         return false;
                                783                 : 
 2092 andres                    784 CBC      530185 :     check_stack_depth();
                                785                 : 
                                786                 :     /*
                                787                 :      * Treat the node as running while we shut it down, but only if it's run
                                788                 :      * at least once already.  We don't expect much CPU consumption during
                                789                 :      * node shutdown, but in the case of Gather or Gather Merge, we may shut
                                790                 :      * down workers at this stage.  If so, their buffer usage will get
                                791                 :      * propagated into pgBufferUsage at this point, and we want to make sure
                                792                 :      * that it gets associated with the Gather node.  We skip this if the node
                                793                 :      * has never been executed, so as to avoid incorrectly making it appear
                                794                 :      * that it has.
                                795                 :      */
 1710 akapila                   796          530185 :     if (node->instrument && node->instrument->running)
                                797            4187 :         InstrStartNode(node->instrument);
                                798                 : 
  202 tgl                       799          530185 :     planstate_tree_walker(node, ExecShutdownNode_walker, context);
                                800                 : 
 2748 rhaas                     801          530185 :     switch (nodeTag(node))
                                802                 :     {
                                803             272 :         case T_GatherState:
 2726                           804             272 :             ExecShutdownGather((GatherState *) node);
 2748                           805             272 :             break;
 2233                           806             542 :         case T_ForeignScanState:
                                807             542 :             ExecShutdownForeignScan((ForeignScanState *) node);
                                808             542 :             break;
 2233 rhaas                     809 UBC           0 :         case T_CustomScanState:
                                810               0 :             ExecShutdownCustomScan((CustomScanState *) node);
                                811               0 :             break;
 2222 rhaas                     812 CBC          60 :         case T_GatherMergeState:
                                813              60 :             ExecShutdownGatherMerge((GatherMergeState *) node);
                                814              60 :             break;
 1951 andres                    815           12754 :         case T_HashState:
                                816           12754 :             ExecShutdownHash((HashState *) node);
                                817           12754 :             break;
 1936                           818           12754 :         case T_HashJoinState:
                                819           12754 :             ExecShutdownHashJoin((HashJoinState *) node);
                                820           12754 :             break;
 2748 rhaas                     821          503803 :         default:
                                822          503803 :             break;
                                823                 :     }
                                824                 : 
                                825                 :     /* Stop the node if we started it above, reporting 0 tuples. */
 1710 akapila                   826          530185 :     if (node->instrument && node->instrument->running)
                                827            4187 :         InstrStopNode(node->instrument, 0);
                                828                 : 
 2237 rhaas                     829          530185 :     return false;
                                830                 : }
                                831                 : 
                                832                 : /*
                                833                 :  * ExecSetTupleBound
                                834                 :  *
                                835                 :  * Set a tuple bound for a planstate node.  This lets child plan nodes
                                836                 :  * optimize based on the knowledge that the maximum number of tuples that
                                837                 :  * their parent will demand is limited.  The tuple bound for a node may
                                838                 :  * only be changed between scans (i.e., after node initialization or just
                                839                 :  * before an ExecReScan call).
                                840                 :  *
                                841                 :  * Any negative tuples_needed value means "no limit", which should be the
                                842                 :  * default assumption when this is not called at all for a particular node.
                                843                 :  *
                                844                 :  * Note: if this is called repeatedly on a plan tree, the exact same set
                                845                 :  * of nodes must be updated with the new limit each time; be careful that
                                846                 :  * only unchanging conditions are tested here.
                                847                 :  */
                                848                 : void
 2049                           849            3971 : ExecSetTupleBound(int64 tuples_needed, PlanState *child_node)
                                850                 : {
                                851                 :     /*
                                852                 :      * Since this function recurses, in principle we should check stack depth
                                853                 :      * here.  In practice, it's probably pointless since the earlier node
                                854                 :      * initialization tree traversal would surely have consumed more stack.
                                855                 :      */
                                856                 : 
                                857            3971 :     if (IsA(child_node, SortState))
                                858                 :     {
                                859                 :         /*
                                860                 :          * If it is a Sort node, notify it that it can use bounded sort.
                                861                 :          *
                                862                 :          * Note: it is the responsibility of nodeSort.c to react properly to
                                863                 :          * changes of these parameters.  If we ever redesign this, it'd be a
                                864                 :          * good idea to integrate this signaling with the parameter-change
                                865                 :          * mechanism.
                                866                 :          */
                                867             860 :         SortState  *sortState = (SortState *) child_node;
                                868                 : 
 1098 tomas.vondra              869             860 :         if (tuples_needed < 0)
                                870                 :         {
                                871                 :             /* make sure flag gets reset if needed upon rescan */
                                872             134 :             sortState->bounded = false;
                                873                 :         }
                                874                 :         else
                                875                 :         {
                                876             726 :             sortState->bounded = true;
                                877             726 :             sortState->bound = tuples_needed;
                                878                 :         }
                                879                 :     }
                                880            3111 :     else if (IsA(child_node, IncrementalSortState))
                                881                 :     {
                                882                 :         /*
                                883                 :          * If it is an IncrementalSort node, notify it that it can use bounded
                                884                 :          * sort.
                                885                 :          *
                                886                 :          * Note: it is the responsibility of nodeIncrementalSort.c to react
                                887                 :          * properly to changes of these parameters.  If we ever redesign this,
                                888                 :          * it'd be a good idea to integrate this signaling with the
                                889                 :          * parameter-change mechanism.
                                890                 :          */
                                891              73 :         IncrementalSortState *sortState = (IncrementalSortState *) child_node;
                                892                 : 
 2049 rhaas                     893              73 :         if (tuples_needed < 0)
                                894                 :         {
                                895                 :             /* make sure flag gets reset if needed upon rescan */
 2049 rhaas                     896 UBC           0 :             sortState->bounded = false;
                                897                 :         }
                                898                 :         else
                                899                 :         {
 2049 rhaas                     900 CBC          73 :             sortState->bounded = true;
                                901              73 :             sortState->bound = tuples_needed;
                                902                 :         }
                                903                 :     }
 1465 tgl                       904            3038 :     else if (IsA(child_node, AppendState))
                                905                 :     {
                                906                 :         /*
                                907                 :          * If it is an Append, we can apply the bound to any nodes that are
                                908                 :          * children of the Append, since the Append surely need read no more
                                909                 :          * than that many tuples from any one input.
                                910                 :          */
                                911              73 :         AppendState *aState = (AppendState *) child_node;
                                912                 :         int         i;
                                913                 : 
                                914             232 :         for (i = 0; i < aState->as_nplans; i++)
                                915             159 :             ExecSetTupleBound(tuples_needed, aState->appendplans[i]);
                                916                 :     }
 2049 rhaas                     917            2965 :     else if (IsA(child_node, MergeAppendState))
                                918                 :     {
                                919                 :         /*
                                920                 :          * If it is a MergeAppend, we can apply the bound to any nodes that
                                921                 :          * are children of the MergeAppend, since the MergeAppend surely need
                                922                 :          * read no more than that many tuples from any one input.
                                923                 :          */
                                924              30 :         MergeAppendState *maState = (MergeAppendState *) child_node;
                                925                 :         int         i;
                                926                 : 
                                927             120 :         for (i = 0; i < maState->ms_nplans; i++)
                                928              90 :             ExecSetTupleBound(tuples_needed, maState->mergeplans[i]);
                                929                 :     }
                                930            2935 :     else if (IsA(child_node, ResultState))
                                931                 :     {
                                932                 :         /*
                                933                 :          * Similarly, for a projecting Result, we can apply the bound to its
                                934                 :          * child node.
                                935                 :          *
                                936                 :          * If Result supported qual checking, we'd have to punt on seeing a
                                937                 :          * qual.  Note that having a resconstantqual is not a showstopper: if
                                938                 :          * that condition succeeds it affects nothing, while if it fails, no
                                939                 :          * rows will be demanded from the Result child anyway.
                                940                 :          */
                                941             377 :         if (outerPlanState(child_node))
                                942              51 :             ExecSetTupleBound(tuples_needed, outerPlanState(child_node));
                                943                 :     }
                                944            2558 :     else if (IsA(child_node, SubqueryScanState))
                                945                 :     {
                                946                 :         /*
                                947                 :          * We can also descend through SubqueryScan, but only if it has no
                                948                 :          * qual (otherwise it might discard rows).
                                949                 :          */
                                950              47 :         SubqueryScanState *subqueryState = (SubqueryScanState *) child_node;
                                951                 : 
                                952              47 :         if (subqueryState->ss.ps.qual == NULL)
                                953              36 :             ExecSetTupleBound(tuples_needed, subqueryState->subplan);
                                954                 :     }
                                955            2511 :     else if (IsA(child_node, GatherState))
                                956                 :     {
                                957                 :         /*
                                958                 :          * A Gather node can propagate the bound to its workers.  As with
                                959                 :          * MergeAppend, no one worker could possibly need to return more
                                960                 :          * tuples than the Gather itself needs to.
                                961                 :          *
                                962                 :          * Note: As with Sort, the Gather node is responsible for reacting
                                963                 :          * properly to changes to this parameter.
                                964                 :          */
 2049 rhaas                     965 UBC           0 :         GatherState *gstate = (GatherState *) child_node;
                                966                 : 
                                967               0 :         gstate->tuples_needed = tuples_needed;
                                968                 : 
                                969                 :         /* Also pass down the bound to our own copy of the child plan */
                                970               0 :         ExecSetTupleBound(tuples_needed, outerPlanState(child_node));
                                971                 :     }
 2049 rhaas                     972 CBC        2511 :     else if (IsA(child_node, GatherMergeState))
                                973                 :     {
                                974                 :         /* Same comments as for Gather */
                                975              15 :         GatherMergeState *gstate = (GatherMergeState *) child_node;
                                976                 : 
                                977              15 :         gstate->tuples_needed = tuples_needed;
                                978                 : 
                                979              15 :         ExecSetTupleBound(tuples_needed, outerPlanState(child_node));
                                980                 :     }
                                981                 : 
                                982                 :     /*
                                983                 :      * In principle we could descend through any plan node type that is
                                984                 :      * certain not to discard or combine input rows; but on seeing a node that
                                985                 :      * can do that, we can't propagate the bound any further.  For the moment
                                986                 :      * it's unclear that any other cases are worth checking here.
                                987                 :      */
                                988            3971 : }
        

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