1/*-------------------------------------------------------------------------
3 * Inline-able support functions for Scan nodes
5 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
6 * Portions Copyright (c) 1994, Regents of the University of California
9 * src/include/executor/execScan.h
10 *-------------------------------------------------------------------------
21 * ExecScanFetch -- check interrupts & fetch next potential tuple
23 * This routine substitutes a test tuple if inside an EvalPlanQual recheck.
24 * Otherwise, it simply executes the access method's next-tuple routine.
26 * The pg_attribute_always_inline attribute allows the compiler to inline
27 * this function into its caller. When EPQState is NULL, the EvalPlanQual
28 * logic is completely eliminated at compile time, avoiding unnecessary
29 * run-time checks and code for cases where EPQ is not required.
42 * We are inside an EvalPlanQual recheck. Return the test tuple if
43 * one is available, after rechecking any access-method-specific
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.
59 if (!(*recheckMtd) (node, slot))
66 * Return empty slot, as either there is no EPQ tuple for this rel
67 * or we already returned it.
77 * Return replacement tuple provided by the EPQ caller.
84 /* Mark to remember that we shouldn't return it again */
87 /* Return empty slot if we haven't got a test tuple */
91 /* Check if it meets the access-method conditions */
92 if (!(*recheckMtd) (node, slot))
100 * Fetch and return replacement tuple using a non-locking rowmark.
105 /* Mark to remember that we shouldn't return more */
111 /* Return empty slot if we haven't got a test tuple */
115 /* Check if it meets the access-method conditions */
116 if (!(*recheckMtd) (node, slot))
124 * Run the node-type-specific access method function to get the next tuple
126 return (*accessMtd) (node);
129/* ----------------------------------------------------------------
131 * Scans the relation using the specified 'access method' and returns the
132 * next tuple. Optionally checks the tuple against 'qual' and applies
133 * 'projInfo' if provided.
135 * The 'recheck method' validates an arbitrary tuple of the relation against
136 * conditions enforced by the access method.
138 * This function is an alternative to ExecScan, used when callers may omit
139 * 'qual' or 'projInfo'. The pg_attribute_always_inline attribute allows the
140 * compiler to eliminate non-relevant branches at compile time, avoiding
141 * run-time checks in those cases.
144 * -- The AMI "cursor" is positioned at the previously returned tuple.
147 * -- The relation is opened for scanning, with the "cursor"
148 * positioned before the first qualifying tuple.
149 * ----------------------------------------------------------------
161 /* interrupt checks are in ExecScanFetch */
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.
167 if (!qual && !projInfo)
174 * Reset per-tuple memory context to free any expression evaluation
175 * storage allocated in the previous tuple cycle.
180 * get a tuple from the access method. Loop until we obtain a tuple that
181 * passes the qualification.
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
204 * place the current tuple into the expr context
209 * check that the current tuple satisfies the qual-clause
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
215 if (qual == NULL ||
ExecQual(qual, econtext))
218 * Found a satisfactory scan tuple.
223 * Form a projection tuple, store it in the result tuple slot
231 * Here, we aren't projecting, so just return scan tuple.
240 * Tuple fails qual, so free per-tuple memory and try again.
246#endif /* EXECSCAN_H */
#define pg_attribute_always_inline
bool EvalPlanQualFetchRowMark(EPQState *epqstate, Index rti, TupleTableSlot *slot)
static pg_attribute_always_inline TupleTableSlot * ExecScanFetch(ScanState *node, EPQState *epqstate, ExecScanAccessMtd accessMtd, ExecScanRecheckMtd recheckMtd)
static pg_attribute_always_inline TupleTableSlot * ExecScanExtended(ScanState *node, ExecScanAccessMtd accessMtd, ExecScanRecheckMtd recheckMtd, EPQState *epqstate, ExprState *qual, ProjectionInfo *projInfo)
#define InstrCountFiltered1(node, delta)
static TupleTableSlot * ExecProject(ProjectionInfo *projInfo)
#define ResetExprContext(econtext)
static bool ExecQual(ExprState *state, ExprContext *econtext)
bool(* ExecScanRecheckMtd)(ScanState *node, TupleTableSlot *slot)
TupleTableSlot *(* ExecScanAccessMtd)(ScanState *node)
Assert(PointerIsAligned(start, uint64))
#define CHECK_FOR_INTERRUPTS()
ExecAuxRowMark ** relsubs_rowmark
TupleTableSlot ** relsubs_slot
TupleTableSlot * ecxt_scantuple
TupleTableSlot * resultslot
ExprContext * ps_ExprContext
TupleTableSlot * ss_ScanTupleSlot
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)