LCOV - code coverage report
Current view: top level - src/backend/executor - nodeNamedtuplestorescan.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 71.8 % 39 28
Test Date: 2026-04-02 12:16:06 Functions: 60.0 % 5 3
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-2026, 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/executor.h"
      19              : #include "executor/nodeNamedtuplestorescan.h"
      20              : #include "utils/queryenvironment.h"
      21              : #include "utils/tuplestore.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        44600 : 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        44600 :     slot = node->ss.ss_ScanTupleSlot;
      43        44600 :     tuplestore_select_read_pointer(node->relation, node->readptr);
      44        44600 :     (void) tuplestore_gettupleslot(node->relation, true, false, slot);
      45        44600 :     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        44600 : ExecNamedTuplestoreScan(PlanState *pstate)
      69              : {
      70        44600 :     NamedTuplestoreScanState *node = castNode(NamedTuplestoreScanState, pstate);
      71              : 
      72        44600 :     return ExecScan(&node->ss,
      73              :                     (ExecScanAccessMtd) NamedTuplestoreScanNext,
      74              :                     (ExecScanRecheckMtd) NamedTuplestoreScanRecheck);
      75              : }
      76              : 
      77              : 
      78              : /* ----------------------------------------------------------------
      79              :  *      ExecInitNamedTuplestoreScan
      80              :  * ----------------------------------------------------------------
      81              :  */
      82              : NamedTuplestoreScanState *
      83          530 : 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          530 :     scanstate = makeNode(NamedTuplestoreScanState);
     101          530 :     scanstate->ss.ps.plan = (Plan *) node;
     102          530 :     scanstate->ss.ps.state = estate;
     103          530 :     scanstate->ss.ps.ExecProcNode = ExecNamedTuplestoreScan;
     104              : 
     105          530 :     enr = get_ENR(estate->es_queryEnv, node->enrname);
     106          530 :     if (!enr)
     107            0 :         elog(ERROR, "executor could not find named tuplestore \"%s\"",
     108              :              node->enrname);
     109              : 
     110              :     Assert(enr->reldata);
     111          530 :     scanstate->relation = (Tuplestorestate *) enr->reldata;
     112          530 :     scanstate->tupdesc = ENRMetadataGetTupDesc(&(enr->md));
     113          530 :     scanstate->readptr =
     114          530 :         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          530 :     tuplestore_select_read_pointer(scanstate->relation, scanstate->readptr);
     121          530 :     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          530 :     ExecAssignExprContext(estate, &scanstate->ss.ps);
     136              : 
     137              :     /*
     138              :      * The scan tuple type is specified for the tuplestore.
     139              :      */
     140          530 :     ExecInitScanTupleSlot(estate, &scanstate->ss, scanstate->tupdesc,
     141              :                           &TTSOpsMinimalTuple, 0);
     142              : 
     143              :     /*
     144              :      * Initialize result type and projection.
     145              :      */
     146          530 :     ExecInitResultTypeTL(&scanstate->ss.ps);
     147          530 :     ExecAssignScanProjectionInfo(&scanstate->ss);
     148              : 
     149              :     /*
     150              :      * initialize child expressions
     151              :      */
     152          530 :     scanstate->ss.ps.qual =
     153          530 :         ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
     154              : 
     155          530 :     return scanstate;
     156              : }
     157              : 
     158              : /* ----------------------------------------------------------------
     159              :  *      ExecReScanNamedTuplestoreScan
     160              :  *
     161              :  *      Rescans the relation.
     162              :  * ----------------------------------------------------------------
     163              :  */
     164              : void
     165            0 : ExecReScanNamedTuplestoreScan(NamedTuplestoreScanState *node)
     166              : {
     167            0 :     Tuplestorestate *tuplestorestate = node->relation;
     168              : 
     169            0 :     if (node->ss.ps.ps_ResultTupleSlot)
     170            0 :         ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
     171              : 
     172            0 :     ExecScanReScan(&node->ss);
     173              : 
     174              :     /*
     175              :      * Rewind my own pointer.
     176              :      */
     177            0 :     tuplestore_select_read_pointer(tuplestorestate, node->readptr);
     178            0 :     tuplestore_rescan(tuplestorestate);
     179            0 : }
        

Generated by: LCOV version 2.0-1