LCOV - code coverage report
Current view: top level - src/backend/executor - nodeSubqueryscan.c (source / functions) Hit Total Coverage
Test: PostgreSQL Lines: 37 39 94.9 %
Date: 2017-09-29 15:12:54 Functions: 5 6 83.3 %
Legend: Lines: hit not hit

          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-2017, 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      125046 : SubqueryNext(SubqueryScanState *node)
      47             : {
      48             :     TupleTableSlot *slot;
      49             : 
      50             :     /*
      51             :      * Get the next tuple from the sub-query.
      52             :      */
      53      125046 :     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      125046 :     return slot;
      61             : }
      62             : 
      63             : /*
      64             :  * SubqueryRecheck -- access method routine to recheck a tuple in EvalPlanQual
      65             :  */
      66             : static bool
      67           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       94761 : ExecSubqueryScan(PlanState *pstate)
      84             : {
      85       94761 :     SubqueryScanState *node = castNode(SubqueryScanState, pstate);
      86             : 
      87       94761 :     return ExecScan(&node->ss,
      88             :                     (ExecScanAccessMtd) SubqueryNext,
      89             :                     (ExecScanRecheckMtd) SubqueryRecheck);
      90             : }
      91             : 
      92             : /* ----------------------------------------------------------------
      93             :  *      ExecInitSubqueryScan
      94             :  * ----------------------------------------------------------------
      95             :  */
      96             : SubqueryScanState *
      97         287 : ExecInitSubqueryScan(SubqueryScan *node, EState *estate, int eflags)
      98             : {
      99             :     SubqueryScanState *subquerystate;
     100             : 
     101             :     /* check for unsupported flags */
     102         287 :     Assert(!(eflags & EXEC_FLAG_MARK));
     103             : 
     104             :     /* SubqueryScan should not have any "normal" children */
     105         287 :     Assert(outerPlan(node) == NULL);
     106         287 :     Assert(innerPlan(node) == NULL);
     107             : 
     108             :     /*
     109             :      * create state structure
     110             :      */
     111         287 :     subquerystate = makeNode(SubqueryScanState);
     112         287 :     subquerystate->ss.ps.plan = (Plan *) node;
     113         287 :     subquerystate->ss.ps.state = estate;
     114         287 :     subquerystate->ss.ps.ExecProcNode = ExecSubqueryScan;
     115             : 
     116             :     /*
     117             :      * Miscellaneous initialization
     118             :      *
     119             :      * create expression context for node
     120             :      */
     121         287 :     ExecAssignExprContext(estate, &subquerystate->ss.ps);
     122             : 
     123             :     /*
     124             :      * initialize child expressions
     125             :      */
     126         287 :     subquerystate->ss.ps.qual =
     127         287 :         ExecInitQual(node->scan.plan.qual, (PlanState *) subquerystate);
     128             : 
     129             :     /*
     130             :      * tuple table initialization
     131             :      */
     132         287 :     ExecInitResultTupleSlot(estate, &subquerystate->ss.ps);
     133         287 :     ExecInitScanTupleSlot(estate, &subquerystate->ss);
     134             : 
     135             :     /*
     136             :      * initialize subquery
     137             :      */
     138         287 :     subquerystate->subplan = ExecInitNode(node->subplan, estate, eflags);
     139             : 
     140             :     /*
     141             :      * Initialize scan tuple type (needed by ExecAssignScanProjectionInfo)
     142             :      */
     143         287 :     ExecAssignScanType(&subquerystate->ss,
     144             :                        ExecGetResultType(subquerystate->subplan));
     145             : 
     146             :     /*
     147             :      * Initialize result tuple type and projection info.
     148             :      */
     149         287 :     ExecAssignResultTypeFromTL(&subquerystate->ss.ps);
     150         287 :     ExecAssignScanProjectionInfo(&subquerystate->ss);
     151             : 
     152         287 :     return subquerystate;
     153             : }
     154             : 
     155             : /* ----------------------------------------------------------------
     156             :  *      ExecEndSubqueryScan
     157             :  *
     158             :  *      frees any storage allocated through C routines.
     159             :  * ----------------------------------------------------------------
     160             :  */
     161             : void
     162         287 : ExecEndSubqueryScan(SubqueryScanState *node)
     163             : {
     164             :     /*
     165             :      * Free the exprcontext
     166             :      */
     167         287 :     ExecFreeExprContext(&node->ss.ps);
     168             : 
     169             :     /*
     170             :      * clean out the upper tuple table
     171             :      */
     172         287 :     ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
     173         287 :     ExecClearTuple(node->ss.ss_ScanTupleSlot);
     174             : 
     175             :     /*
     176             :      * close down subquery
     177             :      */
     178         287 :     ExecEndNode(node->subplan);
     179         287 : }
     180             : 
     181             : /* ----------------------------------------------------------------
     182             :  *      ExecReScanSubqueryScan
     183             :  *
     184             :  *      Rescans the relation.
     185             :  * ----------------------------------------------------------------
     186             :  */
     187             : void
     188          49 : ExecReScanSubqueryScan(SubqueryScanState *node)
     189             : {
     190          49 :     ExecScanReScan(&node->ss);
     191             : 
     192             :     /*
     193             :      * ExecReScan doesn't know about my subplan, so I have to do
     194             :      * changed-parameter signaling myself.  This is just as well, because the
     195             :      * subplan has its own memory context in which its chgParam state lives.
     196             :      */
     197          49 :     if (node->ss.ps.chgParam != NULL)
     198          44 :         UpdateChangedParamSet(node->subplan, node->ss.ps.chgParam);
     199             : 
     200             :     /*
     201             :      * if chgParam of subnode is not null then plan will be re-scanned by
     202             :      * first ExecProcNode.
     203             :      */
     204          49 :     if (node->subplan->chgParam == NULL)
     205          27 :         ExecReScan(node->subplan);
     206          49 : }

Generated by: LCOV version 1.11