LCOV - differential code coverage report
Current view: top level - src/backend/executor - nodeSubqueryscan.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 95.3 % 43 41 2 41
Current Date: 2023-04-08 15:15:32 Functions: 83.3 % 6 5 1 5
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /*-------------------------------------------------------------------------
       2                 :  *
       3                 :  * nodeSubqueryscan.c
       4                 :  *    Support routines for scanning subqueries (subselects in rangetable).
       5                 :  *
       6                 :  * This is just enough different from sublinks (nodeSubplan.c) to mean that
       7                 :  * we need two sets of code.  Ought to look at trying to unify the cases.
       8                 :  *
       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/nodeSubqueryscan.c
      16                 :  *
      17                 :  *-------------------------------------------------------------------------
      18                 :  */
      19                 : /*
      20                 :  * INTERFACE ROUTINES
      21                 :  *      ExecSubqueryScan            scans a subquery.
      22                 :  *      ExecSubqueryNext            retrieve next tuple in sequential order.
      23                 :  *      ExecInitSubqueryScan        creates and initializes a subqueryscan node.
      24                 :  *      ExecEndSubqueryScan         releases any storage allocated.
      25                 :  *      ExecReScanSubqueryScan      rescans the relation
      26                 :  *
      27                 :  */
      28                 : #include "postgres.h"
      29                 : 
      30                 : #include "executor/execdebug.h"
      31                 : #include "executor/nodeSubqueryscan.h"
      32                 : 
      33                 : static TupleTableSlot *SubqueryNext(SubqueryScanState *node);
      34                 : 
      35                 : /* ----------------------------------------------------------------
      36                 :  *                      Scan Support
      37                 :  * ----------------------------------------------------------------
      38                 :  */
      39                 : /* ----------------------------------------------------------------
      40                 :  *      SubqueryNext
      41                 :  *
      42                 :  *      This is a workhorse for ExecSubqueryScan
      43                 :  * ----------------------------------------------------------------
      44                 :  */
      45                 : static TupleTableSlot *
      46 CBC      872607 : SubqueryNext(SubqueryScanState *node)
      47                 : {
      48                 :     TupleTableSlot *slot;
      49                 : 
      50                 :     /*
      51                 :      * Get the next tuple from the sub-query.
      52                 :      */
      53          872607 :     slot = ExecProcNode(node->subplan);
      54                 : 
      55                 :     /*
      56                 :      * We just return the subplan's result slot, rather than expending extra
      57                 :      * cycles for ExecCopySlot().  (Our own ScanTupleSlot is used only for
      58                 :      * EvalPlanQual rechecks.)
      59                 :      */
      60          872607 :     return slot;
      61                 : }
      62                 : 
      63                 : /*
      64                 :  * SubqueryRecheck -- access method routine to recheck a tuple in EvalPlanQual
      65                 :  */
      66                 : static bool
      67 UBC           0 : SubqueryRecheck(SubqueryScanState *node, TupleTableSlot *slot)
      68                 : {
      69                 :     /* nothing to check */
      70               0 :     return true;
      71                 : }
      72                 : 
      73                 : /* ----------------------------------------------------------------
      74                 :  *      ExecSubqueryScan(node)
      75                 :  *
      76                 :  *      Scans the subquery sequentially and returns the next qualifying
      77                 :  *      tuple.
      78                 :  *      We call the ExecScan() routine and pass it the appropriate
      79                 :  *      access method functions.
      80                 :  * ----------------------------------------------------------------
      81                 :  */
      82                 : static TupleTableSlot *
      83 CBC      776947 : ExecSubqueryScan(PlanState *pstate)
      84                 : {
      85          776947 :     SubqueryScanState *node = castNode(SubqueryScanState, pstate);
      86                 : 
      87          776947 :     return ExecScan(&node->ss,
      88                 :                     (ExecScanAccessMtd) SubqueryNext,
      89                 :                     (ExecScanRecheckMtd) SubqueryRecheck);
      90                 : }
      91                 : 
      92                 : /* ----------------------------------------------------------------
      93                 :  *      ExecInitSubqueryScan
      94                 :  * ----------------------------------------------------------------
      95                 :  */
      96                 : SubqueryScanState *
      97            4701 : ExecInitSubqueryScan(SubqueryScan *node, EState *estate, int eflags)
      98                 : {
      99                 :     SubqueryScanState *subquerystate;
     100                 : 
     101                 :     /* check for unsupported flags */
     102            4701 :     Assert(!(eflags & EXEC_FLAG_MARK));
     103                 : 
     104                 :     /* SubqueryScan should not have any "normal" children */
     105            4701 :     Assert(outerPlan(node) == NULL);
     106            4701 :     Assert(innerPlan(node) == NULL);
     107                 : 
     108                 :     /*
     109                 :      * create state structure
     110                 :      */
     111            4701 :     subquerystate = makeNode(SubqueryScanState);
     112            4701 :     subquerystate->ss.ps.plan = (Plan *) node;
     113            4701 :     subquerystate->ss.ps.state = estate;
     114            4701 :     subquerystate->ss.ps.ExecProcNode = ExecSubqueryScan;
     115                 : 
     116                 :     /*
     117                 :      * Miscellaneous initialization
     118                 :      *
     119                 :      * create expression context for node
     120                 :      */
     121            4701 :     ExecAssignExprContext(estate, &subquerystate->ss.ps);
     122                 : 
     123                 :     /*
     124                 :      * initialize subquery
     125                 :      */
     126            4701 :     subquerystate->subplan = ExecInitNode(node->subplan, estate, eflags);
     127                 : 
     128                 :     /*
     129                 :      * Initialize scan slot and type (needed by ExecAssignScanProjectionInfo)
     130                 :      */
     131            4701 :     ExecInitScanTupleSlot(estate, &subquerystate->ss,
     132                 :                           ExecGetResultType(subquerystate->subplan),
     133                 :                           ExecGetResultSlotOps(subquerystate->subplan, NULL));
     134                 : 
     135                 :     /*
     136                 :      * The slot used as the scantuple isn't the slot above (outside of EPQ),
     137                 :      * but the one from the node below.
     138                 :      */
     139            4701 :     subquerystate->ss.ps.scanopsset = true;
     140            4701 :     subquerystate->ss.ps.scanops = ExecGetResultSlotOps(subquerystate->subplan,
     141                 :                                                         &subquerystate->ss.ps.scanopsfixed);
     142            4701 :     subquerystate->ss.ps.resultopsset = true;
     143            4701 :     subquerystate->ss.ps.resultops = subquerystate->ss.ps.scanops;
     144            4701 :     subquerystate->ss.ps.resultopsfixed = subquerystate->ss.ps.scanopsfixed;
     145                 : 
     146                 :     /*
     147                 :      * Initialize result type and projection.
     148                 :      */
     149            4701 :     ExecInitResultTypeTL(&subquerystate->ss.ps);
     150            4701 :     ExecAssignScanProjectionInfo(&subquerystate->ss);
     151                 : 
     152                 :     /*
     153                 :      * initialize child expressions
     154                 :      */
     155            4701 :     subquerystate->ss.ps.qual =
     156            4701 :         ExecInitQual(node->scan.plan.qual, (PlanState *) subquerystate);
     157                 : 
     158            4701 :     return subquerystate;
     159                 : }
     160                 : 
     161                 : /* ----------------------------------------------------------------
     162                 :  *      ExecEndSubqueryScan
     163                 :  *
     164                 :  *      frees any storage allocated through C routines.
     165                 :  * ----------------------------------------------------------------
     166                 :  */
     167                 : void
     168            4701 : ExecEndSubqueryScan(SubqueryScanState *node)
     169                 : {
     170                 :     /*
     171                 :      * Free the exprcontext
     172                 :      */
     173            4701 :     ExecFreeExprContext(&node->ss.ps);
     174                 : 
     175                 :     /*
     176                 :      * clean out the upper tuple table
     177                 :      */
     178            4701 :     if (node->ss.ps.ps_ResultTupleSlot)
     179            4482 :         ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
     180            4701 :     ExecClearTuple(node->ss.ss_ScanTupleSlot);
     181                 : 
     182                 :     /*
     183                 :      * close down subquery
     184                 :      */
     185            4701 :     ExecEndNode(node->subplan);
     186            4701 : }
     187                 : 
     188                 : /* ----------------------------------------------------------------
     189                 :  *      ExecReScanSubqueryScan
     190                 :  *
     191                 :  *      Rescans the relation.
     192                 :  * ----------------------------------------------------------------
     193                 :  */
     194                 : void
     195            1081 : ExecReScanSubqueryScan(SubqueryScanState *node)
     196                 : {
     197            1081 :     ExecScanReScan(&node->ss);
     198                 : 
     199                 :     /*
     200                 :      * ExecReScan doesn't know about my subplan, so I have to do
     201                 :      * changed-parameter signaling myself.  This is just as well, because the
     202                 :      * subplan has its own memory context in which its chgParam state lives.
     203                 :      */
     204            1081 :     if (node->ss.ps.chgParam != NULL)
     205            1074 :         UpdateChangedParamSet(node->subplan, node->ss.ps.chgParam);
     206                 : 
     207                 :     /*
     208                 :      * if chgParam of subnode is not null then plan will be re-scanned by
     209                 :      * first ExecProcNode.
     210                 :      */
     211            1081 :     if (node->subplan->chgParam == NULL)
     212              34 :         ExecReScan(node->subplan);
     213            1081 : }
        

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