LCOV - code coverage report
Current view: top level - src/backend/executor - nodeNamedtuplestorescan.c (source / functions) Hit Total Coverage
Test: PostgreSQL Lines: 38 48 79.2 %
Date: 2017-09-29 15:12:54 Functions: 4 6 66.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * nodeNamedtuplestorescan.c
       4             :  *    routines to handle NamedTuplestoreScan nodes.
       5             :  *
       6             :  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
       7             :  * Portions Copyright (c) 1994, Regents of the University of California
       8             :  *
       9             :  *
      10             :  * IDENTIFICATION
      11             :  *    src/backend/executor/nodeNamedtuplestorescan.c
      12             :  *
      13             :  *-------------------------------------------------------------------------
      14             :  */
      15             : 
      16             : #include "postgres.h"
      17             : 
      18             : #include "executor/execdebug.h"
      19             : #include "executor/nodeNamedtuplestorescan.h"
      20             : #include "miscadmin.h"
      21             : #include "utils/queryenvironment.h"
      22             : 
      23             : static TupleTableSlot *NamedTuplestoreScanNext(NamedTuplestoreScanState *node);
      24             : 
      25             : /* ----------------------------------------------------------------
      26             :  *      NamedTuplestoreScanNext
      27             :  *
      28             :  *      This is a workhorse for ExecNamedTuplestoreScan
      29             :  * ----------------------------------------------------------------
      30             :  */
      31             : static TupleTableSlot *
      32       10944 : NamedTuplestoreScanNext(NamedTuplestoreScanState *node)
      33             : {
      34             :     TupleTableSlot *slot;
      35             : 
      36             :     /* We intentionally do not support backward scan. */
      37       10944 :     Assert(ScanDirectionIsForward(node->ss.ps.state->es_direction));
      38             : 
      39             :     /*
      40             :      * Get the next tuple from tuplestore. Return NULL if no more tuples.
      41             :      */
      42       10944 :     slot = node->ss.ss_ScanTupleSlot;
      43       10944 :     (void) tuplestore_gettupleslot(node->relation, true, false, slot);
      44       10944 :     return slot;
      45             : }
      46             : 
      47             : /*
      48             :  * NamedTuplestoreScanRecheck -- access method routine to recheck a tuple in
      49             :  * EvalPlanQual
      50             :  */
      51             : static bool
      52           0 : NamedTuplestoreScanRecheck(NamedTuplestoreScanState *node, TupleTableSlot *slot)
      53             : {
      54             :     /* nothing to check */
      55           0 :     return true;
      56             : }
      57             : 
      58             : /* ----------------------------------------------------------------
      59             :  *      ExecNamedTuplestoreScan(node)
      60             :  *
      61             :  *      Scans the CTE sequentially and returns the next qualifying tuple.
      62             :  *      We call the ExecScan() routine and pass it the appropriate
      63             :  *      access method functions.
      64             :  * ----------------------------------------------------------------
      65             :  */
      66             : static TupleTableSlot *
      67       10944 : ExecNamedTuplestoreScan(PlanState *pstate)
      68             : {
      69       10944 :     NamedTuplestoreScanState *node = castNode(NamedTuplestoreScanState, pstate);
      70             : 
      71       10944 :     return ExecScan(&node->ss,
      72             :                     (ExecScanAccessMtd) NamedTuplestoreScanNext,
      73             :                     (ExecScanRecheckMtd) NamedTuplestoreScanRecheck);
      74             : }
      75             : 
      76             : 
      77             : /* ----------------------------------------------------------------
      78             :  *      ExecInitNamedTuplestoreScan
      79             :  * ----------------------------------------------------------------
      80             :  */
      81             : NamedTuplestoreScanState *
      82          59 : ExecInitNamedTuplestoreScan(NamedTuplestoreScan *node, EState *estate, int eflags)
      83             : {
      84             :     NamedTuplestoreScanState *scanstate;
      85             :     EphemeralNamedRelation enr;
      86             : 
      87             :     /* check for unsupported flags */
      88          59 :     Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
      89             : 
      90             :     /*
      91             :      * NamedTuplestoreScan should not have any children.
      92             :      */
      93          59 :     Assert(outerPlan(node) == NULL);
      94          59 :     Assert(innerPlan(node) == NULL);
      95             : 
      96             :     /*
      97             :      * create new NamedTuplestoreScanState for node
      98             :      */
      99          59 :     scanstate = makeNode(NamedTuplestoreScanState);
     100          59 :     scanstate->ss.ps.plan = (Plan *) node;
     101          59 :     scanstate->ss.ps.state = estate;
     102          59 :     scanstate->ss.ps.ExecProcNode = ExecNamedTuplestoreScan;
     103             : 
     104          59 :     enr = get_ENR(estate->es_queryEnv, node->enrname);
     105          59 :     if (!enr)
     106           0 :         elog(ERROR, "executor could not find named tuplestore \"%s\"",
     107             :              node->enrname);
     108             : 
     109          59 :     Assert(enr->reldata);
     110          59 :     scanstate->relation = (Tuplestorestate *) enr->reldata;
     111          59 :     scanstate->tupdesc = ENRMetadataGetTupDesc(&(enr->md));
     112          59 :     scanstate->readptr =
     113          59 :         tuplestore_alloc_read_pointer(scanstate->relation, EXEC_FLAG_REWIND);
     114             : 
     115             :     /*
     116             :      * The new read pointer copies its position from read pointer 0, which
     117             :      * could be anywhere, so explicitly rewind it.
     118             :      */
     119          59 :     tuplestore_rescan(scanstate->relation);
     120             : 
     121             :     /*
     122             :      * XXX: Should we add a function to free that read pointer when done?
     123             :      *
     124             :      * This was attempted, but it did not improve performance or memory usage
     125             :      * in any tested cases.
     126             :      */
     127             : 
     128             :     /*
     129             :      * Miscellaneous initialization
     130             :      *
     131             :      * create expression context for node
     132             :      */
     133          59 :     ExecAssignExprContext(estate, &scanstate->ss.ps);
     134             : 
     135             :     /*
     136             :      * initialize child expressions
     137             :      */
     138          59 :     scanstate->ss.ps.qual =
     139          59 :         ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
     140             : 
     141             :     /*
     142             :      * tuple table initialization
     143             :      */
     144          59 :     ExecInitResultTupleSlot(estate, &scanstate->ss.ps);
     145          59 :     ExecInitScanTupleSlot(estate, &scanstate->ss);
     146             : 
     147             :     /*
     148             :      * The scan tuple type is specified for the tuplestore.
     149             :      */
     150          59 :     ExecAssignScanType(&scanstate->ss, scanstate->tupdesc);
     151             : 
     152             :     /*
     153             :      * Initialize result tuple type and projection info.
     154             :      */
     155          59 :     ExecAssignResultTypeFromTL(&scanstate->ss.ps);
     156          59 :     ExecAssignScanProjectionInfo(&scanstate->ss);
     157             : 
     158          59 :     return scanstate;
     159             : }
     160             : 
     161             : /* ----------------------------------------------------------------
     162             :  *      ExecEndNamedTuplestoreScan
     163             :  *
     164             :  *      frees any storage allocated through C routines.
     165             :  * ----------------------------------------------------------------
     166             :  */
     167             : void
     168          59 : ExecEndNamedTuplestoreScan(NamedTuplestoreScanState *node)
     169             : {
     170             :     /*
     171             :      * Free exprcontext
     172             :      */
     173          59 :     ExecFreeExprContext(&node->ss.ps);
     174             : 
     175             :     /*
     176             :      * clean out the tuple table
     177             :      */
     178          59 :     ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
     179          59 :     ExecClearTuple(node->ss.ss_ScanTupleSlot);
     180          59 : }
     181             : 
     182             : /* ----------------------------------------------------------------
     183             :  *      ExecReScanNamedTuplestoreScan
     184             :  *
     185             :  *      Rescans the relation.
     186             :  * ----------------------------------------------------------------
     187             :  */
     188             : void
     189           0 : ExecReScanNamedTuplestoreScan(NamedTuplestoreScanState *node)
     190             : {
     191           0 :     Tuplestorestate *tuplestorestate = node->relation;
     192             : 
     193           0 :     ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
     194             : 
     195           0 :     ExecScanReScan(&node->ss);
     196             : 
     197             :     /*
     198             :      * Rewind my own pointer.
     199             :      */
     200           0 :     tuplestore_select_read_pointer(tuplestorestate, node->readptr);
     201           0 :     tuplestore_rescan(tuplestorestate);
     202           0 : }

Generated by: LCOV version 1.11