1/*-------------------------------------------------------------------------
4 * miscellaneous executor access method routines
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
9 * src/backend/executor/execAmi.c
11 *-------------------------------------------------------------------------
71 * Reset a plan node so that its output can be re-scanned.
73 * Note that if the plan node has parameters that have changed value,
74 * the output might be different from last time.
79 /* If collecting timing stats, update them */
84 * If we have changed parameters, propagate that info.
86 * Note: ExecReScanSetParamPlan() can add bits to node->chgParam,
87 * corresponding to the output param(s) that the InitPlan will update.
88 * Since we make only one pass over the list, that means that an InitPlan
89 * can depend on the output param(s) of a sibling InitPlan only if that
90 * sibling appears earlier in the list. This is workable for now given
91 * the limited ways in which one InitPlan could depend on another, but
92 * eventually we might need to work harder (or else make the planner
93 * enlarge the extParam/allParam sets to include the params of depended-on
105 if (splan->
plan->
extParam != NULL)
/* don't care about child
119 /* Well. Now set chgParam for child trees. */
126 /* Call expression callbacks */
130 /* And do node-type-specific processing */
137 case T_ProjectSetState:
141 case T_ModifyTableState:
149 case T_MergeAppendState:
153 case T_RecursiveUnionState:
157 case T_BitmapAndState:
161 case T_BitmapOrState:
169 case T_SampleScanState:
177 case T_GatherMergeState:
181 case T_IndexScanState:
185 case T_IndexOnlyScanState:
189 case T_BitmapIndexScanState:
193 case T_BitmapHeapScanState:
201 case T_TidRangeScanState:
205 case T_SubqueryScanState:
209 case T_FunctionScanState:
213 case T_TableFuncScanState:
217 case T_ValuesScanState:
225 case T_NamedTuplestoreScanState:
229 case T_WorkTableScanState:
233 case T_ForeignScanState:
237 case T_CustomScanState:
241 case T_NestLoopState:
245 case T_MergeJoinState:
249 case T_HashJoinState:
253 case T_MaterialState:
265 case T_IncrementalSortState:
277 case T_WindowAggState:
293 case T_LockRowsState:
316 * Marks the current scan position.
318 * NOTE: mark/restore capability is currently needed only for plan nodes
319 * that are the immediate inner child of a MergeJoin node. Since MergeJoin
320 * requires sorted input, there is never any need to support mark/restore in
321 * node types that cannot produce sorted output. There are some cases in
322 * which a node can pass through sorted data from its child; if we don't
323 * implement mark/restore for such a node type, the planner compensates by
324 * inserting a Material node above that node.
331 case T_IndexScanState:
335 case T_IndexOnlyScanState:
339 case T_CustomScanState:
343 case T_MaterialState:
356 /* don't make hard error unless caller asks to restore... */
365 * restores the scan position previously saved with ExecMarkPos()
367 * NOTE: the semantics of this are that the first ExecProcNode following
368 * the restore operation will yield the same tuple as the first one following
369 * the mark operation. It is unspecified what happens to the plan node's
370 * result TupleTableSlot. (In most cases the result slot is unchanged by
371 * a restore, but the node may choose to clear it or to load it with the
372 * restored-to tuple.) Hence the caller should discard any previously
373 * returned TupleTableSlot after doing a restore.
380 case T_IndexScanState:
384 case T_IndexOnlyScanState:
388 case T_CustomScanState:
392 case T_MaterialState:
411 * ExecSupportsMarkRestore - does a Path support mark/restore?
413 * This is used during planning and so must accept a Path, not a Plan.
414 * We keep it here to be adjacent to the routines above, which also must
415 * know which plan types support mark/restore.
421 * For consistency with the routines above, we do not examine the nodeTag
422 * but rather the pathtype, which is the Plan node type the Path would
428 case T_IndexOnlyScan:
431 * Not all index types support mark/restore.
447 * Result supports mark/restore iff it has a child plan that does.
449 * We have to be careful here because there is more than one Path
450 * type that can produce a Result plan node.
455 return false;
/* childless Result */
457 return false;
/* childless Result */
460 /* Simple RTE_RESULT base relation */
462 return false;
/* childless Result */
470 * If there's exactly one child, then there will be no Append
471 * in the final plan, so we can handle mark/restore if the
472 * child plan node can.
476 /* Otherwise, Append can't handle it */
485 * Like the Append case above, single-subpath MergeAppends
486 * won't be in the final plan, so just return the child's
487 * mark/restore ability.
491 /* Otherwise, MergeAppend can't handle it */
503 * ExecSupportsBackwardScan - does a plan type support backwards scanning?
505 * Ideally, all plan types would support backwards scan, but that seems
506 * unlikely to happen soon. In some cases, a plan node passes the backwards
507 * scan down to its children, and so supports backwards scan only if its
508 * children do. Therefore, this routine must be passed a complete plan tree.
517 * Parallel-aware nodes return a subset of the tuples in each worker, and
518 * in general we can't expect to have enough bookkeeping state to know
519 * which ones we returned in this worker as opposed to some other worker.
536 /* With async, tuples may be interleaved, so can't back up. */
537 if (((
Append *) node)->nasyncplans > 0)
540 foreach(l, ((
Append *) node)->appendplans)
545 /* need not check tlist because Append doesn't evaluate it */
550 /* Simplify life for tablesample methods by disallowing this */
559 case T_IndexOnlyScan:
578 /* these don't evaluate tlist */
581 case T_IncrementalSort:
584 * Unlike full sort, incremental sort keeps only a single group of
585 * tuples in memory, so it can't scan backwards.
599 * An IndexScan or IndexOnlyScan node supports backward scan only if the
610 /* Fetch the pg_class tuple of the index relation */
613 elog(
ERROR,
"cache lookup failed for relation %u", indexid);
616 /* Fetch the index AM's API struct */
628 * ExecMaterializesOutput - does a plan type materialize its output?
630 * Returns true if the plan node type is one that automatically materializes
631 * its output (typically by keeping it in a tuplestore). For such plans,
632 * a rescan without any parameter change will have zero startup cost and
633 * very low per-tuple cost.
642 case T_TableFuncScan:
644 case T_NamedTuplestoreScan:
645 case T_WorkTableScan:
IndexAmRoutine * GetIndexAmRoutineByAmId(Oid amoid, bool noerror)
void bms_free(Bitmapset *a)
void ExecMarkPos(PlanState *node)
bool ExecSupportsMarkRestore(Path *pathnode)
static bool IndexSupportsBackwardScan(Oid indexid)
bool ExecMaterializesOutput(NodeTag plantype)
bool ExecSupportsBackwardScan(Plan *node)
void ExecReScan(PlanState *node)
void ExecRestrPos(PlanState *node)
void ReScanExprContext(ExprContext *econtext)
void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
#define outerPlanState(node)
#define innerPlanState(node)
#define CUSTOMPATH_SUPPORT_BACKWARD_SCAN
#define CUSTOMPATH_SUPPORT_MARK_RESTORE
Assert(PointerIsAligned(start, uint64))
#define HeapTupleIsValid(tuple)
static void * GETSTRUCT(const HeapTupleData *tuple)
void InstrEndLoop(Instrumentation *instr)
Datum subpath(PG_FUNCTION_ARGS)
void pfree(void *pointer)
void ExecReScanAgg(AggState *node)
void ExecReScanAppend(AppendState *node)
void ExecReScanBitmapAnd(BitmapAndState *node)
void ExecReScanBitmapHeapScan(BitmapHeapScanState *node)
void ExecReScanBitmapIndexScan(BitmapIndexScanState *node)
void ExecReScanBitmapOr(BitmapOrState *node)
void ExecReScanCteScan(CteScanState *node)
void ExecCustomRestrPos(CustomScanState *node)
void ExecReScanCustomScan(CustomScanState *node)
void ExecCustomMarkPos(CustomScanState *node)
void ExecReScanForeignScan(ForeignScanState *node)
void ExecReScanFunctionScan(FunctionScanState *node)
void ExecReScanGatherMerge(GatherMergeState *node)
void ExecReScanGather(GatherState *node)
void ExecReScanGroup(GroupState *node)
void ExecReScanHash(HashState *node)
void ExecReScanHashJoin(HashJoinState *node)
void ExecReScanIncrementalSort(IncrementalSortState *node)
void ExecReScanIndexOnlyScan(IndexOnlyScanState *node)
void ExecIndexOnlyRestrPos(IndexOnlyScanState *node)
void ExecIndexOnlyMarkPos(IndexOnlyScanState *node)
void ExecReScanIndexScan(IndexScanState *node)
void ExecIndexRestrPos(IndexScanState *node)
void ExecIndexMarkPos(IndexScanState *node)
void ExecReScanLimit(LimitState *node)
void ExecReScanLockRows(LockRowsState *node)
void ExecReScanMaterial(MaterialState *node)
void ExecMaterialMarkPos(MaterialState *node)
void ExecMaterialRestrPos(MaterialState *node)
void ExecReScanMemoize(MemoizeState *node)
void ExecReScanMergeAppend(MergeAppendState *node)
void ExecReScanMergeJoin(MergeJoinState *node)
void ExecReScanModifyTable(ModifyTableState *node)
void ExecReScanNamedTuplestoreScan(NamedTuplestoreScanState *node)
void ExecReScanNestLoop(NestLoopState *node)
void ExecReScanProjectSet(ProjectSetState *node)
void ExecReScanRecursiveUnion(RecursiveUnionState *node)
void ExecReScanResult(ResultState *node)
void ExecResultRestrPos(ResultState *node)
void ExecResultMarkPos(ResultState *node)
void ExecReScanSampleScan(SampleScanState *node)
void ExecReScanSeqScan(SeqScanState *node)
void ExecReScanSetOp(SetOpState *node)
void ExecSortMarkPos(SortState *node)
void ExecReScanSort(SortState *node)
void ExecSortRestrPos(SortState *node)
void ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent)
void ExecReScanSubqueryScan(SubqueryScanState *node)
void ExecReScanTableFuncScan(TableFuncScanState *node)
void ExecReScanTidRangeScan(TidRangeScanState *node)
void ExecReScanTidScan(TidScanState *node)
void ExecReScanUnique(UniqueState *node)
void ExecReScanValuesScan(ValuesScanState *node)
void ExecReScanWindowAgg(WindowAggState *node)
void ExecReScanWorkTableScan(WorkTableScanState *node)
#define IsA(nodeptr, _type_)
#define castNode(_type_, nodeptr)
FormData_pg_class * Form_pg_class
static int list_length(const List *l)
static Datum ObjectIdGetDatum(Oid X)
Instrumentation * instrument
ExprContext * ps_ExprContext
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache1(int cacheId, Datum key1)