PostgreSQL Source Code  git master
execUtils.c File Reference
#include "postgres.h"
#include "access/relscan.h"
#include "access/transam.h"
#include "executor/executor.h"
#include "mb/pg_wchar.h"
#include "nodes/nodeFuncs.h"
#include "parser/parsetree.h"
#include "storage/lmgr.h"
#include "utils/builtins.h"
#include "utils/memutils.h"
#include "utils/rel.h"
#include "utils/typcache.h"
Include dependency graph for execUtils.c:

Go to the source code of this file.

Functions

static bool tlist_matches_tupdesc (PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc)
 
static void ShutdownExprContext (ExprContext *econtext, bool isCommit)
 
EStateCreateExecutorState (void)
 
void FreeExecutorState (EState *estate)
 
ExprContextCreateExprContext (EState *estate)
 
ExprContextCreateStandaloneExprContext (void)
 
void FreeExprContext (ExprContext *econtext, bool isCommit)
 
void ReScanExprContext (ExprContext *econtext)
 
ExprContextMakePerTupleExprContext (EState *estate)
 
void ExecAssignExprContext (EState *estate, PlanState *planstate)
 
void ExecAssignResultType (PlanState *planstate, TupleDesc tupDesc)
 
void ExecAssignResultTypeFromTL (PlanState *planstate)
 
TupleDesc ExecGetResultType (PlanState *planstate)
 
void ExecAssignProjectionInfo (PlanState *planstate, TupleDesc inputDesc)
 
void ExecConditionalAssignProjectionInfo (PlanState *planstate, TupleDesc inputDesc, Index varno)
 
void ExecFreeExprContext (PlanState *planstate)
 
void ExecAssignScanType (ScanState *scanstate, TupleDesc tupDesc)
 
void ExecAssignScanTypeFromOuterPlan (ScanState *scanstate)
 
bool ExecRelationIsTargetRelation (EState *estate, Index scanrelid)
 
Relation ExecOpenScanRelation (EState *estate, Index scanrelid, int eflags)
 
void ExecCloseScanRelation (Relation scanrel)
 
void UpdateChangedParamSet (PlanState *node, Bitmapset *newchg)
 
int executor_errposition (EState *estate, int location)
 
void RegisterExprContextCallback (ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
 
void UnregisterExprContextCallback (ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
 
void ExecLockNonLeafAppendTables (List *partitioned_rels, EState *estate)
 
Datum GetAttributeByName (HeapTupleHeader tuple, const char *attname, bool *isNull)
 
Datum GetAttributeByNum (HeapTupleHeader tuple, AttrNumber attrno, bool *isNull)
 
int ExecTargetListLength (List *targetlist)
 
int ExecCleanTargetListLength (List *targetlist)
 

Function Documentation

◆ CreateExecutorState()

EState* CreateExecutorState ( void  )

Definition at line 81 of file execUtils.c.

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, CurrentMemoryContext, EState::es_auxmodifytables, EState::es_crosscheck_snapshot, EState::es_direction, EState::es_epqScanDone, EState::es_epqTuple, EState::es_epqTupleSet, EState::es_exprcontexts, EState::es_finished, EState::es_instrument, EState::es_junkFilter, EState::es_lastoid, EState::es_leaf_result_relations, EState::es_num_result_relations, EState::es_num_root_result_relations, EState::es_output_cid, EState::es_param_exec_vals, EState::es_param_list_info, EState::es_per_tuple_exprcontext, EState::es_plannedstmt, EState::es_processed, EState::es_query_cxt, EState::es_queryEnv, EState::es_range_table, EState::es_result_relation_info, EState::es_result_relations, EState::es_root_result_relations, EState::es_rowMarks, EState::es_snapshot, EState::es_sourceText, EState::es_subplanstates, EState::es_top_eflags, EState::es_trig_newtup_slot, EState::es_trig_oldtup_slot, EState::es_trig_target_relations, EState::es_trig_tuple_slot, EState::es_tupleTable, EState::es_use_parallel_mode, ForwardScanDirection, InvalidOid, InvalidSnapshot, makeNode, MemoryContextSwitchTo(), and NIL.

Referenced by afterTriggerInvokeEvents(), ATRewriteTable(), check_default_allows_bound(), compute_index_stats(), CopyFrom(), create_estate_for_relation(), EvalPlanQualStart(), evaluate_expr(), ExecuteCallStmt(), ExecuteQuery(), ExecuteTruncate(), ExplainExecuteQuery(), get_actual_variable_range(), get_qual_for_range(), IndexBuildHeapRangeScan(), IndexCheckExclusion(), operator_predicate_proof(), plpgsql_create_econtext(), plpgsql_inline_handler(), standard_ExecutorStart(), tuplesort_begin_cluster(), unique_key_recheck(), validate_index_heapscan(), validateCheckConstraint(), and validateDomainConstraint().

82 {
83  EState *estate;
84  MemoryContext qcontext;
85  MemoryContext oldcontext;
86 
87  /*
88  * Create the per-query context for this Executor run.
89  */
91  "ExecutorState",
93 
94  /*
95  * Make the EState node within the per-query context. This way, we don't
96  * need a separate pfree() operation for it at shutdown.
97  */
98  oldcontext = MemoryContextSwitchTo(qcontext);
99 
100  estate = makeNode(EState);
101 
102  /*
103  * Initialize all fields of the Executor State structure
104  */
106  estate->es_snapshot = InvalidSnapshot; /* caller must initialize this */
107  estate->es_crosscheck_snapshot = InvalidSnapshot; /* no crosscheck */
108  estate->es_range_table = NIL;
109  estate->es_plannedstmt = NULL;
110 
111  estate->es_junkFilter = NULL;
112 
113  estate->es_output_cid = (CommandId) 0;
114 
115  estate->es_result_relations = NULL;
116  estate->es_num_result_relations = 0;
117  estate->es_result_relation_info = NULL;
118 
119  estate->es_root_result_relations = NULL;
120  estate->es_num_root_result_relations = 0;
121 
122  estate->es_leaf_result_relations = NIL;
123 
124  estate->es_trig_target_relations = NIL;
125  estate->es_trig_tuple_slot = NULL;
126  estate->es_trig_oldtup_slot = NULL;
127  estate->es_trig_newtup_slot = NULL;
128 
129  estate->es_param_list_info = NULL;
130  estate->es_param_exec_vals = NULL;
131 
132  estate->es_queryEnv = NULL;
133 
134  estate->es_query_cxt = qcontext;
135 
136  estate->es_tupleTable = NIL;
137 
138  estate->es_rowMarks = NIL;
139 
140  estate->es_processed = 0;
141  estate->es_lastoid = InvalidOid;
142 
143  estate->es_top_eflags = 0;
144  estate->es_instrument = 0;
145  estate->es_finished = false;
146 
147  estate->es_exprcontexts = NIL;
148 
149  estate->es_subplanstates = NIL;
150 
151  estate->es_auxmodifytables = NIL;
152 
153  estate->es_per_tuple_exprcontext = NULL;
154 
155  estate->es_epqTuple = NULL;
156  estate->es_epqTupleSet = NULL;
157  estate->es_epqScanDone = NULL;
158  estate->es_sourceText = NULL;
159 
160  estate->es_use_parallel_mode = false;
161 
162  /*
163  * Return the executor state structure
164  */
165  MemoryContextSwitchTo(oldcontext);
166 
167  return estate;
168 }
#define NIL
Definition: pg_list.h:69
uint32 CommandId
Definition: c.h:469
HeapTuple * es_epqTuple
Definition: execnodes.h:517
JunkFilter * es_junkFilter
Definition: execnodes.h:446
CommandId es_output_cid
Definition: execnodes.h:449
TupleTableSlot * es_trig_newtup_slot
Definition: execnodes.h:473
Oid es_lastoid
Definition: execnodes.h:489
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
PlannedStmt * es_plannedstmt
Definition: execnodes.h:443
Snapshot es_crosscheck_snapshot
Definition: execnodes.h:441
ExprContext * es_per_tuple_exprcontext
Definition: execnodes.h:506
Snapshot es_snapshot
Definition: execnodes.h:440
List * es_range_table
Definition: execnodes.h:442
ScanDirection es_direction
Definition: execnodes.h:439
bool es_use_parallel_mode
Definition: execnodes.h:521
const char * es_sourceText
Definition: execnodes.h:444
ParamExecData * es_param_exec_vals
Definition: execnodes.h:477
MemoryContext es_query_cxt
Definition: execnodes.h:482
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:197
ResultRelInfo * es_result_relations
Definition: execnodes.h:452
TupleTableSlot * es_trig_oldtup_slot
Definition: execnodes.h:472
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
int es_instrument
Definition: execnodes.h:492
TupleTableSlot * es_trig_tuple_slot
Definition: execnodes.h:471
List * es_leaf_result_relations
Definition: execnodes.h:467
QueryEnvironment * es_queryEnv
Definition: execnodes.h:479
#define AllocSetContextCreate(parent, name, allocparams)
Definition: memutils.h:165
int es_num_root_result_relations
Definition: execnodes.h:464
#define InvalidSnapshot
Definition: snapshot.h:25
List * es_trig_target_relations
Definition: execnodes.h:470
List * es_tupleTable
Definition: execnodes.h:484
List * es_auxmodifytables
Definition: execnodes.h:499
int es_num_result_relations
Definition: execnodes.h:453
#define InvalidOid
Definition: postgres_ext.h:36
bool es_finished
Definition: execnodes.h:493
#define makeNode(_type_)
Definition: nodes.h:560
uint64 es_processed
Definition: execnodes.h:488
bool * es_epqTupleSet
Definition: execnodes.h:518
List * es_subplanstates
Definition: execnodes.h:497
List * es_rowMarks
Definition: execnodes.h:486
int es_top_eflags
Definition: execnodes.h:491
ResultRelInfo * es_root_result_relations
Definition: execnodes.h:463
bool * es_epqScanDone
Definition: execnodes.h:519
ParamListInfo es_param_list_info
Definition: execnodes.h:476
List * es_exprcontexts
Definition: execnodes.h:495
ResultRelInfo * es_result_relation_info
Definition: execnodes.h:454

◆ CreateExprContext()

ExprContext* CreateExprContext ( EState estate)

Definition at line 226 of file execUtils.c.

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, ExprContext::caseValue_datum, ExprContext::caseValue_isNull, ExprContext::domainValue_datum, ExprContext::domainValue_isNull, ExprContext::ecxt_aggnulls, ExprContext::ecxt_aggvalues, ExprContext::ecxt_callbacks, ExprContext::ecxt_estate, ExprContext::ecxt_innertuple, ExprContext::ecxt_outertuple, ExprContext::ecxt_param_exec_vals, ExprContext::ecxt_param_list_info, ExprContext::ecxt_per_query_memory, ExprContext::ecxt_per_tuple_memory, ExprContext::ecxt_scantuple, EState::es_exprcontexts, EState::es_param_exec_vals, EState::es_param_list_info, EState::es_query_cxt, lcons(), makeNode, and MemoryContextSwitchTo().

Referenced by ExecAssignExprContext(), ExecInitMergeJoin(), ExecInitSubPlan(), MakePerTupleExprContext(), and plpgsql_create_econtext().

227 {
228  ExprContext *econtext;
229  MemoryContext oldcontext;
230 
231  /* Create the ExprContext node within the per-query memory context */
232  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
233 
234  econtext = makeNode(ExprContext);
235 
236  /* Initialize fields of ExprContext */
237  econtext->ecxt_scantuple = NULL;
238  econtext->ecxt_innertuple = NULL;
239  econtext->ecxt_outertuple = NULL;
240 
241  econtext->ecxt_per_query_memory = estate->es_query_cxt;
242 
243  /*
244  * Create working memory for expression evaluation in this context.
245  */
246  econtext->ecxt_per_tuple_memory =
248  "ExprContext",
250 
251  econtext->ecxt_param_exec_vals = estate->es_param_exec_vals;
252  econtext->ecxt_param_list_info = estate->es_param_list_info;
253 
254  econtext->ecxt_aggvalues = NULL;
255  econtext->ecxt_aggnulls = NULL;
256 
257  econtext->caseValue_datum = (Datum) 0;
258  econtext->caseValue_isNull = true;
259 
260  econtext->domainValue_datum = (Datum) 0;
261  econtext->domainValue_isNull = true;
262 
263  econtext->ecxt_estate = estate;
264 
265  econtext->ecxt_callbacks = NULL;
266 
267  /*
268  * Link the ExprContext into the EState to ensure it is shut down when the
269  * EState is freed. Because we use lcons(), shutdowns will occur in
270  * reverse order of creation, which may not be essential but can't hurt.
271  */
272  estate->es_exprcontexts = lcons(econtext, estate->es_exprcontexts);
273 
274  MemoryContextSwitchTo(oldcontext);
275 
276  return econtext;
277 }
Datum * ecxt_aggvalues
Definition: execnodes.h:224
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:214
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Datum domainValue_datum
Definition: execnodes.h:232
ParamExecData * es_param_exec_vals
Definition: execnodes.h:477
MemoryContext es_query_cxt
Definition: execnodes.h:482
Datum caseValue_datum
Definition: execnodes.h:228
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:239
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:197
TupleTableSlot * ecxt_innertuple
Definition: execnodes.h:209
ParamExecData * ecxt_param_exec_vals
Definition: execnodes.h:217
struct EState * ecxt_estate
Definition: execnodes.h:236
#define AllocSetContextCreate(parent, name, allocparams)
Definition: memutils.h:165
bool domainValue_isNull
Definition: execnodes.h:233
bool * ecxt_aggnulls
Definition: execnodes.h:225
uintptr_t Datum
Definition: postgres.h:372
List * lcons(void *datum, List *list)
Definition: list.c:259
#define makeNode(_type_)
Definition: nodes.h:560
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:210
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:208
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:213
bool caseValue_isNull
Definition: execnodes.h:229
ParamListInfo es_param_list_info
Definition: execnodes.h:476
List * es_exprcontexts
Definition: execnodes.h:495
ParamListInfo ecxt_param_list_info
Definition: execnodes.h:218

◆ CreateStandaloneExprContext()

ExprContext* CreateStandaloneExprContext ( void  )

Definition at line 298 of file execUtils.c.

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, ExprContext::caseValue_datum, ExprContext::caseValue_isNull, CurrentMemoryContext, ExprContext::domainValue_datum, ExprContext::domainValue_isNull, ExprContext::ecxt_aggnulls, ExprContext::ecxt_aggvalues, ExprContext::ecxt_callbacks, ExprContext::ecxt_estate, ExprContext::ecxt_innertuple, ExprContext::ecxt_outertuple, ExprContext::ecxt_param_exec_vals, ExprContext::ecxt_param_list_info, ExprContext::ecxt_per_query_memory, ExprContext::ecxt_per_tuple_memory, ExprContext::ecxt_scantuple, and makeNode.

Referenced by domain_check_input(), and ExecuteCallStmt().

299 {
300  ExprContext *econtext;
301 
302  /* Create the ExprContext node within the caller's memory context */
303  econtext = makeNode(ExprContext);
304 
305  /* Initialize fields of ExprContext */
306  econtext->ecxt_scantuple = NULL;
307  econtext->ecxt_innertuple = NULL;
308  econtext->ecxt_outertuple = NULL;
309 
311 
312  /*
313  * Create working memory for expression evaluation in this context.
314  */
315  econtext->ecxt_per_tuple_memory =
317  "ExprContext",
319 
320  econtext->ecxt_param_exec_vals = NULL;
321  econtext->ecxt_param_list_info = NULL;
322 
323  econtext->ecxt_aggvalues = NULL;
324  econtext->ecxt_aggnulls = NULL;
325 
326  econtext->caseValue_datum = (Datum) 0;
327  econtext->caseValue_isNull = true;
328 
329  econtext->domainValue_datum = (Datum) 0;
330  econtext->domainValue_isNull = true;
331 
332  econtext->ecxt_estate = NULL;
333 
334  econtext->ecxt_callbacks = NULL;
335 
336  return econtext;
337 }
Datum * ecxt_aggvalues
Definition: execnodes.h:224
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:214
Datum domainValue_datum
Definition: execnodes.h:232
Datum caseValue_datum
Definition: execnodes.h:228
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:239
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:197
TupleTableSlot * ecxt_innertuple
Definition: execnodes.h:209
ParamExecData * ecxt_param_exec_vals
Definition: execnodes.h:217
struct EState * ecxt_estate
Definition: execnodes.h:236
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
#define AllocSetContextCreate(parent, name, allocparams)
Definition: memutils.h:165
bool domainValue_isNull
Definition: execnodes.h:233
bool * ecxt_aggnulls
Definition: execnodes.h:225
uintptr_t Datum
Definition: postgres.h:372
#define makeNode(_type_)
Definition: nodes.h:560
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:210
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:208
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:213
bool caseValue_isNull
Definition: execnodes.h:229
ParamListInfo ecxt_param_list_info
Definition: execnodes.h:218

◆ ExecAssignExprContext()

◆ ExecAssignProjectionInfo()

void ExecAssignProjectionInfo ( PlanState planstate,
TupleDesc  inputDesc 
)

Definition at line 495 of file execUtils.c.

References ExecBuildProjectionInfo(), PlanState::plan, PlanState::ps_ExprContext, PlanState::ps_ProjInfo, PlanState::ps_ResultTupleSlot, and Plan::targetlist.

Referenced by ExecConditionalAssignProjectionInfo(), ExecInitAgg(), ExecInitGroup(), ExecInitHashJoin(), ExecInitMergeJoin(), ExecInitNestLoop(), ExecInitResult(), and ExecInitWindowAgg().

497 {
498  planstate->ps_ProjInfo =
500  planstate->ps_ExprContext,
501  planstate->ps_ResultTupleSlot,
502  planstate,
503  inputDesc);
504 }
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:893
ExprContext * ps_ExprContext
Definition: execnodes.h:892
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:891
Plan * plan
Definition: execnodes.h:858
List * targetlist
Definition: plannodes.h:144
ProjectionInfo * ExecBuildProjectionInfo(List *targetList, ExprContext *econtext, TupleTableSlot *slot, PlanState *parent, TupleDesc inputDesc)
Definition: execExpr.c:348

◆ ExecAssignResultType()

void ExecAssignResultType ( PlanState planstate,
TupleDesc  tupDesc 
)

Definition at line 436 of file execUtils.c.

References ExecSetSlotDescriptor(), and PlanState::ps_ResultTupleSlot.

Referenced by ExecAssignResultTypeFromTL().

437 {
438  TupleTableSlot *slot = planstate->ps_ResultTupleSlot;
439 
440  ExecSetSlotDescriptor(slot, tupDesc);
441 }
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:891
void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc)
Definition: execTuples.c:247

◆ ExecAssignResultTypeFromTL()

void ExecAssignResultTypeFromTL ( PlanState planstate)

Definition at line 448 of file execUtils.c.

References ExecAssignResultType(), ExecContextForcesOids(), ExecTypeFromTL(), PlanState::plan, and Plan::targetlist.

Referenced by ExecInitAgg(), ExecInitAppend(), ExecInitBitmapHeapScan(), ExecInitCteScan(), ExecInitCustomScan(), ExecInitForeignScan(), ExecInitFunctionScan(), ExecInitGather(), ExecInitGatherMerge(), ExecInitGroup(), ExecInitHash(), ExecInitHashJoin(), ExecInitIndexOnlyScan(), ExecInitIndexScan(), ExecInitLimit(), ExecInitLockRows(), ExecInitMaterial(), ExecInitMergeAppend(), ExecInitMergeJoin(), ExecInitModifyTable(), ExecInitNamedTuplestoreScan(), ExecInitNestLoop(), ExecInitProjectSet(), ExecInitRecursiveUnion(), ExecInitResult(), ExecInitSampleScan(), ExecInitSeqScan(), ExecInitSetOp(), ExecInitSort(), ExecInitSubqueryScan(), ExecInitTableFuncScan(), ExecInitTidScan(), ExecInitUnique(), ExecInitValuesScan(), ExecInitWindowAgg(), and ExecInitWorkTableScan().

449 {
450  bool hasoid;
451  TupleDesc tupDesc;
452 
453  if (ExecContextForcesOids(planstate, &hasoid))
454  {
455  /* context forces OID choice; hasoid is now set correctly */
456  }
457  else
458  {
459  /* given free choice, don't leave space for OIDs in result tuples */
460  hasoid = false;
461  }
462 
463  /*
464  * ExecTypeFromTL needs the parse-time representation of the tlist, not a
465  * list of ExprStates. This is good because some plan nodes don't bother
466  * to set up planstate->targetlist ...
467  */
468  tupDesc = ExecTypeFromTL(planstate->plan->targetlist, hasoid);
469  ExecAssignResultType(planstate, tupDesc);
470 }
void ExecAssignResultType(PlanState *planstate, TupleDesc tupDesc)
Definition: execUtils.c:436
TupleDesc ExecTypeFromTL(List *targetList, bool hasoid)
Definition: execTuples.c:888
Plan * plan
Definition: execnodes.h:858
List * targetlist
Definition: plannodes.h:144
bool ExecContextForcesOids(PlanState *planstate, bool *hasoids)
Definition: execMain.c:1513

◆ ExecAssignScanType()

◆ ExecAssignScanTypeFromOuterPlan()

void ExecAssignScanTypeFromOuterPlan ( ScanState scanstate)

Definition at line 639 of file execUtils.c.

References ExecAssignScanType(), ExecGetResultType(), outerPlan, and outerPlanState.

Referenced by ExecInitAgg(), ExecInitGroup(), ExecInitMaterial(), ExecInitSort(), and ExecInitWindowAgg().

640 {
642  TupleDesc tupDesc;
643 
644  outerPlan = outerPlanState(scanstate);
645  tupDesc = ExecGetResultType(outerPlan);
646 
647  ExecAssignScanType(scanstate, tupDesc);
648 }
#define outerPlanState(node)
Definition: execnodes.h:904
#define outerPlan(node)
Definition: plannodes.h:174
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:477
void ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc)
Definition: execUtils.c:627

◆ ExecCleanTargetListLength()

int ExecCleanTargetListLength ( List targetlist)

Definition at line 1096 of file execUtils.c.

References lfirst_node, and TargetEntry::resjunk.

Referenced by check_sql_fn_retval(), and ExecTypeFromTLInternal().

1097 {
1098  int len = 0;
1099  ListCell *tl;
1100 
1101  foreach(tl, targetlist)
1102  {
1103  TargetEntry *curTle = lfirst_node(TargetEntry, tl);
1104 
1105  if (!curTle->resjunk)
1106  len++;
1107  }
1108  return len;
1109 }
bool resjunk
Definition: primnodes.h:1382
#define lfirst_node(type, lc)
Definition: pg_list.h:109

◆ ExecCloseScanRelation()

void ExecCloseScanRelation ( Relation  scanrel)

Definition at line 748 of file execUtils.c.

References heap_close, and NoLock.

Referenced by ExecEndBitmapHeapScan(), ExecEndCustomScan(), ExecEndForeignScan(), ExecEndIndexOnlyScan(), ExecEndIndexScan(), ExecEndSampleScan(), ExecEndSeqScan(), and ExecEndTidScan().

749 {
750  heap_close(scanrel, NoLock);
751 }
#define heap_close(r, l)
Definition: heapam.h:97
#define NoLock
Definition: lockdefs.h:34

◆ ExecConditionalAssignProjectionInfo()

void ExecConditionalAssignProjectionInfo ( PlanState planstate,
TupleDesc  inputDesc,
Index  varno 
)

Definition at line 515 of file execUtils.c.

References ExecAssignProjectionInfo(), PlanState::plan, PlanState::ps_ProjInfo, Plan::targetlist, and tlist_matches_tupdesc().

Referenced by ExecAssignScanProjectionInfo(), ExecAssignScanProjectionInfoWithVarno(), ExecInitGather(), and ExecInitGatherMerge().

517 {
518  if (tlist_matches_tupdesc(planstate,
519  planstate->plan->targetlist,
520  varno,
521  inputDesc))
522  planstate->ps_ProjInfo = NULL;
523  else
524  ExecAssignProjectionInfo(planstate, inputDesc);
525 }
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:893
void ExecAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc)
Definition: execUtils.c:495
Plan * plan
Definition: execnodes.h:858
static bool tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc)
Definition: execUtils.c:528
List * targetlist
Definition: plannodes.h:144

◆ ExecFreeExprContext()

◆ ExecGetResultType()

◆ ExecLockNonLeafAppendTables()

void ExecLockNonLeafAppendTables ( List partitioned_rels,
EState estate 
)

Definition at line 913 of file execUtils.c.

References AccessShareLock, EState::es_plannedstmt, EState::es_range_table, getrelid, lfirst, lfirst_int, LockRelationOid(), PlanRowMark::markType, PlannedStmt::nonleafResultRelations, RowMarkRequiresRowShareLock, PlannedStmt::rowMarks, and RowShareLock.

Referenced by ExecInitAppend(), and ExecInitMergeAppend().

914 {
915  PlannedStmt *stmt = estate->es_plannedstmt;
916  ListCell *lc;
917 
918  foreach(lc, partitioned_rels)
919  {
920  ListCell *l;
921  Index rti = lfirst_int(lc);
922  bool is_result_rel = false;
923  Oid relid = getrelid(rti, estate->es_range_table);
924 
925  /* If this is a result relation, already locked in InitPlan */
926  foreach(l, stmt->nonleafResultRelations)
927  {
928  if (rti == lfirst_int(l))
929  {
930  is_result_rel = true;
931  break;
932  }
933  }
934 
935  /*
936  * Not a result relation; check if there is a RowMark that requires
937  * taking a RowShareLock on this rel.
938  */
939  if (!is_result_rel)
940  {
941  PlanRowMark *rc = NULL;
942 
943  foreach(l, stmt->rowMarks)
944  {
945  if (((PlanRowMark *) lfirst(l))->rti == rti)
946  {
947  rc = lfirst(l);
948  break;
949  }
950  }
951 
952  if (rc && RowMarkRequiresRowShareLock(rc->markType))
954  else
956  }
957  }
958 }
RowMarkType markType
Definition: plannodes.h:1022
List * nonleafResultRelations
Definition: plannodes.h:72
#define AccessShareLock
Definition: lockdefs.h:36
PlannedStmt * es_plannedstmt
Definition: execnodes.h:443
List * es_range_table
Definition: execnodes.h:442
unsigned int Oid
Definition: postgres_ext.h:31
#define RowMarkRequiresRowShareLock(marktype)
Definition: plannodes.h:975
#define lfirst_int(lc)
Definition: pg_list.h:107
#define RowShareLock
Definition: lockdefs.h:37
unsigned int Index
Definition: c.h:423
List * rowMarks
Definition: plannodes.h:86
#define lfirst(lc)
Definition: pg_list.h:106
#define getrelid(rangeindex, rangetable)
Definition: parsetree.h:41
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:105

◆ ExecOpenScanRelation()

Relation ExecOpenScanRelation ( EState estate,
Index  scanrelid,
int  eflags 
)

Definition at line 690 of file execUtils.c.

References AccessShareLock, ereport, errcode(), errhint(), errmsg(), ERROR, EState::es_range_table, EXEC_FLAG_EXPLAIN_ONLY, EXEC_FLAG_WITH_NO_DATA, ExecFindRowMark(), ExecRelationIsTargetRelation(), getrelid, heap_open(), NoLock, ExecRowMark::relation, RelationGetRelationName, and RelationIsScannable.

Referenced by ExecInitBitmapHeapScan(), ExecInitCustomScan(), ExecInitForeignScan(), ExecInitIndexOnlyScan(), ExecInitIndexScan(), ExecInitTidScan(), and InitScanRelation().

691 {
692  Relation rel;
693  Oid reloid;
694  LOCKMODE lockmode;
695 
696  /*
697  * Determine the lock type we need. First, scan to see if target relation
698  * is a result relation. If not, check if it's a FOR UPDATE/FOR SHARE
699  * relation. In either of those cases, we got the lock already.
700  */
701  lockmode = AccessShareLock;
702  if (ExecRelationIsTargetRelation(estate, scanrelid))
703  lockmode = NoLock;
704  else
705  {
706  /* Keep this check in sync with InitPlan! */
707  ExecRowMark *erm = ExecFindRowMark(estate, scanrelid, true);
708 
709  if (erm != NULL && erm->relation != NULL)
710  lockmode = NoLock;
711  }
712 
713  /* Open the relation and acquire lock as needed */
714  reloid = getrelid(scanrelid, estate->es_range_table);
715  rel = heap_open(reloid, lockmode);
716 
717  /*
718  * Complain if we're attempting a scan of an unscannable relation, except
719  * when the query won't actually be run. This is a slightly klugy place
720  * to do this, perhaps, but there is no better place.
721  */
722  if ((eflags & (EXEC_FLAG_EXPLAIN_ONLY | EXEC_FLAG_WITH_NO_DATA)) == 0 &&
723  !RelationIsScannable(rel))
724  ereport(ERROR,
725  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
726  errmsg("materialized view \"%s\" has not been populated",
728  errhint("Use the REFRESH MATERIALIZED VIEW command.")));
729 
730  return rel;
731 }
int errhint(const char *fmt,...)
Definition: elog.c:987
int LOCKMODE
Definition: lockdefs.h:26
#define RelationIsScannable(relation)
Definition: rel.h:553
Relation relation
Definition: execnodes.h:547
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:575
#define EXEC_FLAG_WITH_NO_DATA
Definition: executor.h:65
List * es_range_table
Definition: execnodes.h:442
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:43
#define NoLock
Definition: lockdefs.h:34
#define RelationGetRelationName(relation)
Definition: rel.h:445
#define ereport(elevel, rest)
Definition: elog.h:122
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define getrelid(rangeindex, rangetable)
Definition: parsetree.h:41
#define EXEC_FLAG_EXPLAIN_ONLY
Definition: executor.h:58
bool ExecRelationIsTargetRelation(EState *estate, Index scanrelid)
Definition: execUtils.c:664
ExecRowMark * ExecFindRowMark(EState *estate, Index rti, bool missing_ok)
Definition: execMain.c:2398

◆ ExecRelationIsTargetRelation()

bool ExecRelationIsTargetRelation ( EState estate,
Index  scanrelid 
)

Definition at line 664 of file execUtils.c.

References EState::es_num_result_relations, EState::es_result_relations, and i.

Referenced by ExecInitBitmapIndexScan(), ExecInitIndexOnlyScan(), ExecInitIndexScan(), and ExecOpenScanRelation().

665 {
666  ResultRelInfo *resultRelInfos;
667  int i;
668 
669  resultRelInfos = estate->es_result_relations;
670  for (i = 0; i < estate->es_num_result_relations; i++)
671  {
672  if (resultRelInfos[i].ri_RangeTableIndex == scanrelid)
673  return true;
674  }
675  return false;
676 }
ResultRelInfo * es_result_relations
Definition: execnodes.h:452
int es_num_result_relations
Definition: execnodes.h:453
int i

◆ ExecTargetListLength()

int ExecTargetListLength ( List targetlist)

Definition at line 1086 of file execUtils.c.

References list_length().

Referenced by ExecTypeFromTLInternal().

1087 {
1088  /* This used to be more complex, but fjoins are dead */
1089  return list_length(targetlist);
1090 }
static int list_length(const List *l)
Definition: pg_list.h:89

◆ executor_errposition()

int executor_errposition ( EState estate,
int  location 
)

Definition at line 792 of file execUtils.c.

References errposition(), EState::es_sourceText, and pg_mbstrlen_with_len().

Referenced by ExecInitFunc(), and init_sexpr().

793 {
794  int pos;
795 
796  /* No-op if location was not provided */
797  if (location < 0)
798  return 0;
799  /* Can't do anything if source text is not available */
800  if (estate == NULL || estate->es_sourceText == NULL)
801  return 0;
802  /* Convert offset to character number */
803  pos = pg_mbstrlen_with_len(estate->es_sourceText, location) + 1;
804  /* And pass it to the ereport mechanism */
805  return errposition(pos);
806 }
int pg_mbstrlen_with_len(const char *mbstr, int limit)
Definition: mbutils.c:794
const char * es_sourceText
Definition: execnodes.h:444
int errposition(int cursorpos)
Definition: elog.c:1125

◆ FreeExecutorState()

void FreeExecutorState ( EState estate)

Definition at line 186 of file execUtils.c.

References EState::es_exprcontexts, EState::es_query_cxt, FreeExprContext(), linitial, and MemoryContextDelete().

Referenced by afterTriggerInvokeEvents(), apply_handle_delete(), apply_handle_insert(), apply_handle_update(), ATRewriteTable(), check_default_allows_bound(), compute_index_stats(), CopyFrom(), EvalPlanQualEnd(), evaluate_expr(), ExecuteCallStmt(), ExecuteQuery(), ExecuteTruncate(), ExplainExecuteQuery(), get_actual_variable_range(), get_qual_for_range(), IndexBuildHeapRangeScan(), IndexCheckExclusion(), operator_predicate_proof(), plpgsql_inline_handler(), plpgsql_xact_cb(), standard_ExecutorEnd(), tuplesort_end(), unique_key_recheck(), validate_index_heapscan(), validateCheckConstraint(), and validateDomainConstraint().

187 {
188  /*
189  * Shut down and free any remaining ExprContexts. We do this explicitly
190  * to ensure that any remaining shutdown callbacks get called (since they
191  * might need to release resources that aren't simply memory within the
192  * per-query memory context).
193  */
194  while (estate->es_exprcontexts)
195  {
196  /*
197  * XXX: seems there ought to be a faster way to implement this than
198  * repeated list_delete(), no?
199  */
201  true);
202  /* FreeExprContext removed the list link for us */
203  }
204 
205  /*
206  * Free the per-query memory context, thereby releasing all working
207  * memory, including the EState node itself.
208  */
210 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:198
MemoryContext es_query_cxt
Definition: execnodes.h:482
#define linitial(l)
Definition: pg_list.h:111
void FreeExprContext(ExprContext *econtext, bool isCommit)
Definition: execUtils.c:357
List * es_exprcontexts
Definition: execnodes.h:495

◆ FreeExprContext()

void FreeExprContext ( ExprContext econtext,
bool  isCommit 
)

Definition at line 357 of file execUtils.c.

References ExprContext::ecxt_estate, ExprContext::ecxt_per_tuple_memory, EState::es_exprcontexts, list_delete_ptr(), MemoryContextDelete(), pfree(), and ShutdownExprContext().

Referenced by ExecEndBitmapIndexScan(), ExecEndIndexOnlyScan(), ExecEndIndexScan(), FreeExecutorState(), plpgsql_destroy_econtext(), and plpgsql_subxact_cb().

358 {
359  EState *estate;
360 
361  /* Call any registered callbacks */
362  ShutdownExprContext(econtext, isCommit);
363  /* And clean up the memory used */
365  /* Unlink self from owning EState, if any */
366  estate = econtext->ecxt_estate;
367  if (estate)
369  econtext);
370  /* And delete the ExprContext node */
371  pfree(econtext);
372 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:198
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:214
List * list_delete_ptr(List *list, void *datum)
Definition: list.c:590
void pfree(void *pointer)
Definition: mcxt.c:936
struct EState * ecxt_estate
Definition: execnodes.h:236
static void ShutdownExprContext(ExprContext *econtext, bool isCommit)
Definition: execUtils.c:876
List * es_exprcontexts
Definition: execnodes.h:495

◆ GetAttributeByName()

Datum GetAttributeByName ( HeapTupleHeader  tuple,
const char *  attname,
bool isNull 
)

Definition at line 972 of file execUtils.c.

References elog, ERROR, heap_getattr, HeapTupleHeaderGetDatumLength, HeapTupleHeaderGetTypeId, HeapTupleHeaderGetTypMod, i, InvalidAttrNumber, InvalidOid, ItemPointerSetInvalid, lookup_rowtype_tupdesc(), namestrcmp(), tupleDesc::natts, ReleaseTupleDesc, HeapTupleData::t_data, HeapTupleData::t_len, HeapTupleData::t_self, HeapTupleData::t_tableOid, and TupleDescAttr.

Referenced by c_overpaid(), and overpaid().

973 {
974  AttrNumber attrno;
975  Datum result;
976  Oid tupType;
977  int32 tupTypmod;
978  TupleDesc tupDesc;
979  HeapTupleData tmptup;
980  int i;
981 
982  if (attname == NULL)
983  elog(ERROR, "invalid attribute name");
984 
985  if (isNull == NULL)
986  elog(ERROR, "a NULL isNull pointer was passed");
987 
988  if (tuple == NULL)
989  {
990  /* Kinda bogus but compatible with old behavior... */
991  *isNull = true;
992  return (Datum) 0;
993  }
994 
995  tupType = HeapTupleHeaderGetTypeId(tuple);
996  tupTypmod = HeapTupleHeaderGetTypMod(tuple);
997  tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
998 
999  attrno = InvalidAttrNumber;
1000  for (i = 0; i < tupDesc->natts; i++)
1001  {
1002  Form_pg_attribute att = TupleDescAttr(tupDesc, i);
1003 
1004  if (namestrcmp(&(att->attname), attname) == 0)
1005  {
1006  attrno = att->attnum;
1007  break;
1008  }
1009  }
1010 
1011  if (attrno == InvalidAttrNumber)
1012  elog(ERROR, "attribute \"%s\" does not exist", attname);
1013 
1014  /*
1015  * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
1016  * the fields in the struct just in case user tries to inspect system
1017  * columns.
1018  */
1019  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
1020  ItemPointerSetInvalid(&(tmptup.t_self));
1021  tmptup.t_tableOid = InvalidOid;
1022  tmptup.t_data = tuple;
1023 
1024  result = heap_getattr(&tmptup,
1025  attrno,
1026  tupDesc,
1027  isNull);
1028 
1029  ReleaseTupleDesc(tupDesc);
1030 
1031  return result;
1032 }
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition: typcache.c:1618
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:90
int namestrcmp(Name name, const char *str)
Definition: name.c:247
unsigned int Oid
Definition: postgres_ext.h:31
int natts
Definition: tupdesc.h:79
signed int int32
Definition: c.h:294
HeapTupleHeader t_data
Definition: htup.h:67
#define HeapTupleHeaderGetTypMod(tup)
Definition: htup_details.h:460
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
uint32 t_len
Definition: htup.h:64
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
Oid t_tableOid
Definition: htup.h:66
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:774
uintptr_t Datum
Definition: postgres.h:372
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:450
#define InvalidOid
Definition: postgres_ext.h:36
#define InvalidAttrNumber
Definition: attnum.h:23
#define ItemPointerSetInvalid(pointer)
Definition: itemptr.h:150
int i
#define elog
Definition: elog.h:219
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:121
int16 AttrNumber
Definition: attnum.h:21
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:444

◆ GetAttributeByNum()

Datum GetAttributeByNum ( HeapTupleHeader  tuple,
AttrNumber  attrno,
bool isNull 
)

Definition at line 1035 of file execUtils.c.

References AttributeNumberIsValid, elog, ERROR, heap_getattr, HeapTupleHeaderGetDatumLength, HeapTupleHeaderGetTypeId, HeapTupleHeaderGetTypMod, InvalidOid, ItemPointerSetInvalid, lookup_rowtype_tupdesc(), ReleaseTupleDesc, HeapTupleData::t_data, HeapTupleData::t_len, HeapTupleData::t_self, and HeapTupleData::t_tableOid.

1038 {
1039  Datum result;
1040  Oid tupType;
1041  int32 tupTypmod;
1042  TupleDesc tupDesc;
1043  HeapTupleData tmptup;
1044 
1045  if (!AttributeNumberIsValid(attrno))
1046  elog(ERROR, "invalid attribute number %d", attrno);
1047 
1048  if (isNull == NULL)
1049  elog(ERROR, "a NULL isNull pointer was passed");
1050 
1051  if (tuple == NULL)
1052  {
1053  /* Kinda bogus but compatible with old behavior... */
1054  *isNull = true;
1055  return (Datum) 0;
1056  }
1057 
1058  tupType = HeapTupleHeaderGetTypeId(tuple);
1059  tupTypmod = HeapTupleHeaderGetTypMod(tuple);
1060  tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
1061 
1062  /*
1063  * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
1064  * the fields in the struct just in case user tries to inspect system
1065  * columns.
1066  */
1067  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
1068  ItemPointerSetInvalid(&(tmptup.t_self));
1069  tmptup.t_tableOid = InvalidOid;
1070  tmptup.t_data = tuple;
1071 
1072  result = heap_getattr(&tmptup,
1073  attrno,
1074  tupDesc,
1075  isNull);
1076 
1077  ReleaseTupleDesc(tupDesc);
1078 
1079  return result;
1080 }
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition: typcache.c:1618
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:294
HeapTupleHeader t_data
Definition: htup.h:67
#define HeapTupleHeaderGetTypMod(tup)
Definition: htup_details.h:460
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
uint32 t_len
Definition: htup.h:64
Oid t_tableOid
Definition: htup.h:66
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:774
#define AttributeNumberIsValid(attributeNumber)
Definition: attnum.h:34
uintptr_t Datum
Definition: postgres.h:372
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:450
#define InvalidOid
Definition: postgres_ext.h:36
#define ItemPointerSetInvalid(pointer)
Definition: itemptr.h:150
#define elog
Definition: elog.h:219
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:121
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:444

◆ MakePerTupleExprContext()

ExprContext* MakePerTupleExprContext ( EState estate)

Definition at line 399 of file execUtils.c.

References CreateExprContext(), and EState::es_per_tuple_exprcontext.

400 {
401  if (estate->es_per_tuple_exprcontext == NULL)
403 
404  return estate->es_per_tuple_exprcontext;
405 }
ExprContext * es_per_tuple_exprcontext
Definition: execnodes.h:506
ExprContext * CreateExprContext(EState *estate)
Definition: execUtils.c:226

◆ RegisterExprContextCallback()

void RegisterExprContextCallback ( ExprContext econtext,
ExprContextCallbackFunction  function,
Datum  arg 
)

Definition at line 819 of file execUtils.c.

References arg, ExprContext_CB::arg, ExprContext::ecxt_callbacks, ExprContext::ecxt_per_query_memory, ExprContext_CB::function, MemoryContextAlloc(), and ExprContext_CB::next.

Referenced by AggRegisterCallback(), ExecMakeFunctionResultSet(), ExecPrepareTuplestoreResult(), fmgr_sql(), get_cached_rowtype(), and init_MultiFuncCall().

822 {
823  ExprContext_CB *ecxt_callback;
824 
825  /* Save the info in appropriate memory context */
826  ecxt_callback = (ExprContext_CB *)
828  sizeof(ExprContext_CB));
829 
830  ecxt_callback->function = function;
831  ecxt_callback->arg = arg;
832 
833  /* link to front of list for appropriate execution order */
834  ecxt_callback->next = econtext->ecxt_callbacks;
835  econtext->ecxt_callbacks = ecxt_callback;
836 }
ExprContextCallbackFunction function
Definition: execnodes.h:176
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:239
struct ExprContext_CB * next
Definition: execnodes.h:175
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:213
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:693
void * arg

◆ ReScanExprContext()

void ReScanExprContext ( ExprContext econtext)

Definition at line 384 of file execUtils.c.

References ExprContext::ecxt_per_tuple_memory, MemoryContextReset(), and ShutdownExprContext().

Referenced by agg_retrieve_direct(), domain_check_input(), ExecEndAgg(), ExecReScan(), ExecReScanAgg(), and ValuesNext().

385 {
386  /* Call any registered callbacks */
387  ShutdownExprContext(econtext, true);
388  /* And clean up the memory used */
390 }
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:214
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:134
static void ShutdownExprContext(ExprContext *econtext, bool isCommit)
Definition: execUtils.c:876

◆ ShutdownExprContext()

static void ShutdownExprContext ( ExprContext econtext,
bool  isCommit 
)
static

Definition at line 876 of file execUtils.c.

References ExprContext_CB::arg, ExprContext::ecxt_callbacks, ExprContext::ecxt_per_tuple_memory, ExprContext_CB::function, MemoryContextSwitchTo(), ExprContext_CB::next, and pfree().

Referenced by FreeExprContext(), and ReScanExprContext().

877 {
878  ExprContext_CB *ecxt_callback;
879  MemoryContext oldcontext;
880 
881  /* Fast path in normal case where there's nothing to do. */
882  if (econtext->ecxt_callbacks == NULL)
883  return;
884 
885  /*
886  * Call the callbacks in econtext's per-tuple context. This ensures that
887  * any memory they might leak will get cleaned up.
888  */
889  oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
890 
891  /*
892  * Call each callback function in reverse registration order.
893  */
894  while ((ecxt_callback = econtext->ecxt_callbacks) != NULL)
895  {
896  econtext->ecxt_callbacks = ecxt_callback->next;
897  if (isCommit)
898  ecxt_callback->function(ecxt_callback->arg);
899  pfree(ecxt_callback);
900  }
901 
902  MemoryContextSwitchTo(oldcontext);
903 }
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:214
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void pfree(void *pointer)
Definition: mcxt.c:936
ExprContextCallbackFunction function
Definition: execnodes.h:176
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:239
struct ExprContext_CB * next
Definition: execnodes.h:175

◆ tlist_matches_tupdesc()

static bool tlist_matches_tupdesc ( PlanState ps,
List tlist,
Index  varno,
TupleDesc  tupdesc 
)
static

Definition at line 528 of file execUtils.c.

References Assert, ExecContextForcesOids(), IsA, lfirst, list_head(), lnext, tupleDesc::natts, tupleDesc::tdhasoid, TupleDescAttr, Var::varattno, Var::varlevelsup, Var::varno, Var::vartype, and Var::vartypmod.

Referenced by ExecConditionalAssignProjectionInfo().

529 {
530  int numattrs = tupdesc->natts;
531  int attrno;
532  bool hasoid;
533  ListCell *tlist_item = list_head(tlist);
534 
535  /* Check the tlist attributes */
536  for (attrno = 1; attrno <= numattrs; attrno++)
537  {
538  Form_pg_attribute att_tup = TupleDescAttr(tupdesc, attrno - 1);
539  Var *var;
540 
541  if (tlist_item == NULL)
542  return false; /* tlist too short */
543  var = (Var *) ((TargetEntry *) lfirst(tlist_item))->expr;
544  if (!var || !IsA(var, Var))
545  return false; /* tlist item not a Var */
546  /* if these Asserts fail, planner messed up */
547  Assert(var->varno == varno);
548  Assert(var->varlevelsup == 0);
549  if (var->varattno != attrno)
550  return false; /* out of order */
551  if (att_tup->attisdropped)
552  return false; /* table contains dropped columns */
553 
554  /*
555  * Note: usually the Var's type should match the tupdesc exactly, but
556  * in situations involving unions of columns that have different
557  * typmods, the Var may have come from above the union and hence have
558  * typmod -1. This is a legitimate situation since the Var still
559  * describes the column, just not as exactly as the tupdesc does. We
560  * could change the planner to prevent it, but it'd then insert
561  * projection steps just to convert from specific typmod to typmod -1,
562  * which is pretty silly.
563  */
564  if (var->vartype != att_tup->atttypid ||
565  (var->vartypmod != att_tup->atttypmod &&
566  var->vartypmod != -1))
567  return false; /* type mismatch */
568 
569  tlist_item = lnext(tlist_item);
570  }
571 
572  if (tlist_item)
573  return false; /* tlist too long */
574 
575  /*
576  * If the plan context requires a particular hasoid setting, then that has
577  * to match, too.
578  */
579  if (ExecContextForcesOids(ps, &hasoid) &&
580  hasoid != tupdesc->tdhasoid)
581  return false;
582 
583  return true;
584 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:563
Index varlevelsup
Definition: primnodes.h:173
bool tdhasoid
Definition: tupdesc.h:82
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:90
AttrNumber varattno
Definition: primnodes.h:168
Definition: primnodes.h:163
int natts
Definition: tupdesc.h:79
Oid vartype
Definition: primnodes.h:170
static ListCell * list_head(const List *l)
Definition: pg_list.h:77
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
#define lnext(lc)
Definition: pg_list.h:105
Index varno
Definition: primnodes.h:166
#define Assert(condition)
Definition: c.h:680
#define lfirst(lc)
Definition: pg_list.h:106
bool ExecContextForcesOids(PlanState *planstate, bool *hasoids)
Definition: execMain.c:1513
int32 vartypmod
Definition: primnodes.h:171

◆ UnregisterExprContextCallback()

void UnregisterExprContextCallback ( ExprContext econtext,
ExprContextCallbackFunction  function,
Datum  arg 
)

Definition at line 845 of file execUtils.c.

References ExprContext_CB::arg, ExprContext::ecxt_callbacks, ExprContext_CB::function, ExprContext_CB::next, and pfree().

Referenced by end_MultiFuncCall(), and fmgr_sql().

848 {
849  ExprContext_CB **prev_callback;
850  ExprContext_CB *ecxt_callback;
851 
852  prev_callback = &econtext->ecxt_callbacks;
853 
854  while ((ecxt_callback = *prev_callback) != NULL)
855  {
856  if (ecxt_callback->function == function && ecxt_callback->arg == arg)
857  {
858  *prev_callback = ecxt_callback->next;
859  pfree(ecxt_callback);
860  }
861  else
862  prev_callback = &ecxt_callback->next;
863  }
864 }
void pfree(void *pointer)
Definition: mcxt.c:936
ExprContextCallbackFunction function
Definition: execnodes.h:176
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:239
struct ExprContext_CB * next
Definition: execnodes.h:175
void * arg

◆ UpdateChangedParamSet()

void UpdateChangedParamSet ( PlanState node,
Bitmapset newchg 
)

Definition at line 758 of file execUtils.c.

References Plan::allParam, bms_free(), bms_intersect(), bms_is_empty(), bms_join(), PlanState::chgParam, and PlanState::plan.

Referenced by ExecReScan(), ExecReScanAppend(), ExecReScanBitmapAnd(), ExecReScanBitmapOr(), ExecReScanMergeAppend(), and ExecReScanSubqueryScan().

759 {
760  Bitmapset *parmset;
761 
762  /*
763  * The plan node only depends on params listed in its allParam set. Don't
764  * include anything else into its chgParam set.
765  */
766  parmset = bms_intersect(node->plan->allParam, newchg);
767 
768  /*
769  * Keep node->chgParam == NULL if there's not actually any members; this
770  * allows the simplest possible tests in executor node files.
771  */
772  if (!bms_is_empty(parmset))
773  node->chgParam = bms_join(node->chgParam, parmset);
774  else
775  bms_free(parmset);
776 }
Bitmapset * bms_join(Bitmapset *a, Bitmapset *b)
Definition: bitmapset.c:954
Bitmapset * allParam
Definition: plannodes.h:163
Bitmapset * chgParam
Definition: execnodes.h:886
bool bms_is_empty(const Bitmapset *a)
Definition: bitmapset.c:707
Bitmapset * bms_intersect(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:296
Plan * plan
Definition: execnodes.h:858
void bms_free(Bitmapset *a)
Definition: bitmapset.c:245