PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
execScan.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * execScan.c
4 * This code provides support for generalized relation scans. ExecScan
5 * is passed a node and a pointer to a function to "do the right thing"
6 * and return a tuple from the relation. ExecScan then does the tedious
7 * stuff - checking the qualification and projecting the tuple
8 * appropriately.
9 *
10 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
11 * Portions Copyright (c) 1994, Regents of the University of California
12 *
13 *
14 * IDENTIFICATION
15 * src/backend/executor/execScan.c
16 *
17 *-------------------------------------------------------------------------
18 */
19#include "postgres.h"
20
21#include "executor/executor.h"
22#include "executor/execScan.h"
23#include "miscadmin.h"
24
25/* ----------------------------------------------------------------
26 * ExecScan
27 *
28 * Scans the relation using the 'access method' indicated and
29 * returns the next qualifying tuple.
30 * The access method returns the next tuple and ExecScan() is
31 * responsible for checking the tuple returned against the qual-clause.
32 *
33 * A 'recheck method' must also be provided that can check an
34 * arbitrary tuple of the relation against any qual conditions
35 * that are implemented internal to the access method.
36 *
37 * Conditions:
38 * -- the "cursor" maintained by the AMI is positioned at the tuple
39 * returned previously.
40 *
41 * Initial States:
42 * -- the relation indicated is opened for scanning so that the
43 * "cursor" is positioned before the first qualifying tuple.
44 * ----------------------------------------------------------------
45 */
48 ExecScanAccessMtd accessMtd, /* function returning a tuple */
49 ExecScanRecheckMtd recheckMtd)
50{
51 EPQState *epqstate;
52 ExprState *qual;
53 ProjectionInfo *projInfo;
54
55 epqstate = node->ps.state->es_epq_active;
56 qual = node->ps.qual;
57 projInfo = node->ps.ps_ProjInfo;
58
59 return ExecScanExtended(node,
60 accessMtd,
61 recheckMtd,
62 epqstate,
63 qual,
64 projInfo);
65}
66
67/*
68 * ExecAssignScanProjectionInfo
69 * Set up projection info for a scan node, if necessary.
70 *
71 * We can avoid a projection step if the requested tlist exactly matches
72 * the underlying tuple type. If so, we just set ps_ProjInfo to NULL.
73 * Note that this case occurs not only for simple "SELECT * FROM ...", but
74 * also in most cases where there are joins or other processing nodes above
75 * the scan node, because the planner will preferentially generate a matching
76 * tlist.
77 *
78 * The scan slot's descriptor must have been set already.
79 */
80void
82{
83 Scan *scan = (Scan *) node->ps.plan;
85
86 ExecConditionalAssignProjectionInfo(&node->ps, tupdesc, scan->scanrelid);
87}
88
89/*
90 * ExecAssignScanProjectionInfoWithVarno
91 * As above, but caller can specify varno expected in Vars in the tlist.
92 */
93void
95{
97
98 ExecConditionalAssignProjectionInfo(&node->ps, tupdesc, varno);
99}
100
101/*
102 * ExecScanReScan
103 *
104 * This must be called within the ReScan function of any plan node type
105 * that uses ExecScan().
106 */
107void
109{
110 EState *estate = node->ps.state;
111
112 /*
113 * We must clear the scan tuple so that observers (e.g., execCurrent.c)
114 * can tell that this plan node is not positioned on a tuple.
115 */
117
118 /*
119 * Rescan EvalPlanQual tuple(s) if we're inside an EvalPlanQual recheck.
120 * But don't lose the "blocked" status of blocked target relations.
121 */
122 if (estate->es_epq_active != NULL)
123 {
124 EPQState *epqstate = estate->es_epq_active;
125 Index scanrelid = ((Scan *) node->ps.plan)->scanrelid;
126
127 if (scanrelid > 0)
128 epqstate->relsubs_done[scanrelid - 1] =
129 epqstate->relsubs_blocked[scanrelid - 1];
130 else
131 {
132 Bitmapset *relids;
133 int rtindex = -1;
134
135 /*
136 * If an FDW or custom scan provider has replaced the join with a
137 * scan, there are multiple RTIs; reset the epqScanDone flag for
138 * all of them.
139 */
140 if (IsA(node->ps.plan, ForeignScan))
141 relids = ((ForeignScan *) node->ps.plan)->fs_base_relids;
142 else if (IsA(node->ps.plan, CustomScan))
143 relids = ((CustomScan *) node->ps.plan)->custom_relids;
144 else
145 elog(ERROR, "unexpected scan node: %d",
146 (int) nodeTag(node->ps.plan));
147
148 while ((rtindex = bms_next_member(relids, rtindex)) >= 0)
149 {
150 Assert(rtindex > 0);
151 epqstate->relsubs_done[rtindex - 1] =
152 epqstate->relsubs_blocked[rtindex - 1];
153 }
154 }
155 }
156}
int bms_next_member(const Bitmapset *a, int prevbit)
Definition: bitmapset.c:1306
unsigned int Index
Definition: c.h:585
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
void ExecAssignScanProjectionInfoWithVarno(ScanState *node, int varno)
Definition: execScan.c:94
TupleTableSlot * ExecScan(ScanState *node, ExecScanAccessMtd accessMtd, ExecScanRecheckMtd recheckMtd)
Definition: execScan.c:47
void ExecAssignScanProjectionInfo(ScanState *node)
Definition: execScan.c:81
void ExecScanReScan(ScanState *node)
Definition: execScan.c:108
static pg_attribute_always_inline TupleTableSlot * ExecScanExtended(ScanState *node, ExecScanAccessMtd accessMtd, ExecScanRecheckMtd recheckMtd, EPQState *epqstate, ExprState *qual, ProjectionInfo *projInfo)
Definition: execScan.h:152
void ExecConditionalAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc, int varno)
Definition: execUtils.c:604
bool(* ExecScanRecheckMtd)(ScanState *node, TupleTableSlot *slot)
Definition: executor.h:602
TupleTableSlot *(* ExecScanAccessMtd)(ScanState *node)
Definition: executor.h:601
Assert(PointerIsAligned(start, uint64))
#define IsA(nodeptr, _type_)
Definition: nodes.h:164
#define nodeTag(nodeptr)
Definition: nodes.h:139
bool * relsubs_blocked
Definition: execnodes.h:1350
bool * relsubs_done
Definition: execnodes.h:1341
struct EPQState * es_epq_active
Definition: execnodes.h:741
ExprState * qual
Definition: execnodes.h:1180
Plan * plan
Definition: execnodes.h:1159
EState * state
Definition: execnodes.h:1161
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:1199
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1618
PlanState ps
Definition: execnodes.h:1615
Index scanrelid
Definition: plannodes.h:483
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:123
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:458