LCOV - differential code coverage report
Current view: top level - src/backend/executor - nodeSeqscan.c (source / functions) Coverage Total Hit CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 100.0 % 71 71 71
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 10 10 10
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /*-------------------------------------------------------------------------
       2                 :  *
       3                 :  * nodeSeqscan.c
       4                 :  *    Support routines for sequential scans of relations.
       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/nodeSeqscan.c
      12                 :  *
      13                 :  *-------------------------------------------------------------------------
      14                 :  */
      15                 : /*
      16                 :  * INTERFACE ROUTINES
      17                 :  *      ExecSeqScan             sequentially scans a relation.
      18                 :  *      ExecSeqNext             retrieve next tuple in sequential order.
      19                 :  *      ExecInitSeqScan         creates and initializes a seqscan node.
      20                 :  *      ExecEndSeqScan          releases any storage allocated.
      21                 :  *      ExecReScanSeqScan       rescans the relation
      22                 :  *
      23                 :  *      ExecSeqScanEstimate     estimates DSM space needed for parallel scan
      24                 :  *      ExecSeqScanInitializeDSM initialize DSM for parallel scan
      25                 :  *      ExecSeqScanReInitializeDSM reinitialize DSM for fresh parallel scan
      26                 :  *      ExecSeqScanInitializeWorker attach to DSM info in parallel worker
      27                 :  */
      28                 : #include "postgres.h"
      29                 : 
      30                 : #include "access/relscan.h"
      31                 : #include "access/tableam.h"
      32                 : #include "executor/execdebug.h"
      33                 : #include "executor/nodeSeqscan.h"
      34                 : #include "utils/rel.h"
      35                 : 
      36                 : static TupleTableSlot *SeqNext(SeqScanState *node);
      37                 : 
      38                 : /* ----------------------------------------------------------------
      39                 :  *                      Scan Support
      40                 :  * ----------------------------------------------------------------
      41                 :  */
      42                 : 
      43                 : /* ----------------------------------------------------------------
      44                 :  *      SeqNext
      45                 :  *
      46                 :  *      This is a workhorse for ExecSeqScan
      47                 :  * ----------------------------------------------------------------
      48                 :  */
      49                 : static TupleTableSlot *
      50 CBC    37554361 : SeqNext(SeqScanState *node)
      51                 : {
      52                 :     TableScanDesc scandesc;
      53                 :     EState     *estate;
      54                 :     ScanDirection direction;
      55                 :     TupleTableSlot *slot;
      56                 : 
      57                 :     /*
      58                 :      * get information from the estate and scan state
      59                 :      */
      60        37554361 :     scandesc = node->ss.ss_currentScanDesc;
      61        37554361 :     estate = node->ss.ps.state;
      62        37554361 :     direction = estate->es_direction;
      63        37554361 :     slot = node->ss.ss_ScanTupleSlot;
      64                 : 
      65        37554361 :     if (scandesc == NULL)
      66                 :     {
      67                 :         /*
      68                 :          * We reach here if the scan is not parallel, or if we're serially
      69                 :          * executing a scan that was planned to be parallel.
      70                 :          */
      71           76850 :         scandesc = table_beginscan(node->ss.ss_currentRelation,
      72                 :                                    estate->es_snapshot,
      73                 :                                    0, NULL);
      74           76850 :         node->ss.ss_currentScanDesc = scandesc;
      75                 :     }
      76                 : 
      77                 :     /*
      78                 :      * get the next tuple from the table
      79                 :      */
      80        37554361 :     if (table_scan_getnextslot(scandesc, direction, slot))
      81        37104995 :         return slot;
      82          449356 :     return NULL;
      83                 : }
      84                 : 
      85                 : /*
      86                 :  * SeqRecheck -- access method routine to recheck a tuple in EvalPlanQual
      87                 :  */
      88                 : static bool
      89              79 : SeqRecheck(SeqScanState *node, TupleTableSlot *slot)
      90                 : {
      91                 :     /*
      92                 :      * Note that unlike IndexScan, SeqScan never use keys in heap_beginscan
      93                 :      * (and this is very bad) - so, here we do not check are keys ok or not.
      94                 :      */
      95              79 :     return true;
      96                 : }
      97                 : 
      98                 : /* ----------------------------------------------------------------
      99                 :  *      ExecSeqScan(node)
     100                 :  *
     101                 :  *      Scans the relation sequentially and returns the next qualifying
     102                 :  *      tuple.
     103                 :  *      We call the ExecScan() routine and pass it the appropriate
     104                 :  *      access method functions.
     105                 :  * ----------------------------------------------------------------
     106                 :  */
     107                 : static TupleTableSlot *
     108        24410430 : ExecSeqScan(PlanState *pstate)
     109                 : {
     110        24410430 :     SeqScanState *node = castNode(SeqScanState, pstate);
     111                 : 
     112        24410430 :     return ExecScan(&node->ss,
     113                 :                     (ExecScanAccessMtd) SeqNext,
     114                 :                     (ExecScanRecheckMtd) SeqRecheck);
     115                 : }
     116                 : 
     117                 : 
     118                 : /* ----------------------------------------------------------------
     119                 :  *      ExecInitSeqScan
     120                 :  * ----------------------------------------------------------------
     121                 :  */
     122                 : SeqScanState *
     123           93563 : ExecInitSeqScan(SeqScan *node, EState *estate, int eflags)
     124                 : {
     125                 :     SeqScanState *scanstate;
     126                 : 
     127                 :     /*
     128                 :      * Once upon a time it was possible to have an outerPlan of a SeqScan, but
     129                 :      * not any more.
     130                 :      */
     131           93563 :     Assert(outerPlan(node) == NULL);
     132           93563 :     Assert(innerPlan(node) == NULL);
     133                 : 
     134                 :     /*
     135                 :      * create state structure
     136                 :      */
     137           93563 :     scanstate = makeNode(SeqScanState);
     138           93563 :     scanstate->ss.ps.plan = (Plan *) node;
     139           93563 :     scanstate->ss.ps.state = estate;
     140           93563 :     scanstate->ss.ps.ExecProcNode = ExecSeqScan;
     141                 : 
     142                 :     /*
     143                 :      * Miscellaneous initialization
     144                 :      *
     145                 :      * create expression context for node
     146                 :      */
     147           93563 :     ExecAssignExprContext(estate, &scanstate->ss.ps);
     148                 : 
     149                 :     /*
     150                 :      * open the scan relation
     151                 :      */
     152           93557 :     scanstate->ss.ss_currentRelation =
     153           93563 :         ExecOpenScanRelation(estate,
     154                 :                              node->scan.scanrelid,
     155                 :                              eflags);
     156                 : 
     157                 :     /* and create slot with the appropriate rowtype */
     158           93557 :     ExecInitScanTupleSlot(estate, &scanstate->ss,
     159           93557 :                           RelationGetDescr(scanstate->ss.ss_currentRelation),
     160                 :                           table_slot_callbacks(scanstate->ss.ss_currentRelation));
     161                 : 
     162                 :     /*
     163                 :      * Initialize result type and projection.
     164                 :      */
     165           93557 :     ExecInitResultTypeTL(&scanstate->ss.ps);
     166           93557 :     ExecAssignScanProjectionInfo(&scanstate->ss);
     167                 : 
     168                 :     /*
     169                 :      * initialize child expressions
     170                 :      */
     171           93557 :     scanstate->ss.ps.qual =
     172           93557 :         ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
     173                 : 
     174           93557 :     return scanstate;
     175                 : }
     176                 : 
     177                 : /* ----------------------------------------------------------------
     178                 :  *      ExecEndSeqScan
     179                 :  *
     180                 :  *      frees any storage allocated through C routines.
     181                 :  * ----------------------------------------------------------------
     182                 :  */
     183                 : void
     184           92458 : ExecEndSeqScan(SeqScanState *node)
     185                 : {
     186                 :     TableScanDesc scanDesc;
     187                 : 
     188                 :     /*
     189                 :      * get information from node
     190                 :      */
     191           92458 :     scanDesc = node->ss.ss_currentScanDesc;
     192                 : 
     193                 :     /*
     194                 :      * Free the exprcontext
     195                 :      */
     196           92458 :     ExecFreeExprContext(&node->ss.ps);
     197                 : 
     198                 :     /*
     199                 :      * clean out the tuple table
     200                 :      */
     201           92458 :     if (node->ss.ps.ps_ResultTupleSlot)
     202           51088 :         ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
     203           92458 :     ExecClearTuple(node->ss.ss_ScanTupleSlot);
     204                 : 
     205                 :     /*
     206                 :      * close heap scan
     207                 :      */
     208           92458 :     if (scanDesc != NULL)
     209           77714 :         table_endscan(scanDesc);
     210           92458 : }
     211                 : 
     212                 : /* ----------------------------------------------------------------
     213                 :  *                      Join Support
     214                 :  * ----------------------------------------------------------------
     215                 :  */
     216                 : 
     217                 : /* ----------------------------------------------------------------
     218                 :  *      ExecReScanSeqScan
     219                 :  *
     220                 :  *      Rescans the relation.
     221                 :  * ----------------------------------------------------------------
     222                 :  */
     223                 : void
     224          387654 : ExecReScanSeqScan(SeqScanState *node)
     225                 : {
     226                 :     TableScanDesc scan;
     227                 : 
     228          387654 :     scan = node->ss.ss_currentScanDesc;
     229                 : 
     230          387654 :     if (scan != NULL)
     231          379034 :         table_rescan(scan,      /* scan desc */
     232                 :                      NULL);     /* new scan keys */
     233                 : 
     234          387654 :     ExecScanReScan((ScanState *) node);
     235          387654 : }
     236                 : 
     237                 : /* ----------------------------------------------------------------
     238                 :  *                      Parallel Scan Support
     239                 :  * ----------------------------------------------------------------
     240                 :  */
     241                 : 
     242                 : /* ----------------------------------------------------------------
     243                 :  *      ExecSeqScanEstimate
     244                 :  *
     245                 :  *      Compute the amount of space we'll need in the parallel
     246                 :  *      query DSM, and inform pcxt->estimator about our needs.
     247                 :  * ----------------------------------------------------------------
     248                 :  */
     249                 : void
     250             441 : ExecSeqScanEstimate(SeqScanState *node,
     251                 :                     ParallelContext *pcxt)
     252                 : {
     253             441 :     EState     *estate = node->ss.ps.state;
     254                 : 
     255             441 :     node->pscan_len = table_parallelscan_estimate(node->ss.ss_currentRelation,
     256                 :                                                   estate->es_snapshot);
     257             441 :     shm_toc_estimate_chunk(&pcxt->estimator, node->pscan_len);
     258             441 :     shm_toc_estimate_keys(&pcxt->estimator, 1);
     259             441 : }
     260                 : 
     261                 : /* ----------------------------------------------------------------
     262                 :  *      ExecSeqScanInitializeDSM
     263                 :  *
     264                 :  *      Set up a parallel heap scan descriptor.
     265                 :  * ----------------------------------------------------------------
     266                 :  */
     267                 : void
     268             441 : ExecSeqScanInitializeDSM(SeqScanState *node,
     269                 :                          ParallelContext *pcxt)
     270                 : {
     271             441 :     EState     *estate = node->ss.ps.state;
     272                 :     ParallelTableScanDesc pscan;
     273                 : 
     274             441 :     pscan = shm_toc_allocate(pcxt->toc, node->pscan_len);
     275             441 :     table_parallelscan_initialize(node->ss.ss_currentRelation,
     276                 :                                   pscan,
     277                 :                                   estate->es_snapshot);
     278             441 :     shm_toc_insert(pcxt->toc, node->ss.ps.plan->plan_node_id, pscan);
     279             441 :     node->ss.ss_currentScanDesc =
     280             441 :         table_beginscan_parallel(node->ss.ss_currentRelation, pscan);
     281             441 : }
     282                 : 
     283                 : /* ----------------------------------------------------------------
     284                 :  *      ExecSeqScanReInitializeDSM
     285                 :  *
     286                 :  *      Reset shared state before beginning a fresh scan.
     287                 :  * ----------------------------------------------------------------
     288                 :  */
     289                 : void
     290             114 : ExecSeqScanReInitializeDSM(SeqScanState *node,
     291                 :                            ParallelContext *pcxt)
     292                 : {
     293                 :     ParallelTableScanDesc pscan;
     294                 : 
     295             114 :     pscan = node->ss.ss_currentScanDesc->rs_parallel;
     296             114 :     table_parallelscan_reinitialize(node->ss.ss_currentRelation, pscan);
     297             114 : }
     298                 : 
     299                 : /* ----------------------------------------------------------------
     300                 :  *      ExecSeqScanInitializeWorker
     301                 :  *
     302                 :  *      Copy relevant information from TOC into planstate.
     303                 :  * ----------------------------------------------------------------
     304                 :  */
     305                 : void
     306            1312 : ExecSeqScanInitializeWorker(SeqScanState *node,
     307                 :                             ParallelWorkerContext *pwcxt)
     308                 : {
     309                 :     ParallelTableScanDesc pscan;
     310                 : 
     311            1312 :     pscan = shm_toc_lookup(pwcxt->toc, node->ss.ps.plan->plan_node_id, false);
     312            1312 :     node->ss.ss_currentScanDesc =
     313            1312 :         table_beginscan_parallel(node->ss.ss_currentRelation, pscan);
     314            1312 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a