PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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"
34#include "utils/rel.h"
35
37
38/* ----------------------------------------------------------------
39 * Scan Support
40 * ----------------------------------------------------------------
41 */
42
43/* ----------------------------------------------------------------
44 * SeqNext
45 *
46 * This is a workhorse for ExecSeqScan
47 * ----------------------------------------------------------------
48 */
49static 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 */
88static 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 */
107static TupleTableSlot *
109{
110 SeqScanState *node = castNode(SeqScanState, pstate);
111
112 return ExecScan(&node->ss,
115}
116
117
118/* ----------------------------------------------------------------
119 * ExecInitSeqScan
120 * ----------------------------------------------------------------
121 */
123ExecInitSeqScan(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 =
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 */
183void
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 */
211void
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 */
237void
239 ParallelContext *pcxt)
240{
241 EState *estate = node->ss.ps.state;
242
244 estate->es_snapshot);
247}
248
249/* ----------------------------------------------------------------
250 * ExecSeqScanInitializeDSM
251 *
252 * Set up a parallel heap scan descriptor.
253 * ----------------------------------------------------------------
254 */
255void
257 ParallelContext *pcxt)
258{
259 EState *estate = node->ss.ps.state;
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 */
277void
279 ParallelContext *pcxt)
280{
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 */
293void
296{
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:812
ExprState * ExecInitQual(List *qual, PlanState *parent)
Definition: execExpr.c:224
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:1998
void ExecInitResultTypeTL(PlanState *planstate)
Definition: execTuples.c:1942
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:485
Relation ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags)
Definition: execUtils.c:742
bool(* ExecScanRecheckMtd)(ScanState *node, TupleTableSlot *slot)
Definition: executor.h:487
TupleTableSlot *(* ExecScanAccessMtd)(ScanState *node)
Definition: executor.h:486
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
SeqScanState * ExecInitSeqScan(SeqScan *node, EState *estate, int eflags)
Definition: nodeSeqscan.c:123
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
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:182
#define outerPlan(node)
Definition: plannodes.h:183
#define RelationGetDescr(relation)
Definition: rel.h:531
ScanDirection
Definition: sdir.h:25
void * shm_toc_allocate(shm_toc *toc, Size nbytes)
Definition: shm_toc.c:88
void shm_toc_insert(shm_toc *toc, uint64 key, void *address)
Definition: shm_toc.c:171
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:631
Snapshot es_snapshot
Definition: execnodes.h:632
shm_toc_estimator estimator
Definition: parallel.h:41
shm_toc * toc
Definition: parallel.h:44
ExprState * qual
Definition: execnodes.h:1147
Plan * plan
Definition: execnodes.h:1126
EState * state
Definition: execnodes.h:1128
ExecProcNodeMtd ExecProcNode
Definition: execnodes.h:1132
int plan_node_id
Definition: plannodes.h:152
Relation ss_currentRelation
Definition: execnodes.h:1574
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1576
PlanState ps
Definition: execnodes.h:1573
struct TableScanDescData * ss_currentScanDesc
Definition: execnodes.h:1575
Index scanrelid
Definition: plannodes.h:390
ScanState ss
Definition: execnodes.h:1585
Size pscan_len
Definition: execnodes.h:1586
Scan scan
Definition: plannodes.h:399
struct ParallelTableScanDescData * rs_parallel
Definition: relscan.h:66
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
const TupleTableSlotOps * table_slot_callbacks(Relation relation)
Definition: tableam.c:58
static TableScanDesc table_beginscan(Relation rel, Snapshot snapshot, int nkeys, struct ScanKeyData *key)
Definition: tableam.h:912
static void table_endscan(TableScanDesc scan)
Definition: tableam.h:1024
static void table_rescan(TableScanDesc scan, struct ScanKeyData *key)
Definition: tableam.h:1033
static bool table_scan_getnextslot(TableScanDesc sscan, ScanDirection direction, TupleTableSlot *slot)
Definition: tableam.h:1060
static void table_parallelscan_reinitialize(Relation rel, ParallelTableScanDesc pscan)
Definition: tableam.h:1179