PostgreSQL Source Code git master
execScan.h File Reference
#include "miscadmin.h"
#include "executor/executor.h"
#include "nodes/execnodes.h"
Include dependency graph for execScan.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

static pg_attribute_always_inline TupleTableSlotExecScanFetch (ScanState *node, EPQState *epqstate, ExecScanAccessMtd accessMtd, ExecScanRecheckMtd recheckMtd)
 
static pg_attribute_always_inline TupleTableSlotExecScanExtended (ScanState *node, ExecScanAccessMtd accessMtd, ExecScanRecheckMtd recheckMtd, EPQState *epqstate, ExprState *qual, ProjectionInfo *projInfo)
 

Function Documentation

◆ ExecScanExtended()

static pg_attribute_always_inline TupleTableSlot * ExecScanExtended ( ScanState node,
ExecScanAccessMtd  accessMtd,
ExecScanRecheckMtd  recheckMtd,
EPQState epqstate,
ExprState qual,
ProjectionInfo projInfo 
)
static

Definition at line 160 of file execScan.h.

166{
167 ExprContext *econtext = node->ps.ps_ExprContext;
168
169 /* interrupt checks are in ExecScanFetch */
170
171 /*
172 * If we have neither a qual to check nor a projection to do, just skip
173 * all the overhead and return the raw scan tuple.
174 */
175 if (!qual && !projInfo)
176 {
177 ResetExprContext(econtext);
178 return ExecScanFetch(node, epqstate, accessMtd, recheckMtd);
179 }
180
181 /*
182 * Reset per-tuple memory context to free any expression evaluation
183 * storage allocated in the previous tuple cycle.
184 */
185 ResetExprContext(econtext);
186
187 /*
188 * get a tuple from the access method. Loop until we obtain a tuple that
189 * passes the qualification.
190 */
191 for (;;)
192 {
193 TupleTableSlot *slot;
194
195 slot = ExecScanFetch(node, epqstate, accessMtd, recheckMtd);
196
197 /*
198 * if the slot returned by the accessMtd contains NULL, then it means
199 * there is nothing more to scan so we just return an empty slot,
200 * being careful to use the projection result slot so it has correct
201 * tupleDesc.
202 */
203 if (TupIsNull(slot))
204 {
205 if (projInfo)
206 return ExecClearTuple(projInfo->pi_state.resultslot);
207 else
208 return slot;
209 }
210
211 /*
212 * place the current tuple into the expr context
213 */
214 econtext->ecxt_scantuple = slot;
215
216 /*
217 * check that the current tuple satisfies the qual-clause
218 *
219 * check for non-null qual here to avoid a function call to ExecQual()
220 * when the qual is null ... saves only a few cycles, but they add up
221 * ...
222 */
223 if (qual == NULL || ExecQual(qual, econtext))
224 {
225 /*
226 * Found a satisfactory scan tuple.
227 */
228 if (projInfo)
229 {
230 /*
231 * Form a projection tuple, store it in the result tuple slot
232 * and return it.
233 */
234 return ExecProject(projInfo);
235 }
236 else
237 {
238 /*
239 * Here, we aren't projecting, so just return scan tuple.
240 */
241 return slot;
242 }
243 }
244 else
245 InstrCountFiltered1(node, 1);
246
247 /*
248 * Tuple fails qual, so free per-tuple memory and try again.
249 */
250 ResetExprContext(econtext);
251 }
252}
static pg_attribute_always_inline TupleTableSlot * ExecScanFetch(ScanState *node, EPQState *epqstate, ExecScanAccessMtd accessMtd, ExecScanRecheckMtd recheckMtd)
Definition: execScan.h:32
#define InstrCountFiltered1(node, delta)
Definition: execnodes.h:1269
static TupleTableSlot * ExecProject(ProjectionInfo *projInfo)
Definition: executor.h:483
#define ResetExprContext(econtext)
Definition: executor.h:650
static bool ExecQual(ExprState *state, ExprContext *econtext)
Definition: executor.h:519
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:273
TupleTableSlot * resultslot
Definition: execnodes.h:104
ExprContext * ps_ExprContext
Definition: execnodes.h:1204
ExprState pi_state
Definition: execnodes.h:386
PlanState ps
Definition: execnodes.h:1621
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:457
#define TupIsNull(slot)
Definition: tuptable.h:309

References ExprContext::ecxt_scantuple, ExecClearTuple(), ExecProject(), ExecQual(), ExecScanFetch(), InstrCountFiltered1, ProjectionInfo::pi_state, ScanState::ps, PlanState::ps_ExprContext, ResetExprContext, ExprState::resultslot, and TupIsNull.

Referenced by ExecScan(), ExecSeqScan(), ExecSeqScanWithProject(), ExecSeqScanWithQual(), and ExecSeqScanWithQualProject().

◆ ExecScanFetch()

static pg_attribute_always_inline TupleTableSlot * ExecScanFetch ( ScanState node,
EPQState epqstate,
ExecScanAccessMtd  accessMtd,
ExecScanRecheckMtd  recheckMtd 
)
static

Definition at line 32 of file execScan.h.

36{
38
39 if (epqstate != NULL)
40 {
41 /*
42 * We are inside an EvalPlanQual recheck. Return the test tuple if
43 * one is available, after rechecking any access-method-specific
44 * conditions.
45 */
46 Index scanrelid = ((Scan *) node->ps.plan)->scanrelid;
47
48 if (scanrelid == 0)
49 {
50 /*
51 * This is a ForeignScan or CustomScan which has pushed down a
52 * join to the remote side. If it is a descendant node in the EPQ
53 * recheck plan tree, run the recheck method function. Otherwise,
54 * run the access method function below.
55 */
56 if (bms_is_member(epqstate->epqParam, node->ps.plan->extParam))
57 {
58 /*
59 * The recheck method is responsible not only for rechecking
60 * the scan/join quals but also for storing the correct tuple
61 * in the slot.
62 */
63
64 TupleTableSlot *slot = node->ss_ScanTupleSlot;
65
66 if (!(*recheckMtd) (node, slot))
67 ExecClearTuple(slot); /* would not be returned by scan */
68 return slot;
69 }
70 }
71 else if (epqstate->relsubs_done[scanrelid - 1])
72 {
73 /*
74 * Return empty slot, as either there is no EPQ tuple for this rel
75 * or we already returned it.
76 */
77
78 TupleTableSlot *slot = node->ss_ScanTupleSlot;
79
80 return ExecClearTuple(slot);
81 }
82 else if (epqstate->relsubs_slot[scanrelid - 1] != NULL)
83 {
84 /*
85 * Return replacement tuple provided by the EPQ caller.
86 */
87
88 TupleTableSlot *slot = epqstate->relsubs_slot[scanrelid - 1];
89
90 Assert(epqstate->relsubs_rowmark[scanrelid - 1] == NULL);
91
92 /* Mark to remember that we shouldn't return it again */
93 epqstate->relsubs_done[scanrelid - 1] = true;
94
95 /* Return empty slot if we haven't got a test tuple */
96 if (TupIsNull(slot))
97 return NULL;
98
99 /* Check if it meets the access-method conditions */
100 if (!(*recheckMtd) (node, slot))
101 return ExecClearTuple(slot); /* would not be returned by
102 * scan */
103 return slot;
104 }
105 else if (epqstate->relsubs_rowmark[scanrelid - 1] != NULL)
106 {
107 /*
108 * Fetch and return replacement tuple using a non-locking rowmark.
109 */
110
111 TupleTableSlot *slot = node->ss_ScanTupleSlot;
112
113 /* Mark to remember that we shouldn't return more */
114 epqstate->relsubs_done[scanrelid - 1] = true;
115
116 if (!EvalPlanQualFetchRowMark(epqstate, scanrelid, slot))
117 return NULL;
118
119 /* Return empty slot if we haven't got a test tuple */
120 if (TupIsNull(slot))
121 return NULL;
122
123 /* Check if it meets the access-method conditions */
124 if (!(*recheckMtd) (node, slot))
125 return ExecClearTuple(slot); /* would not be returned by
126 * scan */
127 return slot;
128 }
129 }
130
131 /*
132 * Run the node-type-specific access method function to get the next tuple
133 */
134 return (*accessMtd) (node);
135}
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:510
unsigned int Index
Definition: c.h:624
bool EvalPlanQualFetchRowMark(EPQState *epqstate, Index rti, TupleTableSlot *slot)
Definition: execMain.c:2805
Assert(PointerIsAligned(start, uint64))
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:123
ExecAuxRowMark ** relsubs_rowmark
Definition: execnodes.h:1340
TupleTableSlot ** relsubs_slot
Definition: execnodes.h:1312
int epqParam
Definition: execnodes.h:1302
bool * relsubs_done
Definition: execnodes.h:1347
Plan * plan
Definition: execnodes.h:1165
Bitmapset * extParam
Definition: plannodes.h:249
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1624

References Assert(), bms_is_member(), CHECK_FOR_INTERRUPTS, EPQState::epqParam, EvalPlanQualFetchRowMark(), ExecClearTuple(), Plan::extParam, PlanState::plan, ScanState::ps, EPQState::relsubs_done, EPQState::relsubs_rowmark, EPQState::relsubs_slot, ScanState::ss_ScanTupleSlot, and TupIsNull.

Referenced by ExecScanExtended().