1/*-------------------------------------------------------------------------
4 * Support routines for sequential scans of relations.
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * src/backend/executor/nodeSeqscan.c
13 *-------------------------------------------------------------------------
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
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
39/* ----------------------------------------------------------------
41 * ----------------------------------------------------------------
44/* ----------------------------------------------------------------
47 * This is a workhorse for ExecSeqScan
48 * ----------------------------------------------------------------
59 * get information from the estate and scan state
69 * We reach here if the scan is not parallel, or if we're serially
70 * executing a scan that was planned to be parallel.
79 * get the next tuple from the table
87 * SeqRecheck -- access method routine to recheck a tuple in EvalPlanQual
93 * Note that unlike IndexScan, SeqScan never use keys in heap_beginscan
94 * (and this is very bad) - so, here we do not check are keys ok or not.
99/* ----------------------------------------------------------------
102 * Scans the relation sequentially and returns the next qualifying
103 * tuple. This variant is used when there is no es_epq_active, no qual
104 * and no projection. Passing const-NULLs for these to ExecScanExtended
105 * allows the compiler to eliminate the additional code that would
106 * ordinarily be required for the evaluation of these.
107 * ----------------------------------------------------------------
127 * Variant of ExecSeqScan() but when qual evaluation is required.
135 * Use pg_assume() for != NULL tests to make the compiler realize no
136 * runtime check for the field is needed in ExecScanExtended().
151 * Variant of ExecSeqScan() but when projection is required.
171 * Variant of ExecSeqScan() but when qual evaluation and projection are
192 * Variant of ExecSeqScan for when EPQ evaluation is required. We don't
193 * bother adding variants of this for with/without qual and projection as
194 * EPQ doesn't seem as exciting a case to optimize for.
206/* ----------------------------------------------------------------
208 * ----------------------------------------------------------------
216 * Once upon a time it was possible to have an outerPlan of a SeqScan, but
223 * create state structure
230 * Miscellaneous initialization
232 * create expression context for node
237 * open the scan relation
244 /* and create slot with the appropriate rowtype */
250 * Initialize result type and projection.
256 * initialize child expressions
262 * When EvalPlanQual() is not in use, assign ExecProcNode for this node
263 * based on the presence of qual and projection. Each ExecSeqScan*()
264 * variant is optimized for the specific combination of these conditions.
268 else if (scanstate->
ss.
ps.
qual == NULL)
286/* ----------------------------------------------------------------
289 * frees any storage allocated through C routines.
290 * ----------------------------------------------------------------
298 * get information from node
305 if (scanDesc != NULL)
309/* ----------------------------------------------------------------
311 * ----------------------------------------------------------------
314/* ----------------------------------------------------------------
317 * Rescans the relation.
318 * ----------------------------------------------------------------
329 NULL);
/* new scan keys */
334/* ----------------------------------------------------------------
335 * Parallel Scan Support
336 * ----------------------------------------------------------------
339/* ----------------------------------------------------------------
340 * ExecSeqScanEstimate
342 * Compute the amount of space we'll need in the parallel
343 * query DSM, and inform pcxt->estimator about our needs.
344 * ----------------------------------------------------------------
358/* ----------------------------------------------------------------
359 * ExecSeqScanInitializeDSM
361 * Set up a parallel heap scan descriptor.
362 * ----------------------------------------------------------------
380/* ----------------------------------------------------------------
381 * ExecSeqScanReInitializeDSM
383 * Reset shared state before beginning a fresh scan.
384 * ----------------------------------------------------------------
396/* ----------------------------------------------------------------
397 * ExecSeqScanInitializeWorker
399 * Copy relevant information from TOC into planstate.
400 * ----------------------------------------------------------------
ExprState * ExecInitQual(List *qual, PlanState *parent)
TupleTableSlot * ExecScan(ScanState *node, ExecScanAccessMtd accessMtd, ExecScanRecheckMtd recheckMtd)
void ExecAssignScanProjectionInfo(ScanState *node)
void ExecScanReScan(ScanState *node)
static pg_attribute_always_inline TupleTableSlot * ExecScanExtended(ScanState *node, ExecScanAccessMtd accessMtd, ExecScanRecheckMtd recheckMtd, EPQState *epqstate, ExprState *qual, ProjectionInfo *projInfo)
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
void ExecInitResultTypeTL(PlanState *planstate)
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Relation ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags)
bool(* ExecScanRecheckMtd)(ScanState *node, TupleTableSlot *slot)
TupleTableSlot *(* ExecScanAccessMtd)(ScanState *node)
Assert(PointerIsAligned(start, uint64))
static TupleTableSlot * ExecSeqScanWithQual(PlanState *pstate)
void ExecSeqScanReInitializeDSM(SeqScanState *node, ParallelContext *pcxt)
void ExecSeqScanInitializeWorker(SeqScanState *node, ParallelWorkerContext *pwcxt)
void ExecEndSeqScan(SeqScanState *node)
static TupleTableSlot * ExecSeqScanWithQualProject(PlanState *pstate)
static TupleTableSlot * ExecSeqScan(PlanState *pstate)
SeqScanState * ExecInitSeqScan(SeqScan *node, EState *estate, int eflags)
void ExecSeqScanInitializeDSM(SeqScanState *node, ParallelContext *pcxt)
static TupleTableSlot * ExecSeqScanEPQ(PlanState *pstate)
static bool SeqRecheck(SeqScanState *node, TupleTableSlot *slot)
static TupleTableSlot * ExecSeqScanWithProject(PlanState *pstate)
void ExecSeqScanEstimate(SeqScanState *node, ParallelContext *pcxt)
static TupleTableSlot * SeqNext(SeqScanState *node)
void ExecReScanSeqScan(SeqScanState *node)
#define castNode(_type_, nodeptr)
#define RelationGetDescr(relation)
void * shm_toc_allocate(shm_toc *toc, Size nbytes)
void shm_toc_insert(shm_toc *toc, uint64 key, void *address)
void * shm_toc_lookup(shm_toc *toc, uint64 key, bool noError)
#define shm_toc_estimate_chunk(e, sz)
#define shm_toc_estimate_keys(e, cnt)
ScanDirection es_direction
struct EPQState * es_epq_active
shm_toc_estimator estimator
ProjectionInfo * ps_ProjInfo
ExecProcNodeMtd ExecProcNode
Relation ss_currentRelation
TupleTableSlot * ss_ScanTupleSlot
struct TableScanDescData * ss_currentScanDesc
struct ParallelTableScanDescData * rs_parallel
TableScanDesc table_beginscan_parallel(Relation relation, ParallelTableScanDesc pscan)
Size table_parallelscan_estimate(Relation rel, Snapshot snapshot)
void table_parallelscan_initialize(Relation rel, ParallelTableScanDesc pscan, Snapshot snapshot)
const TupleTableSlotOps * table_slot_callbacks(Relation relation)
static void table_endscan(TableScanDesc scan)
static void table_rescan(TableScanDesc scan, ScanKeyData *key)
static bool table_scan_getnextslot(TableScanDesc sscan, ScanDirection direction, TupleTableSlot *slot)
static TableScanDesc table_beginscan(Relation rel, Snapshot snapshot, int nkeys, ScanKeyData *key)
static void table_parallelscan_reinitialize(Relation rel, ParallelTableScanDesc pscan)