LCOV - code coverage report
Current view: top level - src/backend/executor - nodeNamedtuplestorescan.c (source / functions) Hit Total Coverage
Test: PostgreSQL 16beta1 Lines: 34 45 75.6 %
Date: 2023-06-06 08:12:15 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-2023, 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       66612 : NamedTuplestoreScanNext(NamedTuplestoreScanState *node)
      33             : {
      34             :     TupleTableSlot *slot;
      35             : 
      36             :     /* We intentionally do not support backward scan. */
      37             :     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       66612 :     slot = node->ss.ss_ScanTupleSlot;
      43       66612 :     tuplestore_select_read_pointer(node->relation, node->readptr);
      44       66612 :     (void) tuplestore_gettupleslot(node->relation, true, false, slot);
      45       66612 :     return slot;
      46             : }
      47             : 
      48             : /*
      49             :  * NamedTuplestoreScanRecheck -- access method routine to recheck a tuple in
      50             :  * EvalPlanQual
      51             :  */
      52             : static bool
      53           0 : NamedTuplestoreScanRecheck(NamedTuplestoreScanState *node, TupleTableSlot *slot)
      54             : {
      55             :     /* nothing to check */
      56           0 :     return true;
      57             : }
      58             : 
      59             : /* ----------------------------------------------------------------
      60             :  *      ExecNamedTuplestoreScan(node)
      61             :  *
      62             :  *      Scans the CTE sequentially and returns the next qualifying tuple.
      63             :  *      We call the ExecScan() routine and pass it the appropriate
      64             :  *      access method functions.
      65             :  * ----------------------------------------------------------------
      66             :  */
      67             : static TupleTableSlot *
      68       66612 : ExecNamedTuplestoreScan(PlanState *pstate)
      69             : {
      70       66612 :     NamedTuplestoreScanState *node = castNode(NamedTuplestoreScanState, pstate);
      71             : 
      72       66612 :     return ExecScan(&node->ss,
      73             :                     (ExecScanAccessMtd) NamedTuplestoreScanNext,
      74             :                     (ExecScanRecheckMtd) NamedTuplestoreScanRecheck);
      75             : }
      76             : 
      77             : 
      78             : /* ----------------------------------------------------------------
      79             :  *      ExecInitNamedTuplestoreScan
      80             :  * ----------------------------------------------------------------
      81             :  */
      82             : NamedTuplestoreScanState *
      83         660 : ExecInitNamedTuplestoreScan(NamedTuplestoreScan *node, EState *estate, int eflags)
      84             : {
      85             :     NamedTuplestoreScanState *scanstate;
      86             :     EphemeralNamedRelation enr;
      87             : 
      88             :     /* check for unsupported flags */
      89             :     Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
      90             : 
      91             :     /*
      92             :      * NamedTuplestoreScan should not have any children.
      93             :      */
      94             :     Assert(outerPlan(node) == NULL);
      95             :     Assert(innerPlan(node) == NULL);
      96             : 
      97             :     /*
      98             :      * create new NamedTuplestoreScanState for node
      99             :      */
     100         660 :     scanstate = makeNode(NamedTuplestoreScanState);
     101         660 :     scanstate->ss.ps.plan = (Plan *) node;
     102         660 :     scanstate->ss.ps.state = estate;
     103         660 :     scanstate->ss.ps.ExecProcNode = ExecNamedTuplestoreScan;
     104             : 
     105         660 :     enr = get_ENR(estate->es_queryEnv, node->enrname);
     106         660 :     if (!enr)
     107           0 :         elog(ERROR, "executor could not find named tuplestore \"%s\"",
     108             :              node->enrname);
     109             : 
     110             :     Assert(enr->reldata);
     111         660 :     scanstate->relation = (Tuplestorestate *) enr->reldata;
     112         660 :     scanstate->tupdesc = ENRMetadataGetTupDesc(&(enr->md));
     113         660 :     scanstate->readptr =
     114         660 :         tuplestore_alloc_read_pointer(scanstate->relation, EXEC_FLAG_REWIND);
     115             : 
     116             :     /*
     117             :      * The new read pointer copies its position from read pointer 0, which
     118             :      * could be anywhere, so explicitly rewind it.
     119             :      */
     120         660 :     tuplestore_select_read_pointer(scanstate->relation, scanstate->readptr);
     121         660 :     tuplestore_rescan(scanstate->relation);
     122             : 
     123             :     /*
     124             :      * XXX: Should we add a function to free that read pointer when done?
     125             :      *
     126             :      * This was attempted, but it did not improve performance or memory usage
     127             :      * in any tested cases.
     128             :      */
     129             : 
     130             :     /*
     131             :      * Miscellaneous initialization
     132             :      *
     133             :      * create expression context for node
     134             :      */
     135         660 :     ExecAssignExprContext(estate, &scanstate->ss.ps);
     136             : 
     137             :     /*
     138             :      * The scan tuple type is specified for the tuplestore.
     139             :      */
     140         660 :     ExecInitScanTupleSlot(estate, &scanstate->ss, scanstate->tupdesc,
     141             :                           &TTSOpsMinimalTuple);
     142             : 
     143             :     /*
     144             :      * Initialize result type and projection.
     145             :      */
     146         660 :     ExecInitResultTypeTL(&scanstate->ss.ps);
     147         660 :     ExecAssignScanProjectionInfo(&scanstate->ss);
     148             : 
     149             :     /*
     150             :      * initialize child expressions
     151             :      */
     152         660 :     scanstate->ss.ps.qual =
     153         660 :         ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
     154             : 
     155         660 :     return scanstate;
     156             : }
     157             : 
     158             : /* ----------------------------------------------------------------
     159             :  *      ExecEndNamedTuplestoreScan
     160             :  *
     161             :  *      frees any storage allocated through C routines.
     162             :  * ----------------------------------------------------------------
     163             :  */
     164             : void
     165         660 : ExecEndNamedTuplestoreScan(NamedTuplestoreScanState *node)
     166             : {
     167             :     /*
     168             :      * Free exprcontext
     169             :      */
     170         660 :     ExecFreeExprContext(&node->ss.ps);
     171             : 
     172             :     /*
     173             :      * clean out the tuple table
     174             :      */
     175         660 :     if (node->ss.ps.ps_ResultTupleSlot)
     176         588 :         ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
     177         660 :     ExecClearTuple(node->ss.ss_ScanTupleSlot);
     178         660 : }
     179             : 
     180             : /* ----------------------------------------------------------------
     181             :  *      ExecReScanNamedTuplestoreScan
     182             :  *
     183             :  *      Rescans the relation.
     184             :  * ----------------------------------------------------------------
     185             :  */
     186             : void
     187           0 : ExecReScanNamedTuplestoreScan(NamedTuplestoreScanState *node)
     188             : {
     189           0 :     Tuplestorestate *tuplestorestate = node->relation;
     190             : 
     191           0 :     if (node->ss.ps.ps_ResultTupleSlot)
     192           0 :         ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
     193             : 
     194           0 :     ExecScanReScan(&node->ss);
     195             : 
     196             :     /*
     197             :      * Rewind my own pointer.
     198             :      */
     199           0 :     tuplestore_select_read_pointer(tuplestorestate, node->readptr);
     200           0 :     tuplestore_rescan(tuplestorestate);
     201           0 : }

Generated by: LCOV version 1.14