1/*-------------------------------------------------------------------------
4 * miscellaneous executor utility routines
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * src/backend/executor/execUtils.c
13 *-------------------------------------------------------------------------
17 * CreateExecutorState Create/delete executor working state
20 * CreateStandaloneExprContext
24 * ExecAssignExprContext Common code for plan node init routines.
27 * ExecOpenScanRelation Common code for scan node init routines.
29 * ExecInitRangeTable Set up executor's range-table-related data.
31 * ExecGetRangeTableRelation Fetch Relation for a rangetable entry.
33 * executor_errposition Report syntactic position of an error.
35 * RegisterExprContextCallback Register function shutdown callback
36 * UnregisterExprContextCallback Deregister function shutdown callback
38 * GetAttributeByName Runtime extraction of columns from tuples.
42 * This file has traditionally been the place to stick misc.
43 * executor support stuff that doesn't really go anyplace else.
70/* ----------------------------------------------------------------
71 * Executor state and memory management functions
72 * ----------------------------------------------------------------
78 * Create and initialize an EState node, which is the root of
79 * working storage for an entire Executor invocation.
81 * Principally, this creates the per-query memory context that will be
82 * used to hold all working data that lives till the end of the query.
83 * Note that the per-query context will become a child of the caller's
84 * CurrentMemoryContext.
95 * Create the per-query context for this Executor run.
102 * Make the EState node within the per-query context. This way, we don't
103 * need a separate pfree() operation for it at shutdown.
110 * Initialize all fields of the Executor State structure
169 * Return the executor state structure
179 * Release an EState along with all remaining working storage.
181 * Note: this is not responsible for releasing non-memory resources, such as
182 * open relations or buffer pins. But it will shut down any still-active
183 * ExprContexts within the EState and deallocate associated JITed expressions.
184 * That is sufficient cleanup for situations where the EState has only been
185 * used for expression evaluation, and not to run a complete Plan.
187 * This can be called in any memory context ... so long as it's not one
188 * of the ones to be freed.
195 * Shut down and free any remaining ExprContexts. We do this explicitly
196 * to ensure that any remaining shutdown callbacks get called (since they
197 * might need to release resources that aren't simply memory within the
198 * per-query memory context).
203 * XXX: seems there ought to be a faster way to implement this than
204 * repeated list_delete(), no?
208 /* FreeExprContext removed the list link for us */
211 /* release JIT context, if allocated */
218 /* release partition directory, if allocated */
226 * Free the per-query memory context, thereby releasing all working
227 * memory, including the EState node itself.
233 * Internal implementation for CreateExprContext() and CreateWorkExprContext()
234 * that allows control over the AllocSet parameters.
238 Size initBlockSize,
Size maxBlockSize)
243 /* Create the ExprContext node within the per-query memory context */
248 /* Initialize fields of ExprContext */
256 * Create working memory for expression evaluation in this context.
282 * Link the ExprContext into the EState to ensure it is shut down when the
283 * EState is freed. Because we use lcons(), shutdowns will occur in
284 * reverse order of creation, which may not be essential but can't hurt.
296 * Create a context for expression evaluation within an EState.
298 * An executor run may require multiple ExprContexts (we usually make one
299 * for each Plan node, and a separate one for per-output-tuple processing
300 * such as constraint checking). Each ExprContext has its own "per-tuple"
303 * Note we make no assumption about the caller's memory context.
314 * CreateWorkExprContext
316 * Like CreateExprContext, but specifies the AllocSet sizes to be reasonable
317 * in proportion to work_mem. If the maximum block allocation size is too
318 * large, it's easy to skip right past work_mem with a single allocation.
328 /* But no bigger than ALLOCSET_DEFAULT_MAXSIZE */
331 /* and no smaller than ALLOCSET_DEFAULT_INITSIZE */
339 * CreateStandaloneExprContext
341 * Create a context for standalone expression evaluation.
343 * An ExprContext made this way can be used for evaluation of expressions
344 * that contain no Params, subplans, or Var references (it might work to
345 * put tuple references into the scantuple field, but it seems unwise).
347 * The ExprContext struct is allocated in the caller's current memory
348 * context, which also becomes its "per query" context.
350 * It is caller's responsibility to free the ExprContext when done,
351 * or at least ensure that any shutdown callbacks have been called
352 * (ReScanExprContext() is suitable). Otherwise, non-memory resources
361 /* Create the ExprContext node within the caller's memory context */
364 /* Initialize fields of ExprContext */
372 * Create working memory for expression evaluation in this context.
401 * Free an expression context, including calling any remaining
402 * shutdown callbacks.
404 * Since we free the temporary context used for expression evaluation,
405 * any previously computed pass-by-reference expression result will go away!
407 * If isCommit is false, we are being called in error cleanup, and should
408 * not call callbacks but only release memory. (It might be better to call
409 * the callbacks and pass the isCommit flag to them, but that would require
410 * more invasive code changes than currently seems justified.)
412 * Note we make no assumption about the caller's memory context.
420 /* Call any registered callbacks */
422 /* And clean up the memory used */
424 /* Unlink self from owning EState, if any */
429 /* And delete the ExprContext node */
436 * Reset an expression context in preparation for a rescan of its
437 * plan node. This requires calling any registered shutdown callbacks,
438 * since any partially complete set-returning-functions must be canceled.
440 * Note we make no assumption about the caller's memory context.
445 /* Call any registered callbacks */
447 /* And clean up the memory used */
452 * Build a per-output-tuple ExprContext for an EState.
454 * This is normally invoked via GetPerTupleExprContext() macro,
467/* ----------------------------------------------------------------
468 * miscellaneous node-init support functions
470 * Note: all of these are expected to be called with CurrentMemoryContext
471 * equal to the per-query memory context.
472 * ----------------------------------------------------------------
476 * ExecAssignExprContext
478 * This initializes the ps_ExprContext field. It is only necessary
479 * to do this for nodes which use ExecQual or ExecProject
480 * because those routines require an econtext. Other nodes that
481 * don't have to evaluate expressions don't need to do this.
501 * ExecGetResultSlotOps - information about node's type of result slot
530 * ExecGetCommonSlotOps - identify common result slot type, if any
532 * If all the given PlanState nodes return the same fixed tuple slot type,
533 * return the slot ops struct for that slot type. Else, return NULL.
546 for (
int i = 1;
i < nplans;
i++)
553 if (result != thisops)
560 * ExecGetCommonChildSlotOps - as above, for the PlanState's standard children
574 * ExecAssignProjectionInfo
576 * forms the projection information from the node's targetlist
578 * Notes for inputDesc are same as for ExecBuildProjectionInfo: supply it
579 * for a relation-scan node, can pass NULL for upper-level nodes
596 * ExecConditionalAssignProjectionInfo
598 * as ExecAssignProjectionInfo, but store NULL rather than building projection
599 * info if no projection is required
632 int numattrs = tupdesc->
natts;
636 /* Check the tlist attributes */
637 for (attrno = 1; attrno <= numattrs; attrno++)
642 if (tlist_item == NULL)
643 return false;
/* tlist too short */
645 if (!var || !
IsA(var,
Var))
646 return false;
/* tlist item not a Var */
647 /* if these Asserts fail, planner messed up */
651 return false;
/* out of order */
652 if (att_tup->attisdropped)
653 return false;
/* table contains dropped columns */
654 if (att_tup->atthasmissing)
655 return false;
/* table contains cols with missing values */
658 * Note: usually the Var's type should match the tupdesc exactly, but
659 * in situations involving unions of columns that have different
660 * typmods, the Var may have come from above the union and hence have
661 * typmod -1. This is a legitimate situation since the Var still
662 * describes the column, just not as exactly as the tupdesc does. We
663 * could change the planner to prevent it, but it'd then insert
664 * projection steps just to convert from specific typmod to typmod -1,
665 * which is pretty silly.
667 if (var->vartype != att_tup->atttypid ||
668 (var->vartypmod != att_tup->atttypmod &&
669 var->vartypmod != -1))
670 return false;
/* type mismatch */
672 tlist_item =
lnext(tlist, tlist_item);
676 return false;
/* tlist too long */
682/* ----------------------------------------------------------------
684 * ----------------------------------------------------------------
700 * ExecCreateScanSlotFromOuterPlan
717/* ----------------------------------------------------------------
718 * ExecRelationIsTargetRelation
720 * Detect whether a relation (identified by rangetable index)
721 * is one of the target relations of the query.
723 * Note: This is currently no longer used in core. We keep it around
724 * because FDWs may wish to use it to determine if their foreign table
725 * is a target relation.
726 * ----------------------------------------------------------------
734/* ----------------------------------------------------------------
735 * ExecOpenScanRelation
737 * Open the heap relation to be scanned by a base-level scan plan node.
738 * This should be called during the node's ExecInit routine.
739 * ----------------------------------------------------------------
746 /* Open the relation. */
750 * Complain if we're attempting a scan of an unscannable relation, except
751 * when the query won't actually be run. This is a slightly klugy place
752 * to do this, perhaps, but there is no better place.
757 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
758 errmsg(
"materialized view \"%s\" has not been populated",
760 errhint(
"Use the REFRESH MATERIALIZED VIEW command.")));
767 * Set up executor's range-table-related data
769 * In addition to the range table proper, initialize arrays that are
770 * indexed by rangetable index.
776 /* Remember the range table List as-is */
779 /* ... and the RTEPermissionInfo List too */
782 /* Set size of associated arrays */
786 * Initialize the bitmapset of RT indexes (es_unpruned_relids)
787 * representing relations that will be scanned during execution. This set
788 * is initially populated by the caller and may be extended later by
789 * ExecDoInitialPruning() to include RT indexes of unpruned leaf
795 * Allocate an array to store an open Relation corresponding to each
796 * rangetable entry, and initialize entries to NULL. Relations are opened
797 * and stored here as needed.
803 * es_result_relations and es_rowmarks are also parallel to
804 * es_range_table, but are allocated only if needed.
811 * ExecGetRangeTableRelation
812 * Open the Relation for a range table entry, if not already done
814 * The Relations will be closed in ExecEndPlan().
816 * If isResultRel is true, the relation is being used as a result relation.
817 * Such a relation might have been pruned, which is OK for result relations,
818 * but not for scan relations; see the details in ExecInitModifyTable(). If
819 * isResultRel is false, the caller must ensure that 'rti' refers to an
820 * unpruned relation (i.e., it is a member of estate->es_unpruned_relids)
821 * before calling this function. Attempting to open a pruned relation for
822 * scanning will result in an error.
829 Assert(rti > 0 && rti <= estate->es_range_table_size);
832 elog(
ERROR,
"trying to open a pruned relation");
837 /* First time through, so open the relation */
845 * In a normal query, we should already have the appropriate lock,
846 * but verify that through an Assert. Since there's already an
847 * Assert inside table_open that insists on holding some lock, it
848 * seems sufficient to check this only when rellockmode is higher
858 * If we are a parallel worker, we need to obtain our own local
859 * lock on the relation. This ensures sane behavior in case the
860 * parent process exits before we do.
862 rel =
table_open(rte->relid, rte->rellockmode);
872 * ExecInitResultRelation
873 * Open relation given by the passed-in RT index and fill its
876 * Here, we also save the ResultRelInfo in estate->es_result_relations array
877 * such that it can be accessed later using the RT index.
898 * Saving in the list allows to avoid needlessly traversing the whole
899 * array when only a few of its entries are possibly non-NULL.
906 * UpdateChangedParamSet
907 * Add changed parameters to a plan node's chgParam set
915 * The plan node only depends on params listed in its allParam set. Don't
916 * include anything else into its chgParam set.
923 * executor_errposition
924 * Report an execution-time cursor position, if possible.
926 * This is expected to be used within an ereport() call. The return value
927 * is a dummy (always 0, in fact).
929 * The locations stored in parsetrees are byte offsets into the source string.
930 * We have to convert them to 1-based character indexes for reporting to
931 * clients. (We do things this way to avoid unnecessary overhead in the
932 * normal non-error case: computing character indexes would be much more
933 * expensive than storing token offsets.)
940 /* No-op if location was not provided */
943 /* Can't do anything if source text is not available */
946 /* Convert offset to character number */
948 /* And pass it to the ereport mechanism */
953 * Register a shutdown callback in an ExprContext.
955 * Shutdown callbacks will be called (in reverse order of registration)
956 * when the ExprContext is deleted or rescanned. This provides a hook
957 * for functions called in the context to do any cleanup needed --- it's
958 * particularly useful for functions returning sets. Note that the
959 * callback will *not* be called in the event that execution is aborted
969 /* Save the info in appropriate memory context */
977 /* link to front of list for appropriate execution order */
983 * Deregister a shutdown callback in an ExprContext.
985 * Any list entries matching the function and arg will be removed.
986 * This can be used if it's no longer necessary to call the callback.
998 while ((ecxt_callback = *prev_callback) != NULL)
1002 *prev_callback = ecxt_callback->
next;
1003 pfree(ecxt_callback);
1006 prev_callback = &ecxt_callback->
next;
1011 * Call all the shutdown callbacks registered in an ExprContext.
1013 * The callback list is emptied (important in case this is only a rescan
1014 * reset, and not deletion of the ExprContext).
1016 * If isCommit is false, just clean the callback list but don't call 'em.
1017 * (See comment for FreeExprContext.)
1025 /* Fast path in normal case where there's nothing to do. */
1030 * Call the callbacks in econtext's per-tuple context. This ensures that
1031 * any memory they might leak will get cleaned up.
1036 * Call each callback function in reverse registration order.
1043 pfree(ecxt_callback);
1050 * GetAttributeByName
1053 * These functions return the value of the requested attribute
1054 * out of the given tuple Datum.
1055 * C functions which take a tuple as an argument are expected
1056 * to use these. Ex: overpaid(EMP) might call GetAttributeByNum().
1057 * Note: these are actually rather slow because they do a typcache
1058 * lookup on each call.
1075 elog(
ERROR,
"a NULL isNull pointer was passed");
1079 /* Kinda bogus but compatible with old behavior... */
1089 for (
i = 0;
i < tupDesc->
natts;
i++)
1095 attrno = att->attnum;
1104 * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
1105 * the fields in the struct just in case user tries to inspect system
1135 elog(
ERROR,
"invalid attribute number %d", attrno);
1138 elog(
ERROR,
"a NULL isNull pointer was passed");
1142 /* Kinda bogus but compatible with old behavior... */
1152 * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
1153 * the fields in the struct just in case user tries to inspect system
1172 * Number of items in a tlist (including any resjunk items!)
1177 /* This used to be more complex, but fjoins are dead */
1182 * Number of items in a tlist, not including any resjunk items
1190 foreach(tl, targetlist)
1194 if (!curTle->resjunk)
1201 * Return a relInfo's tuple slot for a trigger's OLD tuples.
1223 * Return a relInfo's tuple slot for a trigger's NEW tuples.
1245 * Return a relInfo's tuple slot for processing returning tuples.
1267 * Return a relInfo's all-NULL tuple slot for processing returning tuples.
1269 * Note: this slot is intentionally filled with NULLs in every column, and
1270 * should be considered read-only --- the caller must not update it.
1295 * Return the map needed to convert given child result relation's tuples to
1296 * the rowtype of the query's main target ("root") relation. Note that a
1297 * NULL result is valid and means that no conversion is needed.
1302 /* If we didn't already do so, compute the map for this child. */
1311 else /* this isn't a child result rel */
1321 * Returns the map needed to convert given root result relation's tuples to
1322 * the rowtype of the given child relation. Note that a NULL result is valid
1323 * and means that no conversion is needed.
1328 /* Mustn't get called for a non-child result relation. */
1331 /* If we didn't already do so, compute the map for this child. */
1342 * When this child table is not a partition (!relispartition), it may
1343 * have columns that are not present in the root table, which we ask
1344 * to ignore by passing true for missing_ok.
1348 !childrel->
rd_rel->relispartition);
1359/* Return a bitmap representing columns being inserted */
1365 if (perminfo == NULL)
1368 /* Map the columns to child's attribute numbers if needed. */
1380/* Return a bitmap representing columns being updated */
1386 if (perminfo == NULL)
1389 /* Map the columns to child's attribute numbers if needed. */
1401/* Return a bitmap representing generated columns being updated */
1405 /* Compute the info if we didn't already */
1412 * Return columns being updated, including generated columns
1414 * The bitmap is allocated in per-tuple memory context. It's up to the caller to
1415 * copy it into a different context with the appropriate lifespan, if needed.
1434 * GetResultRTEPermissionInfo
1435 * Looks up RTEPermissionInfo for ExecGet*Cols() routines
1447 * For inheritance child result relations (a partition routing target
1448 * of an INSERT or a child UPDATE target), this returns the root
1449 * parent's RTE to fetch the RTEPermissionInfo because that's the only
1450 * one that has one assigned.
1457 * Non-child result relation should have their own RTEPermissionInfo.
1464 * The relation isn't in the range table and it isn't a partition
1465 * routing target. This ResultRelInfo must've been created only for
1466 * firing triggers and the relation is not being inserted into. (See
1467 * ExecGetTriggerResultRel.)
1482 * ExecGetResultRelCheckAsUser
1483 * Returns the user to modify passed-in result relation as
1485 * The user is chosen by looking up the relation's or, if a child table, its
1486 * root parent's RTEPermissionInfo.
1493 /* XXX - maybe ok to return GetUserId() in this case? */
1494 if (perminfo == NULL)
1495 elog(
ERROR,
"no RTEPermissionInfo found for result relation with OID %u",
AttrMap * build_attrmap_by_name_if_req(TupleDesc indesc, TupleDesc outdesc, bool missing_ok)
#define AttributeNumberIsValid(attributeNumber)
#define InvalidAttrNumber
Bitmapset * bms_intersect(const Bitmapset *a, const Bitmapset *b)
bool bms_is_member(int x, const Bitmapset *a)
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
Bitmapset * bms_join(Bitmapset *a, Bitmapset *b)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
int errposition(int cursorpos)
#define ereport(elevel,...)
ProjectionInfo * ExecBuildProjectionInfo(List *targetList, ExprContext *econtext, TupleTableSlot *slot, PlanState *parent, TupleDesc inputDesc)
void InitResultRelInfo(ResultRelInfo *resultRelInfo, Relation resultRelationDesc, Index resultRelationIndex, ResultRelInfo *partition_root_rri, int instrument_options)
const TupleTableSlotOps TTSOpsVirtual
void ExecInitResultSlot(PlanState *planstate, const TupleTableSlotOps *tts_ops)
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc)
TupleTableSlot * ExecStoreAllNullTuple(TupleTableSlot *slot)
TupleDesc ExecGetResultType(PlanState *planstate)
Relation ExecGetRangeTableRelation(EState *estate, Index rti, bool isResultRel)
TupleConversionMap * ExecGetRootToChildMap(ResultRelInfo *resultRelInfo, EState *estate)
Bitmapset * ExecGetExtraUpdatedCols(ResultRelInfo *relinfo, EState *estate)
static void ShutdownExprContext(ExprContext *econtext, bool isCommit)
Bitmapset * ExecGetInsertedCols(ResultRelInfo *relinfo, EState *estate)
TupleTableSlot * ExecGetTriggerNewSlot(EState *estate, ResultRelInfo *relInfo)
void ReScanExprContext(ExprContext *econtext)
ExprContext * CreateExprContext(EState *estate)
static RTEPermissionInfo * GetResultRTEPermissionInfo(ResultRelInfo *relinfo, EState *estate)
TupleConversionMap * ExecGetChildToRootMap(ResultRelInfo *resultRelInfo)
ExprContext * CreateStandaloneExprContext(void)
TupleTableSlot * ExecGetTriggerOldSlot(EState *estate, ResultRelInfo *relInfo)
int executor_errposition(EState *estate, int location)
Datum GetAttributeByNum(HeapTupleHeader tuple, AttrNumber attrno, bool *isNull)
void FreeExprContext(ExprContext *econtext, bool isCommit)
void ExecInitRangeTable(EState *estate, List *rangeTable, List *permInfos, Bitmapset *unpruned_relids)
static bool tlist_matches_tupdesc(PlanState *ps, List *tlist, int varno, TupleDesc tupdesc)
Bitmapset * ExecGetUpdatedCols(ResultRelInfo *relinfo, EState *estate)
const TupleTableSlotOps * ExecGetCommonSlotOps(PlanState **planstates, int nplans)
void ExecInitResultRelation(EState *estate, ResultRelInfo *resultRelInfo, Index rti)
void ExecCreateScanSlotFromOuterPlan(EState *estate, ScanState *scanstate, const TupleTableSlotOps *tts_ops)
void ExecAssignExprContext(EState *estate, PlanState *planstate)
void ExecAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc)
ExprContext * MakePerTupleExprContext(EState *estate)
void UnregisterExprContextCallback(ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
void ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc)
const TupleTableSlotOps * ExecGetCommonChildSlotOps(PlanState *ps)
void ExecConditionalAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc, int varno)
void RegisterExprContextCallback(ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
int ExecTargetListLength(List *targetlist)
void FreeExecutorState(EState *estate)
bool ExecRelationIsTargetRelation(EState *estate, Index scanrelid)
static ExprContext * CreateExprContextInternal(EState *estate, Size minContextSize, Size initBlockSize, Size maxBlockSize)
TupleTableSlot * ExecGetAllNullSlot(EState *estate, ResultRelInfo *relInfo)
int ExecCleanTargetListLength(List *targetlist)
ExprContext * CreateWorkExprContext(EState *estate)
void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
const TupleTableSlotOps * ExecGetResultSlotOps(PlanState *planstate, bool *isfixed)
Datum GetAttributeByName(HeapTupleHeader tuple, const char *attname, bool *isNull)
Bitmapset * ExecGetAllUpdatedCols(ResultRelInfo *relinfo, EState *estate)
TupleTableSlot * ExecGetReturningSlot(EState *estate, ResultRelInfo *relInfo)
Relation ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags)
Oid ExecGetResultRelCheckAsUser(ResultRelInfo *relInfo, EState *estate)
EState * CreateExecutorState(void)
#define outerPlanState(node)
#define innerPlanState(node)
#define EXEC_FLAG_WITH_NO_DATA
static RangeTblEntry * exec_rt_fetch(Index rti, EState *estate)
#define GetPerTupleMemoryContext(estate)
#define EXEC_FLAG_EXPLAIN_ONLY
void(* ExprContextCallbackFunction)(Datum arg)
Assert(PointerIsAligned(start, uint64))
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
static int32 HeapTupleHeaderGetTypMod(const HeapTupleHeaderData *tup)
static uint32 HeapTupleHeaderGetDatumLength(const HeapTupleHeaderData *tup)
static Oid HeapTupleHeaderGetTypeId(const HeapTupleHeaderData *tup)
#define IsParallelWorker()
static void ItemPointerSetInvalid(ItemPointerData *pointer)
void jit_release_context(JitContext *context)
List * list_delete_ptr(List *list, void *datum)
List * lappend(List *list, void *datum)
List * lcons(void *datum, List *list)
bool list_member_int(const List *list, int datum)
bool CheckRelationLockedByMe(Relation relation, LOCKMODE lockmode, bool orstronger)
int pg_mbstrlen_with_len(const char *mbstr, int limit)
void * MemoryContextAlloc(MemoryContext context, Size size)
void MemoryContextReset(MemoryContext context)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
void MemoryContextDelete(MemoryContext context)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_MAXSIZE
#define ALLOCSET_DEFAULT_MINSIZE
#define ALLOCSET_DEFAULT_SIZES
#define ALLOCSET_DEFAULT_INITSIZE
int namestrcmp(Name name, const char *str)
void ExecInitGenerated(ResultRelInfo *resultRelInfo, EState *estate, CmdType cmdtype)
#define IsA(nodeptr, _type_)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
RTEPermissionInfo * getRTEPermissionInfo(List *rteperminfos, RangeTblEntry *rte)
void DestroyPartitionDirectory(PartitionDirectory pdir)
FormData_pg_attribute * Form_pg_attribute
on_exit_nicely_callback function
#define pg_prevpower2_size_t
#define lfirst_node(type, lc)
static int list_length(const List *l)
static ListCell * list_head(const List *l)
static ListCell * lnext(const List *l, const ListCell *c)
#define RelationGetRelid(relation)
#define RelationIsScannable(relation)
#define RelationGetDescr(relation)
#define RelationGetRelationName(relation)
List * es_part_prune_infos
int es_parallel_workers_to_launch
List * es_tuple_routing_result_relations
struct JitContext * es_jit
PlannedStmt * es_plannedstmt
QueryEnvironment * es_queryEnv
ResultRelInfo ** es_result_relations
ParamExecData * es_param_exec_vals
uint64 es_total_processed
Bitmapset * es_unpruned_relids
ParamListInfo es_param_list_info
ExecRowMark ** es_rowmarks
List * es_insert_pending_result_relations
MemoryContext es_query_cxt
ScanDirection es_direction
PartitionDirectory es_partition_directory
List * es_trig_target_relations
List * es_opened_result_relations
bool es_use_parallel_mode
ExprContext * es_per_tuple_exprcontext
int es_parallel_workers_launched
Index es_range_table_size
List * es_insert_pending_modifytables
const char * es_sourceText
List * es_auxmodifytables
JunkFilter * es_junkFilter
Snapshot es_crosscheck_snapshot
struct ExprContext_CB * next
ExprContextCallbackFunction function
ParamListInfo ecxt_param_list_info
MemoryContext ecxt_per_tuple_memory
TupleTableSlot * ecxt_innertuple
ParamExecData * ecxt_param_exec_vals
TupleTableSlot * ecxt_scantuple
MemoryContext ecxt_per_query_memory
ExprContext_CB * ecxt_callbacks
struct EState * ecxt_estate
TupleTableSlot * ecxt_outertuple
const TupleTableSlotOps * resultops
const TupleTableSlotOps * scanops
TupleDesc ps_ResultTupleDesc
ExprContext * ps_ExprContext
TupleTableSlot * ps_ResultTupleSlot
ProjectionInfo * ps_ProjInfo
TupleConversionMap * ri_RootToChildMap
struct ResultRelInfo * ri_RootResultRelInfo
TupleTableSlot * ri_ReturningSlot
bool ri_extraUpdatedCols_valid
bool ri_RootToChildMapValid
TupleTableSlot * ri_AllNullSlot
Bitmapset * ri_extraUpdatedCols
TupleConversionMap * ri_ChildToRootMap
bool ri_ChildToRootMapValid
TupleTableSlot * ri_TrigNewSlot
TupleTableSlot * ri_TrigOldSlot
TupleTableSlot * ss_ScanTupleSlot
const TupleTableSlotOps *const tts_ops
Relation table_open(Oid relationId, LOCKMODE lockmode)
const TupleTableSlotOps * table_slot_callbacks(Relation relation)
TupleConversionMap * convert_tuples_by_name(TupleDesc indesc, TupleDesc outdesc)
TupleConversionMap * convert_tuples_by_name_attrmap(TupleDesc indesc, TupleDesc outdesc, AttrMap *attrMap)
Bitmapset * execute_attr_map_cols(AttrMap *attrMap, Bitmapset *in_cols)
#define ReleaseTupleDesc(tupdesc)
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)