PostgreSQL Source Code  git master
nodeSeqscan.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * nodeSeqscan.c
4  * Support routines for sequential scans of relations.
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/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/executor.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 *
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  scandesc = node->ss.ss_currentScanDesc;
61  estate = node->ss.ps.state;
62  direction = estate->es_direction;
63  slot = node->ss.ss_ScanTupleSlot;
64 
65  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  scandesc = table_beginscan(node->ss.ss_currentRelation,
72  estate->es_snapshot,
73  0, NULL);
74  node->ss.ss_currentScanDesc = scandesc;
75  }
76 
77  /*
78  * get the next tuple from the table
79  */
80  if (table_scan_getnextslot(scandesc, direction, slot))
81  return slot;
82  return NULL;
83 }
84 
85 /*
86  * SeqRecheck -- access method routine to recheck a tuple in EvalPlanQual
87  */
88 static bool
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  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 *
109 {
110  SeqScanState *node = castNode(SeqScanState, pstate);
111 
112  return ExecScan(&node->ss,
115 }
116 
117 
118 /* ----------------------------------------------------------------
119  * ExecInitSeqScan
120  * ----------------------------------------------------------------
121  */
122 SeqScanState *
123 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  Assert(outerPlan(node) == NULL);
132  Assert(innerPlan(node) == NULL);
133 
134  /*
135  * create state structure
136  */
137  scanstate = makeNode(SeqScanState);
138  scanstate->ss.ps.plan = (Plan *) node;
139  scanstate->ss.ps.state = estate;
140  scanstate->ss.ps.ExecProcNode = ExecSeqScan;
141 
142  /*
143  * Miscellaneous initialization
144  *
145  * create expression context for node
146  */
147  ExecAssignExprContext(estate, &scanstate->ss.ps);
148 
149  /*
150  * open the scan relation
151  */
152  scanstate->ss.ss_currentRelation =
153  ExecOpenScanRelation(estate,
154  node->scan.scanrelid,
155  eflags);
156 
157  /* and create slot with the appropriate rowtype */
158  ExecInitScanTupleSlot(estate, &scanstate->ss,
161 
162  /*
163  * Initialize result type and projection.
164  */
165  ExecInitResultTypeTL(&scanstate->ss.ps);
166  ExecAssignScanProjectionInfo(&scanstate->ss);
167 
168  /*
169  * initialize child expressions
170  */
171  scanstate->ss.ps.qual =
172  ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
173 
174  return scanstate;
175 }
176 
177 /* ----------------------------------------------------------------
178  * ExecEndSeqScan
179  *
180  * frees any storage allocated through C routines.
181  * ----------------------------------------------------------------
182  */
183 void
185 {
186  TableScanDesc scanDesc;
187 
188  /*
189  * get information from node
190  */
191  scanDesc = node->ss.ss_currentScanDesc;
192 
193  /*
194  * close heap scan
195  */
196  if (scanDesc != NULL)
197  table_endscan(scanDesc);
198 }
199 
200 /* ----------------------------------------------------------------
201  * Join Support
202  * ----------------------------------------------------------------
203  */
204 
205 /* ----------------------------------------------------------------
206  * ExecReScanSeqScan
207  *
208  * Rescans the relation.
209  * ----------------------------------------------------------------
210  */
211 void
213 {
214  TableScanDesc scan;
215 
216  scan = node->ss.ss_currentScanDesc;
217 
218  if (scan != NULL)
219  table_rescan(scan, /* scan desc */
220  NULL); /* new scan keys */
221 
222  ExecScanReScan((ScanState *) node);
223 }
224 
225 /* ----------------------------------------------------------------
226  * Parallel Scan Support
227  * ----------------------------------------------------------------
228  */
229 
230 /* ----------------------------------------------------------------
231  * ExecSeqScanEstimate
232  *
233  * Compute the amount of space we'll need in the parallel
234  * query DSM, and inform pcxt->estimator about our needs.
235  * ----------------------------------------------------------------
236  */
237 void
239  ParallelContext *pcxt)
240 {
241  EState *estate = node->ss.ps.state;
242 
244  estate->es_snapshot);
246  shm_toc_estimate_keys(&pcxt->estimator, 1);
247 }
248 
249 /* ----------------------------------------------------------------
250  * ExecSeqScanInitializeDSM
251  *
252  * Set up a parallel heap scan descriptor.
253  * ----------------------------------------------------------------
254  */
255 void
257  ParallelContext *pcxt)
258 {
259  EState *estate = node->ss.ps.state;
260  ParallelTableScanDesc pscan;
261 
262  pscan = shm_toc_allocate(pcxt->toc, node->pscan_len);
264  pscan,
265  estate->es_snapshot);
266  shm_toc_insert(pcxt->toc, node->ss.ps.plan->plan_node_id, pscan);
267  node->ss.ss_currentScanDesc =
269 }
270 
271 /* ----------------------------------------------------------------
272  * ExecSeqScanReInitializeDSM
273  *
274  * Reset shared state before beginning a fresh scan.
275  * ----------------------------------------------------------------
276  */
277 void
279  ParallelContext *pcxt)
280 {
281  ParallelTableScanDesc pscan;
282 
283  pscan = node->ss.ss_currentScanDesc->rs_parallel;
285 }
286 
287 /* ----------------------------------------------------------------
288  * ExecSeqScanInitializeWorker
289  *
290  * Copy relevant information from TOC into planstate.
291  * ----------------------------------------------------------------
292  */
293 void
295  ParallelWorkerContext *pwcxt)
296 {
297  ParallelTableScanDesc pscan;
298 
299  pscan = shm_toc_lookup(pwcxt->toc, node->ss.ps.plan->plan_node_id, false);
300  node->ss.ss_currentScanDesc =
302 }
#define Assert(condition)
Definition: c.h:858
ExprState * ExecInitQual(List *qual, PlanState *parent)
Definition: execExpr.c:220
TupleTableSlot * ExecScan(ScanState *node, ExecScanAccessMtd accessMtd, ExecScanRecheckMtd recheckMtd)
Definition: execScan.c:156
void ExecAssignScanProjectionInfo(ScanState *node)
Definition: execScan.c:270
void ExecScanReScan(ScanState *node)
Definition: execScan.c:297
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1898
void ExecInitResultTypeTL(PlanState *planstate)
Definition: execTuples.c:1842
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:483
Relation ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags)
Definition: execUtils.c:697
TupleTableSlot *(* ExecScanAccessMtd)(ScanState *node)
Definition: executor.h:473
bool(* ExecScanRecheckMtd)(ScanState *node, TupleTableSlot *slot)
Definition: executor.h:474
void ExecSeqScanReInitializeDSM(SeqScanState *node, ParallelContext *pcxt)
Definition: nodeSeqscan.c:278
void ExecSeqScanInitializeWorker(SeqScanState *node, ParallelWorkerContext *pwcxt)
Definition: nodeSeqscan.c:294
void ExecEndSeqScan(SeqScanState *node)
Definition: nodeSeqscan.c:184
static TupleTableSlot * ExecSeqScan(PlanState *pstate)
Definition: nodeSeqscan.c:108
void ExecSeqScanInitializeDSM(SeqScanState *node, ParallelContext *pcxt)
Definition: nodeSeqscan.c:256
static bool SeqRecheck(SeqScanState *node, TupleTableSlot *slot)
Definition: nodeSeqscan.c:89
void ExecSeqScanEstimate(SeqScanState *node, ParallelContext *pcxt)
Definition: nodeSeqscan.c:238
static TupleTableSlot * SeqNext(SeqScanState *node)
Definition: nodeSeqscan.c:50
SeqScanState * ExecInitSeqScan(SeqScan *node, EState *estate, int eflags)
Definition: nodeSeqscan.c:123
void ExecReScanSeqScan(SeqScanState *node)
Definition: nodeSeqscan.c:212
#define makeNode(_type_)
Definition: nodes.h:155
#define castNode(_type_, nodeptr)
Definition: nodes.h:176
#define innerPlan(node)
Definition: plannodes.h:181
#define outerPlan(node)
Definition: plannodes.h:182
#define RelationGetDescr(relation)
Definition: rel.h:531
ScanDirection
Definition: sdir.h:25
void shm_toc_insert(shm_toc *toc, uint64 key, void *address)
Definition: shm_toc.c:171
void * shm_toc_allocate(shm_toc *toc, Size nbytes)
Definition: shm_toc.c:88
void * shm_toc_lookup(shm_toc *toc, uint64 key, bool noError)
Definition: shm_toc.c:232
#define shm_toc_estimate_chunk(e, sz)
Definition: shm_toc.h:51
#define shm_toc_estimate_keys(e, cnt)
Definition: shm_toc.h:53
ScanDirection es_direction
Definition: execnodes.h:623
Snapshot es_snapshot
Definition: execnodes.h:624
shm_toc_estimator estimator
Definition: parallel.h:41
shm_toc * toc
Definition: parallel.h:44
ExprState * qual
Definition: execnodes.h:1139
Plan * plan
Definition: execnodes.h:1118
EState * state
Definition: execnodes.h:1120
ExecProcNodeMtd ExecProcNode
Definition: execnodes.h:1124
int plan_node_id
Definition: plannodes.h:151
Relation ss_currentRelation
Definition: execnodes.h:1566
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1568
PlanState ps
Definition: execnodes.h:1565
struct TableScanDescData * ss_currentScanDesc
Definition: execnodes.h:1567
Index scanrelid
Definition: plannodes.h:389
ScanState ss
Definition: execnodes.h:1577
Size pscan_len
Definition: execnodes.h:1578
Scan scan
Definition: plannodes.h:398
struct ParallelTableScanDescData * rs_parallel
Definition: relscan.h:49
const TupleTableSlotOps * table_slot_callbacks(Relation relation)
Definition: tableam.c:58
TableScanDesc table_beginscan_parallel(Relation relation, ParallelTableScanDesc pscan)
Definition: tableam.c:165
Size table_parallelscan_estimate(Relation rel, Snapshot snapshot)
Definition: tableam.c:130
void table_parallelscan_initialize(Relation rel, ParallelTableScanDesc pscan, Snapshot snapshot)
Definition: tableam.c:145
static TableScanDesc table_beginscan(Relation rel, Snapshot snapshot, int nkeys, struct ScanKeyData *key)
Definition: tableam.h:880
static void table_endscan(TableScanDesc scan)
Definition: tableam.h:991
static void table_rescan(TableScanDesc scan, struct ScanKeyData *key)
Definition: tableam.h:1000
static bool table_scan_getnextslot(TableScanDesc sscan, ScanDirection direction, TupleTableSlot *slot)
Definition: tableam.h:1027
static void table_parallelscan_reinitialize(Relation rel, ParallelTableScanDesc pscan)
Definition: tableam.h:1146