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 152 of file execScan.h.

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

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. The recheck method is responsible not
53 * only for rechecking the scan/join quals but also for storing
54 * the correct tuple in the slot.
55 */
56
57 TupleTableSlot *slot = node->ss_ScanTupleSlot;
58
59 if (!(*recheckMtd) (node, slot))
60 ExecClearTuple(slot); /* would not be returned by scan */
61 return slot;
62 }
63 else if (epqstate->relsubs_done[scanrelid - 1])
64 {
65 /*
66 * Return empty slot, as either there is no EPQ tuple for this rel
67 * or we already returned it.
68 */
69
70 TupleTableSlot *slot = node->ss_ScanTupleSlot;
71
72 return ExecClearTuple(slot);
73 }
74 else if (epqstate->relsubs_slot[scanrelid - 1] != NULL)
75 {
76 /*
77 * Return replacement tuple provided by the EPQ caller.
78 */
79
80 TupleTableSlot *slot = epqstate->relsubs_slot[scanrelid - 1];
81
82 Assert(epqstate->relsubs_rowmark[scanrelid - 1] == NULL);
83
84 /* Mark to remember that we shouldn't return it again */
85 epqstate->relsubs_done[scanrelid - 1] = true;
86
87 /* Return empty slot if we haven't got a test tuple */
88 if (TupIsNull(slot))
89 return NULL;
90
91 /* Check if it meets the access-method conditions */
92 if (!(*recheckMtd) (node, slot))
93 return ExecClearTuple(slot); /* would not be returned by
94 * scan */
95 return slot;
96 }
97 else if (epqstate->relsubs_rowmark[scanrelid - 1] != NULL)
98 {
99 /*
100 * Fetch and return replacement tuple using a non-locking rowmark.
101 */
102
103 TupleTableSlot *slot = node->ss_ScanTupleSlot;
104
105 /* Mark to remember that we shouldn't return more */
106 epqstate->relsubs_done[scanrelid - 1] = true;
107
108 if (!EvalPlanQualFetchRowMark(epqstate, scanrelid, slot))
109 return NULL;
110
111 /* Return empty slot if we haven't got a test tuple */
112 if (TupIsNull(slot))
113 return NULL;
114
115 /* Check if it meets the access-method conditions */
116 if (!(*recheckMtd) (node, slot))
117 return ExecClearTuple(slot); /* would not be returned by
118 * scan */
119 return slot;
120 }
121 }
122
123 /*
124 * Run the node-type-specific access method function to get the next tuple
125 */
126 return (*accessMtd) (node);
127}
#define Assert(condition)
Definition: c.h:815
unsigned int Index
Definition: c.h:571
bool EvalPlanQualFetchRowMark(EPQState *epqstate, Index rti, TupleTableSlot *slot)
Definition: execMain.c:2662
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:122
ExecAuxRowMark ** relsubs_rowmark
Definition: execnodes.h:1325
TupleTableSlot ** relsubs_slot
Definition: execnodes.h:1297
bool * relsubs_done
Definition: execnodes.h:1332
Plan * plan
Definition: execnodes.h:1150
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1606

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

Referenced by ExecScanExtended().