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)
 
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 ExecCreateScanSlotFromOuterPlan (EState *estate, 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 80 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_jit, EState::es_jit_flags, EState::es_junkFilter, EState::es_lastoid, 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_tuple_routing_result_relations, 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(), ExecuteTruncateGuts(), ExplainExecuteQuery(), get_actual_variable_range(), get_qual_for_range(), IndexBuildHeapRangeScan(), IndexCheckExclusion(), operator_predicate_proof(), plpgsql_create_econtext(), plpgsql_inline_handler(), ProjIndexIsUnchanged(), standard_ExecutorStart(), StoreAttrDefault(), tuplesort_begin_cluster(), unique_key_recheck(), validate_index_heapscan(), validateCheckConstraint(), and validateDomainConstraint().

81 {
82  EState *estate;
83  MemoryContext qcontext;
84  MemoryContext oldcontext;
85 
86  /*
87  * Create the per-query context for this Executor run.
88  */
90  "ExecutorState",
92 
93  /*
94  * Make the EState node within the per-query context. This way, we don't
95  * need a separate pfree() operation for it at shutdown.
96  */
97  oldcontext = MemoryContextSwitchTo(qcontext);
98 
99  estate = makeNode(EState);
100 
101  /*
102  * Initialize all fields of the Executor State structure
103  */
105  estate->es_snapshot = InvalidSnapshot; /* caller must initialize this */
106  estate->es_crosscheck_snapshot = InvalidSnapshot; /* no crosscheck */
107  estate->es_range_table = NIL;
108  estate->es_plannedstmt = NULL;
109 
110  estate->es_junkFilter = NULL;
111 
112  estate->es_output_cid = (CommandId) 0;
113 
114  estate->es_result_relations = NULL;
115  estate->es_num_result_relations = 0;
116  estate->es_result_relation_info = NULL;
117 
118  estate->es_root_result_relations = NULL;
119  estate->es_num_root_result_relations = 0;
120 
122 
123  estate->es_trig_target_relations = NIL;
124  estate->es_trig_tuple_slot = NULL;
125  estate->es_trig_oldtup_slot = NULL;
126  estate->es_trig_newtup_slot = NULL;
127 
128  estate->es_param_list_info = NULL;
129  estate->es_param_exec_vals = NULL;
130 
131  estate->es_queryEnv = NULL;
132 
133  estate->es_query_cxt = qcontext;
134 
135  estate->es_tupleTable = NIL;
136 
137  estate->es_rowMarks = NIL;
138 
139  estate->es_processed = 0;
140  estate->es_lastoid = InvalidOid;
141 
142  estate->es_top_eflags = 0;
143  estate->es_instrument = 0;
144  estate->es_finished = false;
145 
146  estate->es_exprcontexts = NIL;
147 
148  estate->es_subplanstates = NIL;
149 
150  estate->es_auxmodifytables = NIL;
151 
152  estate->es_per_tuple_exprcontext = NULL;
153 
154  estate->es_epqTuple = NULL;
155  estate->es_epqTupleSet = NULL;
156  estate->es_epqScanDone = NULL;
157  estate->es_sourceText = NULL;
158 
159  estate->es_use_parallel_mode = false;
160 
161  estate->es_jit_flags = 0;
162  estate->es_jit = NULL;
163 
164  /*
165  * Return the executor state structure
166  */
167  MemoryContextSwitchTo(oldcontext);
168 
169  return estate;
170 }
#define NIL
Definition: pg_list.h:69
uint32 CommandId
Definition: c.h:488
HeapTuple * es_epqTuple
Definition: execnodes.h:558
JunkFilter * es_junkFilter
Definition: execnodes.h:484
CommandId es_output_cid
Definition: execnodes.h:487
struct JitContext * es_jit
Definition: execnodes.h:573
TupleTableSlot * es_trig_newtup_slot
Definition: execnodes.h:514
Oid es_lastoid
Definition: execnodes.h:530
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
PlannedStmt * es_plannedstmt
Definition: execnodes.h:481
Snapshot es_crosscheck_snapshot
Definition: execnodes.h:479
ExprContext * es_per_tuple_exprcontext
Definition: execnodes.h:547
Snapshot es_snapshot
Definition: execnodes.h:478
List * es_range_table
Definition: execnodes.h:480
ScanDirection es_direction
Definition: execnodes.h:477
bool es_use_parallel_mode
Definition: execnodes.h:562
const char * es_sourceText
Definition: execnodes.h:482
ParamExecData * es_param_exec_vals
Definition: execnodes.h:518
MemoryContext es_query_cxt
Definition: execnodes.h:523
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:192
int es_jit_flags
Definition: execnodes.h:572
ResultRelInfo * es_result_relations
Definition: execnodes.h:490
TupleTableSlot * es_trig_oldtup_slot
Definition: execnodes.h:513
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
int es_instrument
Definition: execnodes.h:533
TupleTableSlot * es_trig_tuple_slot
Definition: execnodes.h:512
QueryEnvironment * es_queryEnv
Definition: execnodes.h:520
#define AllocSetContextCreate(parent, name, allocparams)
Definition: memutils.h:170
int es_num_root_result_relations
Definition: execnodes.h:502
#define InvalidSnapshot
Definition: snapshot.h:25
List * es_trig_target_relations
Definition: execnodes.h:511
List * es_tupleTable
Definition: execnodes.h:525
List * es_auxmodifytables
Definition: execnodes.h:540
int es_num_result_relations
Definition: execnodes.h:491
#define InvalidOid
Definition: postgres_ext.h:36
List * es_tuple_routing_result_relations
Definition: execnodes.h:508
bool es_finished
Definition: execnodes.h:534
#define makeNode(_type_)
Definition: nodes.h:565
uint64 es_processed
Definition: execnodes.h:529
bool * es_epqTupleSet
Definition: execnodes.h:559
List * es_subplanstates
Definition: execnodes.h:538
List * es_rowMarks
Definition: execnodes.h:527
int es_top_eflags
Definition: execnodes.h:532
ResultRelInfo * es_root_result_relations
Definition: execnodes.h:501
bool * es_epqScanDone
Definition: execnodes.h:560
ParamListInfo es_param_list_info
Definition: execnodes.h:517
List * es_exprcontexts
Definition: execnodes.h:536
ResultRelInfo * es_result_relation_info
Definition: execnodes.h:492

◆ CreateExprContext()

ExprContext* CreateExprContext ( EState estate)

Definition at line 228 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 BuildTupleHashTable(), ExecAssignExprContext(), ExecInitMergeJoin(), ExecInitSubPlan(), ExecuteCallStmt(), MakePerTupleExprContext(), and plpgsql_create_econtext().

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

◆ CreateStandaloneExprContext()

ExprContext* CreateStandaloneExprContext ( void  )

Definition at line 300 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 hypothetical_dense_rank_final().

301 {
302  ExprContext *econtext;
303 
304  /* Create the ExprContext node within the caller's memory context */
305  econtext = makeNode(ExprContext);
306 
307  /* Initialize fields of ExprContext */
308  econtext->ecxt_scantuple = NULL;
309  econtext->ecxt_innertuple = NULL;
310  econtext->ecxt_outertuple = NULL;
311 
313 
314  /*
315  * Create working memory for expression evaluation in this context.
316  */
317  econtext->ecxt_per_tuple_memory =
319  "ExprContext",
321 
322  econtext->ecxt_param_exec_vals = NULL;
323  econtext->ecxt_param_list_info = NULL;
324 
325  econtext->ecxt_aggvalues = NULL;
326  econtext->ecxt_aggnulls = NULL;
327 
328  econtext->caseValue_datum = (Datum) 0;
329  econtext->caseValue_isNull = true;
330 
331  econtext->domainValue_datum = (Datum) 0;
332  econtext->domainValue_isNull = true;
333 
334  econtext->ecxt_estate = NULL;
335 
336  econtext->ecxt_callbacks = NULL;
337 
338  return econtext;
339 }
Datum * ecxt_aggvalues
Definition: execnodes.h:237
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:226
Datum domainValue_datum
Definition: execnodes.h:249
Datum caseValue_datum
Definition: execnodes.h:243
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:257
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:192
TupleTableSlot * ecxt_innertuple
Definition: execnodes.h:220
ParamExecData * ecxt_param_exec_vals
Definition: execnodes.h:229
struct EState * ecxt_estate
Definition: execnodes.h:254
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
#define AllocSetContextCreate(parent, name, allocparams)
Definition: memutils.h:170
bool domainValue_isNull
Definition: execnodes.h:251
bool * ecxt_aggnulls
Definition: execnodes.h:239
uintptr_t Datum
Definition: postgres.h:367
#define makeNode(_type_)
Definition: nodes.h:565
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:222
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:218
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:225
bool caseValue_isNull
Definition: execnodes.h:245
ParamListInfo ecxt_param_list_info
Definition: execnodes.h:230

◆ ExecAssignExprContext()

◆ ExecAssignProjectionInfo()

void ExecAssignProjectionInfo ( PlanState planstate,
TupleDesc  inputDesc 
)

Definition at line 456 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().

458 {
459  planstate->ps_ProjInfo =
461  planstate->ps_ExprContext,
462  planstate->ps_ResultTupleSlot,
463  planstate,
464  inputDesc);
465 }
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:948
ExprContext * ps_ExprContext
Definition: execnodes.h:947
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:946
Plan * plan
Definition: execnodes.h:912
List * targetlist
Definition: plannodes.h:146
ProjectionInfo * ExecBuildProjectionInfo(List *targetList, ExprContext *econtext, TupleTableSlot *slot, PlanState *parent, TupleDesc inputDesc)
Definition: execExpr.c:349

◆ ExecAssignScanType()

void ExecAssignScanType ( ScanState scanstate,
TupleDesc  tupDesc 
)

Definition at line 586 of file execUtils.c.

References ExecSetSlotDescriptor(), and ScanState::ss_ScanTupleSlot.

Referenced by ExecWorkTableScan().

587 {
588  TupleTableSlot *slot = scanstate->ss_ScanTupleSlot;
589 
590  ExecSetSlotDescriptor(slot, tupDesc);
591 }
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1195
void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc)
Definition: execTuples.c:281

◆ ExecCleanTargetListLength()

int ExecCleanTargetListLength ( List targetlist)

Definition at line 1049 of file execUtils.c.

References lfirst_node, and TargetEntry::resjunk.

Referenced by check_sql_fn_retval(), and ExecTypeFromTLInternal().

1050 {
1051  int len = 0;
1052  ListCell *tl;
1053 
1054  foreach(tl, targetlist)
1055  {
1056  TargetEntry *curTle = lfirst_node(TargetEntry, tl);
1057 
1058  if (!curTle->resjunk)
1059  len++;
1060  }
1061  return len;
1062 }
bool resjunk
Definition: primnodes.h:1383
#define lfirst_node(type, lc)
Definition: pg_list.h:109

◆ ExecCloseScanRelation()

void ExecCloseScanRelation ( Relation  scanrel)

Definition at line 701 of file execUtils.c.

References heap_close, and NoLock.

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

702 {
703  heap_close(scanrel, NoLock);
704 }
#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 476 of file execUtils.c.

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

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

478 {
479  if (tlist_matches_tupdesc(planstate,
480  planstate->plan->targetlist,
481  varno,
482  inputDesc))
483  planstate->ps_ProjInfo = NULL;
484  else
485  ExecAssignProjectionInfo(planstate, inputDesc);
486 }
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:948
void ExecAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc)
Definition: execUtils.c:456
Plan * plan
Definition: execnodes.h:912
static bool tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc)
Definition: execUtils.c:489
List * targetlist
Definition: plannodes.h:146

◆ ExecCreateScanSlotFromOuterPlan()

void ExecCreateScanSlotFromOuterPlan ( EState estate,
ScanState scanstate 
)

Definition at line 598 of file execUtils.c.

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

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

599 {
601  TupleDesc tupDesc;
602 
603  outerPlan = outerPlanState(scanstate);
604  tupDesc = ExecGetResultType(outerPlan);
605 
606  ExecInitScanTupleSlot(estate, scanstate, tupDesc);
607 }
#define outerPlanState(node)
Definition: execnodes.h:966
#define outerPlan(node)
Definition: plannodes.h:176
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:438
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc)
Definition: execTuples.c:915

◆ ExecFreeExprContext()

◆ ExecGetResultType()

◆ ExecLockNonLeafAppendTables()

void ExecLockNonLeafAppendTables ( List partitioned_rels,
EState estate 
)

Definition at line 866 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().

867 {
868  PlannedStmt *stmt = estate->es_plannedstmt;
869  ListCell *lc;
870 
871  foreach(lc, partitioned_rels)
872  {
873  ListCell *l;
874  Index rti = lfirst_int(lc);
875  bool is_result_rel = false;
876  Oid relid = getrelid(rti, estate->es_range_table);
877 
878  /* If this is a result relation, already locked in InitPlan */
879  foreach(l, stmt->nonleafResultRelations)
880  {
881  if (rti == lfirst_int(l))
882  {
883  is_result_rel = true;
884  break;
885  }
886  }
887 
888  /*
889  * Not a result relation; check if there is a RowMark that requires
890  * taking a RowShareLock on this rel.
891  */
892  if (!is_result_rel)
893  {
894  PlanRowMark *rc = NULL;
895 
896  foreach(l, stmt->rowMarks)
897  {
898  if (((PlanRowMark *) lfirst(l))->rti == rti)
899  {
900  rc = lfirst(l);
901  break;
902  }
903  }
904 
905  if (rc && RowMarkRequiresRowShareLock(rc->markType))
907  else
909  }
910  }
911 }
RowMarkType markType
Definition: plannodes.h:1041
List * nonleafResultRelations
Definition: plannodes.h:74
#define AccessShareLock
Definition: lockdefs.h:36
PlannedStmt * es_plannedstmt
Definition: execnodes.h:481
List * es_range_table
Definition: execnodes.h:480
unsigned int Oid
Definition: postgres_ext.h:31
#define RowMarkRequiresRowShareLock(marktype)
Definition: plannodes.h:994
#define lfirst_int(lc)
Definition: pg_list.h:107
#define RowShareLock
Definition: lockdefs.h:37
unsigned int Index
Definition: c.h:442
List * rowMarks
Definition: plannodes.h:88
#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 643 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(), ExecInitSampleScan(), ExecInitSeqScan(), ExecInitTidScan(), and postgresBeginDirectModify().

644 {
645  Relation rel;
646  Oid reloid;
647  LOCKMODE lockmode;
648 
649  /*
650  * Determine the lock type we need. First, scan to see if target relation
651  * is a result relation. If not, check if it's a FOR UPDATE/FOR SHARE
652  * relation. In either of those cases, we got the lock already.
653  */
654  lockmode = AccessShareLock;
655  if (ExecRelationIsTargetRelation(estate, scanrelid))
656  lockmode = NoLock;
657  else
658  {
659  /* Keep this check in sync with InitPlan! */
660  ExecRowMark *erm = ExecFindRowMark(estate, scanrelid, true);
661 
662  if (erm != NULL && erm->relation != NULL)
663  lockmode = NoLock;
664  }
665 
666  /* Open the relation and acquire lock as needed */
667  reloid = getrelid(scanrelid, estate->es_range_table);
668  rel = heap_open(reloid, lockmode);
669 
670  /*
671  * Complain if we're attempting a scan of an unscannable relation, except
672  * when the query won't actually be run. This is a slightly klugy place
673  * to do this, perhaps, but there is no better place.
674  */
675  if ((eflags & (EXEC_FLAG_EXPLAIN_ONLY | EXEC_FLAG_WITH_NO_DATA)) == 0 &&
676  !RelationIsScannable(rel))
677  ereport(ERROR,
678  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
679  errmsg("materialized view \"%s\" has not been populated",
681  errhint("Use the REFRESH MATERIALIZED VIEW command.")));
682 
683  return rel;
684 }
int errhint(const char *fmt,...)
Definition: elog.c:987
int LOCKMODE
Definition: lockdefs.h:26
#define RelationIsScannable(relation)
Definition: rel.h:549
Relation relation
Definition: execnodes.h:596
#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:480
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:441
#define ereport(elevel, rest)
Definition: elog.h:122
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
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:617
ExecRowMark * ExecFindRowMark(EState *estate, Index rti, bool missing_ok)
Definition: execMain.c:2406

◆ ExecRelationIsTargetRelation()

bool ExecRelationIsTargetRelation ( EState estate,
Index  scanrelid 
)

Definition at line 617 of file execUtils.c.

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

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

618 {
619  ResultRelInfo *resultRelInfos;
620  int i;
621 
622  resultRelInfos = estate->es_result_relations;
623  for (i = 0; i < estate->es_num_result_relations; i++)
624  {
625  if (resultRelInfos[i].ri_RangeTableIndex == scanrelid)
626  return true;
627  }
628  return false;
629 }
ResultRelInfo * es_result_relations
Definition: execnodes.h:490
int es_num_result_relations
Definition: execnodes.h:491
int i

◆ ExecTargetListLength()

int ExecTargetListLength ( List targetlist)

Definition at line 1039 of file execUtils.c.

References list_length().

Referenced by ExecTypeFromTLInternal().

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

◆ executor_errposition()

int executor_errposition ( EState estate,
int  location 
)

Definition at line 745 of file execUtils.c.

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

Referenced by ExecInitFunc(), and init_sexpr().

746 {
747  int pos;
748 
749  /* No-op if location was not provided */
750  if (location < 0)
751  return 0;
752  /* Can't do anything if source text is not available */
753  if (estate == NULL || estate->es_sourceText == NULL)
754  return 0;
755  /* Convert offset to character number */
756  pos = pg_mbstrlen_with_len(estate->es_sourceText, location) + 1;
757  /* And pass it to the ereport mechanism */
758  return errposition(pos);
759 }
int pg_mbstrlen_with_len(const char *mbstr, int limit)
Definition: mbutils.c:794
const char * es_sourceText
Definition: execnodes.h:482
int errposition(int cursorpos)
Definition: elog.c:1125

◆ FreeExecutorState()

void FreeExecutorState ( EState estate)

Definition at line 188 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(), ExecuteTruncateGuts(), ExplainExecuteQuery(), get_actual_variable_range(), get_qual_for_range(), IndexBuildHeapRangeScan(), IndexCheckExclusion(), operator_predicate_proof(), plpgsql_inline_handler(), plpgsql_xact_cb(), ProjIndexIsUnchanged(), standard_ExecutorEnd(), StoreAttrDefault(), tuplesort_end(), unique_key_recheck(), validate_index_heapscan(), validateCheckConstraint(), and validateDomainConstraint().

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

◆ FreeExprContext()

void FreeExprContext ( ExprContext econtext,
bool  isCommit 
)

Definition at line 359 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().

360 {
361  EState *estate;
362 
363  /* Call any registered callbacks */
364  ShutdownExprContext(econtext, isCommit);
365  /* And clean up the memory used */
367  /* Unlink self from owning EState, if any */
368  estate = econtext->ecxt_estate;
369  if (estate)
371  econtext);
372  /* And delete the ExprContext node */
373  pfree(econtext);
374 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:211
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:226
List * list_delete_ptr(List *list, void *datum)
Definition: list.c:590
void pfree(void *pointer)
Definition: mcxt.c:1031
struct EState * ecxt_estate
Definition: execnodes.h:254
static void ShutdownExprContext(ExprContext *econtext, bool isCommit)
Definition: execUtils.c:829
List * es_exprcontexts
Definition: execnodes.h:536

◆ GetAttributeByName()

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

Definition at line 925 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().

926 {
927  AttrNumber attrno;
928  Datum result;
929  Oid tupType;
930  int32 tupTypmod;
931  TupleDesc tupDesc;
932  HeapTupleData tmptup;
933  int i;
934 
935  if (attname == NULL)
936  elog(ERROR, "invalid attribute name");
937 
938  if (isNull == NULL)
939  elog(ERROR, "a NULL isNull pointer was passed");
940 
941  if (tuple == NULL)
942  {
943  /* Kinda bogus but compatible with old behavior... */
944  *isNull = true;
945  return (Datum) 0;
946  }
947 
948  tupType = HeapTupleHeaderGetTypeId(tuple);
949  tupTypmod = HeapTupleHeaderGetTypMod(tuple);
950  tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
951 
952  attrno = InvalidAttrNumber;
953  for (i = 0; i < tupDesc->natts; i++)
954  {
955  Form_pg_attribute att = TupleDescAttr(tupDesc, i);
956 
957  if (namestrcmp(&(att->attname), attname) == 0)
958  {
959  attrno = att->attnum;
960  break;
961  }
962  }
963 
964  if (attrno == InvalidAttrNumber)
965  elog(ERROR, "attribute \"%s\" does not exist", attname);
966 
967  /*
968  * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
969  * the fields in the struct just in case user tries to inspect system
970  * columns.
971  */
972  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
973  ItemPointerSetInvalid(&(tmptup.t_self));
974  tmptup.t_tableOid = InvalidOid;
975  tmptup.t_data = tuple;
976 
977  result = heap_getattr(&tmptup,
978  attrno,
979  tupDesc,
980  isNull);
981 
982  ReleaseTupleDesc(tupDesc);
983 
984  return result;
985 }
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition: typcache.c:1641
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:93
int namestrcmp(Name name, const char *str)
Definition: name.c:247
unsigned int Oid
Definition: postgres_ext.h:31
int natts
Definition: tupdesc.h:82
signed int int32
Definition: c.h:313
HeapTupleHeader t_data
Definition: htup.h:68
#define HeapTupleHeaderGetTypMod(tup)
Definition: htup_details.h:467
#define ERROR
Definition: elog.h:43
NameData attname
Definition: pg_attribute.h:40
ItemPointerData t_self
Definition: htup.h:65
uint32 t_len
Definition: htup.h:64
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:197
Oid t_tableOid
Definition: htup.h:66
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:781
uintptr_t Datum
Definition: postgres.h:367
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:457
#define InvalidOid
Definition: postgres_ext.h:36
#define InvalidAttrNumber
Definition: attnum.h:23
#define ItemPointerSetInvalid(pointer)
Definition: itemptr.h:172
int i
#define elog
Definition: elog.h:219
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:124
int16 AttrNumber
Definition: attnum.h:21
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:451

◆ GetAttributeByNum()

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

Definition at line 988 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.

991 {
992  Datum result;
993  Oid tupType;
994  int32 tupTypmod;
995  TupleDesc tupDesc;
996  HeapTupleData tmptup;
997 
998  if (!AttributeNumberIsValid(attrno))
999  elog(ERROR, "invalid attribute number %d", attrno);
1000 
1001  if (isNull == NULL)
1002  elog(ERROR, "a NULL isNull pointer was passed");
1003 
1004  if (tuple == NULL)
1005  {
1006  /* Kinda bogus but compatible with old behavior... */
1007  *isNull = true;
1008  return (Datum) 0;
1009  }
1010 
1011  tupType = HeapTupleHeaderGetTypeId(tuple);
1012  tupTypmod = HeapTupleHeaderGetTypMod(tuple);
1013  tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
1014 
1015  /*
1016  * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
1017  * the fields in the struct just in case user tries to inspect system
1018  * columns.
1019  */
1020  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
1021  ItemPointerSetInvalid(&(tmptup.t_self));
1022  tmptup.t_tableOid = InvalidOid;
1023  tmptup.t_data = tuple;
1024 
1025  result = heap_getattr(&tmptup,
1026  attrno,
1027  tupDesc,
1028  isNull);
1029 
1030  ReleaseTupleDesc(tupDesc);
1031 
1032  return result;
1033 }
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition: typcache.c:1641
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:313
HeapTupleHeader t_data
Definition: htup.h:68
#define HeapTupleHeaderGetTypMod(tup)
Definition: htup_details.h:467
#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:781
#define AttributeNumberIsValid(attributeNumber)
Definition: attnum.h:34
uintptr_t Datum
Definition: postgres.h:367
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:457
#define InvalidOid
Definition: postgres_ext.h:36
#define ItemPointerSetInvalid(pointer)
Definition: itemptr.h:172
#define elog
Definition: elog.h:219
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:124
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:451

◆ MakePerTupleExprContext()

ExprContext* MakePerTupleExprContext ( EState estate)

Definition at line 401 of file execUtils.c.

References CreateExprContext(), and EState::es_per_tuple_exprcontext.

402 {
403  if (estate->es_per_tuple_exprcontext == NULL)
405 
406  return estate->es_per_tuple_exprcontext;
407 }
ExprContext * es_per_tuple_exprcontext
Definition: execnodes.h:547
ExprContext * CreateExprContext(EState *estate)
Definition: execUtils.c:228

◆ RegisterExprContextCallback()

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

Definition at line 772 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().

775 {
776  ExprContext_CB *ecxt_callback;
777 
778  /* Save the info in appropriate memory context */
779  ecxt_callback = (ExprContext_CB *)
781  sizeof(ExprContext_CB));
782 
783  ecxt_callback->function = function;
784  ecxt_callback->arg = arg;
785 
786  /* link to front of list for appropriate execution order */
787  ecxt_callback->next = econtext->ecxt_callbacks;
788  econtext->ecxt_callbacks = ecxt_callback;
789 }
ExprContextCallbackFunction function
Definition: execnodes.h:185
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:257
struct ExprContext_CB * next
Definition: execnodes.h:184
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:225
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:771
void * arg

◆ ReScanExprContext()

void ReScanExprContext ( ExprContext econtext)

Definition at line 386 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().

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

◆ ShutdownExprContext()

static void ShutdownExprContext ( ExprContext econtext,
bool  isCommit 
)
static

Definition at line 829 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().

830 {
831  ExprContext_CB *ecxt_callback;
832  MemoryContext oldcontext;
833 
834  /* Fast path in normal case where there's nothing to do. */
835  if (econtext->ecxt_callbacks == NULL)
836  return;
837 
838  /*
839  * Call the callbacks in econtext's per-tuple context. This ensures that
840  * any memory they might leak will get cleaned up.
841  */
842  oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
843 
844  /*
845  * Call each callback function in reverse registration order.
846  */
847  while ((ecxt_callback = econtext->ecxt_callbacks) != NULL)
848  {
849  econtext->ecxt_callbacks = ecxt_callback->next;
850  if (isCommit)
851  ecxt_callback->function(ecxt_callback->arg);
852  pfree(ecxt_callback);
853  }
854 
855  MemoryContextSwitchTo(oldcontext);
856 }
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:226
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void pfree(void *pointer)
Definition: mcxt.c:1031
ExprContextCallbackFunction function
Definition: execnodes.h:185
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:257
struct ExprContext_CB * next
Definition: execnodes.h:184

◆ tlist_matches_tupdesc()

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

Definition at line 489 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().

490 {
491  int numattrs = tupdesc->natts;
492  int attrno;
493  bool hasoid;
494  ListCell *tlist_item = list_head(tlist);
495 
496  /* Check the tlist attributes */
497  for (attrno = 1; attrno <= numattrs; attrno++)
498  {
499  Form_pg_attribute att_tup = TupleDescAttr(tupdesc, attrno - 1);
500  Var *var;
501 
502  if (tlist_item == NULL)
503  return false; /* tlist too short */
504  var = (Var *) ((TargetEntry *) lfirst(tlist_item))->expr;
505  if (!var || !IsA(var, Var))
506  return false; /* tlist item not a Var */
507  /* if these Asserts fail, planner messed up */
508  Assert(var->varno == varno);
509  Assert(var->varlevelsup == 0);
510  if (var->varattno != attrno)
511  return false; /* out of order */
512  if (att_tup->attisdropped)
513  return false; /* table contains dropped columns */
514  if (att_tup->atthasmissing)
515  return false; /* table contains cols with missing values */
516 
517  /*
518  * Note: usually the Var's type should match the tupdesc exactly, but
519  * in situations involving unions of columns that have different
520  * typmods, the Var may have come from above the union and hence have
521  * typmod -1. This is a legitimate situation since the Var still
522  * describes the column, just not as exactly as the tupdesc does. We
523  * could change the planner to prevent it, but it'd then insert
524  * projection steps just to convert from specific typmod to typmod -1,
525  * which is pretty silly.
526  */
527  if (var->vartype != att_tup->atttypid ||
528  (var->vartypmod != att_tup->atttypmod &&
529  var->vartypmod != -1))
530  return false; /* type mismatch */
531 
532  tlist_item = lnext(tlist_item);
533  }
534 
535  if (tlist_item)
536  return false; /* tlist too long */
537 
538  /*
539  * If the plan context requires a particular hasoid setting, then that has
540  * to match, too.
541  */
542  if (ExecContextForcesOids(ps, &hasoid) &&
543  hasoid != tupdesc->tdhasoid)
544  return false;
545 
546  return true;
547 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:568
Index varlevelsup
Definition: primnodes.h:174
bool tdhasoid
Definition: tupdesc.h:85
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:93
AttrNumber varattno
Definition: primnodes.h:169
Definition: primnodes.h:164
int natts
Definition: tupdesc.h:82
Oid vartype
Definition: primnodes.h:171
static ListCell * list_head(const List *l)
Definition: pg_list.h:77
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:197
#define lnext(lc)
Definition: pg_list.h:105
Index varno
Definition: primnodes.h:167
#define Assert(condition)
Definition: c.h:699
#define lfirst(lc)
Definition: pg_list.h:106
bool ExecContextForcesOids(PlanState *planstate, bool *hasoids)
Definition: execMain.c:1521
int32 vartypmod
Definition: primnodes.h:172

◆ UnregisterExprContextCallback()

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

Definition at line 798 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().

801 {
802  ExprContext_CB **prev_callback;
803  ExprContext_CB *ecxt_callback;
804 
805  prev_callback = &econtext->ecxt_callbacks;
806 
807  while ((ecxt_callback = *prev_callback) != NULL)
808  {
809  if (ecxt_callback->function == function && ecxt_callback->arg == arg)
810  {
811  *prev_callback = ecxt_callback->next;
812  pfree(ecxt_callback);
813  }
814  else
815  prev_callback = &ecxt_callback->next;
816  }
817 }
void pfree(void *pointer)
Definition: mcxt.c:1031
ExprContextCallbackFunction function
Definition: execnodes.h:185
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:257
struct ExprContext_CB * next
Definition: execnodes.h:184
void * arg

◆ UpdateChangedParamSet()

void UpdateChangedParamSet ( PlanState node,
Bitmapset newchg 
)

Definition at line 711 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().

712 {
713  Bitmapset *parmset;
714 
715  /*
716  * The plan node only depends on params listed in its allParam set. Don't
717  * include anything else into its chgParam set.
718  */
719  parmset = bms_intersect(node->plan->allParam, newchg);
720 
721  /*
722  * Keep node->chgParam == NULL if there's not actually any members; this
723  * allows the simplest possible tests in executor node files.
724  */
725  if (!bms_is_empty(parmset))
726  node->chgParam = bms_join(node->chgParam, parmset);
727  else
728  bms_free(parmset);
729 }
Bitmapset * bms_join(Bitmapset *a, Bitmapset *b)
Definition: bitmapset.c:976
Bitmapset * allParam
Definition: plannodes.h:165
Bitmapset * chgParam
Definition: execnodes.h:941
bool bms_is_empty(const Bitmapset *a)
Definition: bitmapset.c:729
Bitmapset * bms_intersect(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:318
Plan * plan
Definition: execnodes.h:912
void bms_free(Bitmapset *a)
Definition: bitmapset.c:267