LCOV - code coverage report
Current view: top level - src/backend/executor - nodeNamedtuplestorescan.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 28 39 71.8 %
Date: 2024-12-12 15:15:20 Functions: 3 5 60.0 %
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-2024, 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             : 
      22             : static TupleTableSlot *NamedTuplestoreScanNext(NamedTuplestoreScanState *node);
      23             : 
      24             : /* ----------------------------------------------------------------
      25             :  *      NamedTuplestoreScanNext
      26             :  *
      27             :  *      This is a workhorse for ExecNamedTuplestoreScan
      28             :  * ----------------------------------------------------------------
      29             :  */
      30             : static TupleTableSlot *
      31       66612 : NamedTuplestoreScanNext(NamedTuplestoreScanState *node)
      32             : {
      33             :     TupleTableSlot *slot;
      34             : 
      35             :     /* We intentionally do not support backward scan. */
      36             :     Assert(ScanDirectionIsForward(node->ss.ps.state->es_direction));
      37             : 
      38             :     /*
      39             :      * Get the next tuple from tuplestore. Return NULL if no more tuples.
      40             :      */
      41       66612 :     slot = node->ss.ss_ScanTupleSlot;
      42       66612 :     tuplestore_select_read_pointer(node->relation, node->readptr);
      43       66612 :     (void) tuplestore_gettupleslot(node->relation, true, false, slot);
      44       66612 :     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       66612 : ExecNamedTuplestoreScan(PlanState *pstate)
      68             : {
      69       66612 :     NamedTuplestoreScanState *node = castNode(NamedTuplestoreScanState, pstate);
      70             : 
      71       66612 :     return ExecScan(&node->ss,
      72             :                     (ExecScanAccessMtd) NamedTuplestoreScanNext,
      73             :                     (ExecScanRecheckMtd) NamedTuplestoreScanRecheck);
      74             : }
      75             : 
      76             : 
      77             : /* ----------------------------------------------------------------
      78             :  *      ExecInitNamedTuplestoreScan
      79             :  * ----------------------------------------------------------------
      80             :  */
      81             : NamedTuplestoreScanState *
      82         660 : ExecInitNamedTuplestoreScan(NamedTuplestoreScan *node, EState *estate, int eflags)
      83             : {
      84             :     NamedTuplestoreScanState *scanstate;
      85             :     EphemeralNamedRelation enr;
      86             : 
      87             :     /* check for unsupported flags */
      88             :     Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
      89             : 
      90             :     /*
      91             :      * NamedTuplestoreScan should not have any children.
      92             :      */
      93             :     Assert(outerPlan(node) == NULL);
      94             :     Assert(innerPlan(node) == NULL);
      95             : 
      96             :     /*
      97             :      * create new NamedTuplestoreScanState for node
      98             :      */
      99         660 :     scanstate = makeNode(NamedTuplestoreScanState);
     100         660 :     scanstate->ss.ps.plan = (Plan *) node;
     101         660 :     scanstate->ss.ps.state = estate;
     102         660 :     scanstate->ss.ps.ExecProcNode = ExecNamedTuplestoreScan;
     103             : 
     104         660 :     enr = get_ENR(estate->es_queryEnv, node->enrname);
     105         660 :     if (!enr)
     106           0 :         elog(ERROR, "executor could not find named tuplestore \"%s\"",
     107             :              node->enrname);
     108             : 
     109             :     Assert(enr->reldata);
     110         660 :     scanstate->relation = (Tuplestorestate *) enr->reldata;
     111         660 :     scanstate->tupdesc = ENRMetadataGetTupDesc(&(enr->md));
     112         660 :     scanstate->readptr =
     113         660 :         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         660 :     tuplestore_select_read_pointer(scanstate->relation, scanstate->readptr);
     120         660 :     tuplestore_rescan(scanstate->relation);
     121             : 
     122             :     /*
     123             :      * XXX: Should we add a function to free that read pointer when done?
     124             :      *
     125             :      * This was attempted, but it did not improve performance or memory usage
     126             :      * in any tested cases.
     127             :      */
     128             : 
     129             :     /*
     130             :      * Miscellaneous initialization
     131             :      *
     132             :      * create expression context for node
     133             :      */
     134         660 :     ExecAssignExprContext(estate, &scanstate->ss.ps);
     135             : 
     136             :     /*
     137             :      * The scan tuple type is specified for the tuplestore.
     138             :      */
     139         660 :     ExecInitScanTupleSlot(estate, &scanstate->ss, scanstate->tupdesc,
     140             :                           &TTSOpsMinimalTuple);
     141             : 
     142             :     /*
     143             :      * Initialize result type and projection.
     144             :      */
     145         660 :     ExecInitResultTypeTL(&scanstate->ss.ps);
     146         660 :     ExecAssignScanProjectionInfo(&scanstate->ss);
     147             : 
     148             :     /*
     149             :      * initialize child expressions
     150             :      */
     151         660 :     scanstate->ss.ps.qual =
     152         660 :         ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
     153             : 
     154         660 :     return scanstate;
     155             : }
     156             : 
     157             : /* ----------------------------------------------------------------
     158             :  *      ExecReScanNamedTuplestoreScan
     159             :  *
     160             :  *      Rescans the relation.
     161             :  * ----------------------------------------------------------------
     162             :  */
     163             : void
     164           0 : ExecReScanNamedTuplestoreScan(NamedTuplestoreScanState *node)
     165             : {
     166           0 :     Tuplestorestate *tuplestorestate = node->relation;
     167             : 
     168           0 :     if (node->ss.ps.ps_ResultTupleSlot)
     169           0 :         ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
     170             : 
     171           0 :     ExecScanReScan(&node->ss);
     172             : 
     173             :     /*
     174             :      * Rewind my own pointer.
     175             :      */
     176           0 :     tuplestore_select_read_pointer(tuplestorestate, node->readptr);
     177           0 :     tuplestore_rescan(tuplestorestate);
     178           0 : }

Generated by: LCOV version 1.14