LCOV - differential code coverage report
Current view: top level - src/backend/executor - nodeNamedtuplestorescan.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 78.0 % 50 39 11 39
Current Date: 2023-04-08 15:15:32 Functions: 66.7 % 6 4 2 4
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  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 CBC       33306 : NamedTuplestoreScanNext(NamedTuplestoreScanState *node)
      33                 : {
      34                 :     TupleTableSlot *slot;
      35                 : 
      36                 :     /* We intentionally do not support backward scan. */
      37           33306 :     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           33306 :     slot = node->ss.ss_ScanTupleSlot;
      43           33306 :     tuplestore_select_read_pointer(node->relation, node->readptr);
      44           33306 :     (void) tuplestore_gettupleslot(node->relation, true, false, slot);
      45           33306 :     return slot;
      46                 : }
      47                 : 
      48                 : /*
      49                 :  * NamedTuplestoreScanRecheck -- access method routine to recheck a tuple in
      50                 :  * EvalPlanQual
      51                 :  */
      52                 : static bool
      53 UBC           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 CBC       33306 : ExecNamedTuplestoreScan(PlanState *pstate)
      69                 : {
      70           33306 :     NamedTuplestoreScanState *node = castNode(NamedTuplestoreScanState, pstate);
      71                 : 
      72           33306 :     return ExecScan(&node->ss,
      73                 :                     (ExecScanAccessMtd) NamedTuplestoreScanNext,
      74                 :                     (ExecScanRecheckMtd) NamedTuplestoreScanRecheck);
      75                 : }
      76                 : 
      77                 : 
      78                 : /* ----------------------------------------------------------------
      79                 :  *      ExecInitNamedTuplestoreScan
      80                 :  * ----------------------------------------------------------------
      81                 :  */
      82                 : NamedTuplestoreScanState *
      83             330 : ExecInitNamedTuplestoreScan(NamedTuplestoreScan *node, EState *estate, int eflags)
      84                 : {
      85                 :     NamedTuplestoreScanState *scanstate;
      86                 :     EphemeralNamedRelation enr;
      87                 : 
      88                 :     /* check for unsupported flags */
      89             330 :     Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
      90                 : 
      91                 :     /*
      92                 :      * NamedTuplestoreScan should not have any children.
      93                 :      */
      94             330 :     Assert(outerPlan(node) == NULL);
      95             330 :     Assert(innerPlan(node) == NULL);
      96                 : 
      97                 :     /*
      98                 :      * create new NamedTuplestoreScanState for node
      99                 :      */
     100             330 :     scanstate = makeNode(NamedTuplestoreScanState);
     101             330 :     scanstate->ss.ps.plan = (Plan *) node;
     102             330 :     scanstate->ss.ps.state = estate;
     103             330 :     scanstate->ss.ps.ExecProcNode = ExecNamedTuplestoreScan;
     104                 : 
     105             330 :     enr = get_ENR(estate->es_queryEnv, node->enrname);
     106             330 :     if (!enr)
     107 UBC           0 :         elog(ERROR, "executor could not find named tuplestore \"%s\"",
     108                 :              node->enrname);
     109                 : 
     110 CBC         330 :     Assert(enr->reldata);
     111             330 :     scanstate->relation = (Tuplestorestate *) enr->reldata;
     112             330 :     scanstate->tupdesc = ENRMetadataGetTupDesc(&(enr->md));
     113             330 :     scanstate->readptr =
     114             330 :         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             330 :     tuplestore_select_read_pointer(scanstate->relation, scanstate->readptr);
     121             330 :     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             330 :     ExecAssignExprContext(estate, &scanstate->ss.ps);
     136                 : 
     137                 :     /*
     138                 :      * The scan tuple type is specified for the tuplestore.
     139                 :      */
     140             330 :     ExecInitScanTupleSlot(estate, &scanstate->ss, scanstate->tupdesc,
     141                 :                           &TTSOpsMinimalTuple);
     142                 : 
     143                 :     /*
     144                 :      * Initialize result type and projection.
     145                 :      */
     146             330 :     ExecInitResultTypeTL(&scanstate->ss.ps);
     147             330 :     ExecAssignScanProjectionInfo(&scanstate->ss);
     148                 : 
     149                 :     /*
     150                 :      * initialize child expressions
     151                 :      */
     152             330 :     scanstate->ss.ps.qual =
     153             330 :         ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
     154                 : 
     155             330 :     return scanstate;
     156                 : }
     157                 : 
     158                 : /* ----------------------------------------------------------------
     159                 :  *      ExecEndNamedTuplestoreScan
     160                 :  *
     161                 :  *      frees any storage allocated through C routines.
     162                 :  * ----------------------------------------------------------------
     163                 :  */
     164                 : void
     165             330 : ExecEndNamedTuplestoreScan(NamedTuplestoreScanState *node)
     166                 : {
     167                 :     /*
     168                 :      * Free exprcontext
     169                 :      */
     170             330 :     ExecFreeExprContext(&node->ss.ps);
     171                 : 
     172                 :     /*
     173                 :      * clean out the tuple table
     174                 :      */
     175             330 :     if (node->ss.ps.ps_ResultTupleSlot)
     176             294 :         ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
     177             330 :     ExecClearTuple(node->ss.ss_ScanTupleSlot);
     178             330 : }
     179                 : 
     180                 : /* ----------------------------------------------------------------
     181                 :  *      ExecReScanNamedTuplestoreScan
     182                 :  *
     183                 :  *      Rescans the relation.
     184                 :  * ----------------------------------------------------------------
     185                 :  */
     186                 : void
     187 UBC           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 v1.16-55-g56c0a2a