LCOV - differential code coverage report
Current view: top level - src/backend/executor - nodeWorktablescan.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 96.2 % 52 50 2 50
Current Date: 2023-04-08 17:13:01 Functions: 83.3 % 6 5 1 5
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (240..) days: 96.2 % 52 50 2 50
Legend: Lines: hit not hit Function coverage date bins:
(240..) days: 83.3 % 6 5 1 5

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * nodeWorktablescan.c
                                  4                 :  *    routines to handle WorkTableScan nodes.
                                  5                 :  *
                                  6                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
                                  7                 :  * Portions Copyright (c) 1994, Regents of the University of California
                                  8                 :  *
                                  9                 :  *
                                 10                 :  * IDENTIFICATION
                                 11                 :  *    src/backend/executor/nodeWorktablescan.c
                                 12                 :  *
                                 13                 :  *-------------------------------------------------------------------------
                                 14                 :  */
                                 15                 : 
                                 16                 : #include "postgres.h"
                                 17                 : 
                                 18                 : #include "executor/execdebug.h"
                                 19                 : #include "executor/nodeWorktablescan.h"
                                 20                 : 
                                 21                 : static TupleTableSlot *WorkTableScanNext(WorkTableScanState *node);
                                 22                 : 
                                 23                 : /* ----------------------------------------------------------------
                                 24                 :  *      WorkTableScanNext
                                 25                 :  *
                                 26                 :  *      This is a workhorse for ExecWorkTableScan
                                 27                 :  * ----------------------------------------------------------------
                                 28                 :  */
                                 29                 : static TupleTableSlot *
 5300 tgl                        30 CBC       21134 : WorkTableScanNext(WorkTableScanState *node)
                                 31                 : {
                                 32                 :     TupleTableSlot *slot;
                                 33                 :     Tuplestorestate *tuplestorestate;
                                 34                 : 
                                 35                 :     /*
                                 36                 :      * get information from the estate and scan state
                                 37                 :      *
                                 38                 :      * Note: we intentionally do not support backward scan.  Although it would
                                 39                 :      * take only a couple more lines here, it would force nodeRecursiveunion.c
                                 40                 :      * to create the tuplestore with backward scan enabled, which has a
                                 41                 :      * performance cost.  In practice backward scan is never useful for a
                                 42                 :      * worktable plan node, since it cannot appear high enough in the plan
                                 43                 :      * tree of a scrollable cursor to be exposed to a backward-scan
                                 44                 :      * requirement.  So it's not worth expending effort to support it.
                                 45                 :      *
                                 46                 :      * Note: we are also assuming that this node is the only reader of the
                                 47                 :      * worktable.  Therefore, we don't need a private read pointer for the
                                 48                 :      * tuplestore, nor do we need to tell tuplestore_gettupleslot to copy.
                                 49                 :      */
 4036 peter_e                    50           21134 :     Assert(ScanDirectionIsForward(node->ss.ps.state->es_direction));
                                 51                 : 
 5300 tgl                        52           21134 :     tuplestorestate = node->rustate->working_table;
                                 53                 : 
                                 54                 :     /*
                                 55                 :      * Get the next tuple from tuplestore. Return NULL if no more tuples.
                                 56                 :      */
                                 57           21134 :     slot = node->ss.ss_ScanTupleSlot;
 5126                            58           21134 :     (void) tuplestore_gettupleslot(tuplestorestate, true, false, slot);
 5300                            59           21134 :     return slot;
                                 60                 : }
                                 61                 : 
                                 62                 : /*
                                 63                 :  * WorkTableScanRecheck -- access method routine to recheck a tuple in EvalPlanQual
                                 64                 :  */
                                 65                 : static bool
 4913 tgl                        66 UBC           0 : WorkTableScanRecheck(WorkTableScanState *node, TupleTableSlot *slot)
                                 67                 : {
                                 68                 :     /* nothing to check */
                                 69               0 :     return true;
                                 70                 : }
                                 71                 : 
                                 72                 : /* ----------------------------------------------------------------
                                 73                 :  *      ExecWorkTableScan(node)
                                 74                 :  *
                                 75                 :  *      Scans the worktable sequentially and returns the next qualifying tuple.
                                 76                 :  *      We call the ExecScan() routine and pass it the appropriate
                                 77                 :  *      access method functions.
                                 78                 :  * ----------------------------------------------------------------
                                 79                 :  */
                                 80                 : static TupleTableSlot *
 2092 andres                     81 CBC       14127 : ExecWorkTableScan(PlanState *pstate)
                                 82                 : {
                                 83           14127 :     WorkTableScanState *node = castNode(WorkTableScanState, pstate);
                                 84                 : 
                                 85                 :     /*
                                 86                 :      * On the first call, find the ancestor RecursiveUnion's state via the
                                 87                 :      * Param slot reserved for it.  (We can't do this during node init because
                                 88                 :      * there are corner cases where we'll get the init call before the
                                 89                 :      * RecursiveUnion does.)
                                 90                 :      */
 5291 tgl                        91           14127 :     if (node->rustate == NULL)
                                 92                 :     {
                                 93             327 :         WorkTableScan *plan = (WorkTableScan *) node->ss.ps.plan;
                                 94             327 :         EState     *estate = node->ss.ps.state;
                                 95                 :         ParamExecData *param;
                                 96                 : 
                                 97             327 :         param = &(estate->es_param_exec_vals[plan->wtParam]);
                                 98             327 :         Assert(param->execPlan == NULL);
                                 99             327 :         Assert(!param->isnull);
 2264 andres                    100             327 :         node->rustate = castNode(RecursiveUnionState, DatumGetPointer(param->value));
                                101             327 :         Assert(node->rustate);
                                102                 : 
                                103                 :         /*
                                104                 :          * The scan tuple type (ie, the rowtype we expect to find in the work
                                105                 :          * table) is the same as the result rowtype of the ancestor
                                106                 :          * RecursiveUnion node.  Note this depends on the assumption that
                                107                 :          * RecursiveUnion doesn't allow projection.
                                108                 :          */
 5291 tgl                       109             327 :         ExecAssignScanType(&node->ss,
                                110             327 :                            ExecGetResultType(&node->rustate->ps));
                                111                 : 
                                112                 :         /*
                                113                 :          * Now we can initialize the projection info.  This must be completed
                                114                 :          * before we can call ExecScan().
                                115                 :          */
                                116             327 :         ExecAssignScanProjectionInfo(&node->ss);
                                117                 :     }
                                118                 : 
 4913                           119           14127 :     return ExecScan(&node->ss,
                                120                 :                     (ExecScanAccessMtd) WorkTableScanNext,
                                121                 :                     (ExecScanRecheckMtd) WorkTableScanRecheck);
                                122                 : }
                                123                 : 
                                124                 : 
                                125                 : /* ----------------------------------------------------------------
                                126                 :  *      ExecInitWorkTableScan
                                127                 :  * ----------------------------------------------------------------
                                128                 :  */
                                129                 : WorkTableScanState *
 5300                           130             354 : ExecInitWorkTableScan(WorkTableScan *node, EState *estate, int eflags)
                                131                 : {
                                132                 :     WorkTableScanState *scanstate;
                                133                 : 
                                134                 :     /* check for unsupported flags */
 5276                           135             354 :     Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
                                136                 : 
                                137                 :     /*
                                138                 :      * WorkTableScan should not have any children.
                                139                 :      */
 5300                           140             354 :     Assert(outerPlan(node) == NULL);
                                141             354 :     Assert(innerPlan(node) == NULL);
                                142                 : 
                                143                 :     /*
                                144                 :      * create new WorkTableScanState for node
                                145                 :      */
                                146             354 :     scanstate = makeNode(WorkTableScanState);
                                147             354 :     scanstate->ss.ps.plan = (Plan *) node;
                                148             354 :     scanstate->ss.ps.state = estate;
 2092 andres                    149             354 :     scanstate->ss.ps.ExecProcNode = ExecWorkTableScan;
 5291 tgl                       150             354 :     scanstate->rustate = NULL;   /* we'll set this later */
                                151                 : 
                                152                 :     /*
                                153                 :      * Miscellaneous initialization
                                154                 :      *
                                155                 :      * create expression context for node
                                156                 :      */
 5300                           157             354 :     ExecAssignExprContext(estate, &scanstate->ss.ps);
                                158                 : 
                                159                 :     /*
                                160                 :      * tuple table initialization
                                161                 :      */
 1612 andres                    162             354 :     ExecInitResultTypeTL(&scanstate->ss.ps);
                                163                 : 
                                164                 :     /* signal that return type is not yet known */
 1606                           165             354 :     scanstate->ss.ps.resultopsset = true;
                                166             354 :     scanstate->ss.ps.resultopsfixed = false;
                                167                 : 
                                168             354 :     ExecInitScanTupleSlot(estate, &scanstate->ss, NULL, &TTSOpsMinimalTuple);
                                169                 : 
                                170                 :     /*
                                171                 :      * initialize child expressions
                                172                 :      */
 1878                           173             354 :     scanstate->ss.ps.qual =
                                174             354 :         ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
                                175                 : 
                                176                 :     /*
                                177                 :      * Do not yet initialize projection info, see ExecWorkTableScan() for
                                178                 :      * details.
                                179                 :      */
                                180                 : 
 5300 tgl                       181             354 :     return scanstate;
                                182                 : }
                                183                 : 
                                184                 : /* ----------------------------------------------------------------
                                185                 :  *      ExecEndWorkTableScan
                                186                 :  *
                                187                 :  *      frees any storage allocated through C routines.
                                188                 :  * ----------------------------------------------------------------
                                189                 :  */
                                190                 : void
                                191             354 : ExecEndWorkTableScan(WorkTableScanState *node)
                                192                 : {
                                193                 :     /*
                                194                 :      * Free exprcontext
                                195                 :      */
                                196             354 :     ExecFreeExprContext(&node->ss.ps);
                                197                 : 
                                198                 :     /*
                                199                 :      * clean out the tuple table
                                200                 :      */
 1612 andres                    201             354 :     if (node->ss.ps.ps_ResultTupleSlot)
                                202             258 :         ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
 5300 tgl                       203             354 :     ExecClearTuple(node->ss.ss_ScanTupleSlot);
                                204             354 : }
                                205                 : 
                                206                 : /* ----------------------------------------------------------------
                                207                 :  *      ExecReScanWorkTableScan
                                208                 :  *
                                209                 :  *      Rescans the relation.
                                210                 :  * ----------------------------------------------------------------
                                211                 :  */
                                212                 : void
 4654                           213            3104 : ExecReScanWorkTableScan(WorkTableScanState *node)
                                214                 : {
 1612 andres                    215            3104 :     if (node->ss.ps.ps_ResultTupleSlot)
                                216            2942 :         ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
                                217                 : 
 4913 tgl                       218            3104 :     ExecScanReScan(&node->ss);
                                219                 : 
                                220                 :     /* No need (or way) to rescan if ExecWorkTableScan not called yet */
 5291                           221            3104 :     if (node->rustate)
                                222            3101 :         tuplestore_rescan(node->rustate->working_table);
 5300                           223            3104 : }
        

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