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 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 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 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_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(), 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().

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 
121  estate->es_leaf_result_relations = NIL;
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  /*
162  * Return the executor state structure
163  */
164  MemoryContextSwitchTo(oldcontext);
165 
166  return estate;
167 }
#define NIL
Definition: pg_list.h:69
uint32 CommandId
Definition: c.h:459
HeapTuple * es_epqTuple
Definition: execnodes.h:506
JunkFilter * es_junkFilter
Definition: execnodes.h:435
CommandId es_output_cid
Definition: execnodes.h:438
TupleTableSlot * es_trig_newtup_slot
Definition: execnodes.h:462
Oid es_lastoid
Definition: execnodes.h:478
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
PlannedStmt * es_plannedstmt
Definition: execnodes.h:432
Snapshot es_crosscheck_snapshot
Definition: execnodes.h:430
ExprContext * es_per_tuple_exprcontext
Definition: execnodes.h:495
Snapshot es_snapshot
Definition: execnodes.h:429
List * es_range_table
Definition: execnodes.h:431
ScanDirection es_direction
Definition: execnodes.h:428
bool es_use_parallel_mode
Definition: execnodes.h:510
const char * es_sourceText
Definition: execnodes.h:433
ParamExecData * es_param_exec_vals
Definition: execnodes.h:466
MemoryContext es_query_cxt
Definition: execnodes.h:471
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:165
ResultRelInfo * es_result_relations
Definition: execnodes.h:441
TupleTableSlot * es_trig_oldtup_slot
Definition: execnodes.h:461
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
int es_instrument
Definition: execnodes.h:481
TupleTableSlot * es_trig_tuple_slot
Definition: execnodes.h:460
List * es_leaf_result_relations
Definition: execnodes.h:456
QueryEnvironment * es_queryEnv
Definition: execnodes.h:468
int es_num_root_result_relations
Definition: execnodes.h:453
#define InvalidSnapshot
Definition: snapshot.h:25
List * es_trig_target_relations
Definition: execnodes.h:459
List * es_tupleTable
Definition: execnodes.h:473
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:322
List * es_auxmodifytables
Definition: execnodes.h:488
int es_num_result_relations
Definition: execnodes.h:442
#define InvalidOid
Definition: postgres_ext.h:36
bool es_finished
Definition: execnodes.h:482
#define makeNode(_type_)
Definition: nodes.h:558
uint64 es_processed
Definition: execnodes.h:477
bool * es_epqTupleSet
Definition: execnodes.h:507
List * es_subplanstates
Definition: execnodes.h:486
List * es_rowMarks
Definition: execnodes.h:475
int es_top_eflags
Definition: execnodes.h:480
ResultRelInfo * es_root_result_relations
Definition: execnodes.h:452
bool * es_epqScanDone
Definition: execnodes.h:508
ParamListInfo es_param_list_info
Definition: execnodes.h:465
List * es_exprcontexts
Definition: execnodes.h:484
ResultRelInfo * es_result_relation_info
Definition: execnodes.h:443

◆ CreateExprContext()

ExprContext* CreateExprContext ( EState estate)

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

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

◆ CreateStandaloneExprContext()

ExprContext* CreateStandaloneExprContext ( void  )

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

298 {
299  ExprContext *econtext;
300 
301  /* Create the ExprContext node within the caller's memory context */
302  econtext = makeNode(ExprContext);
303 
304  /* Initialize fields of ExprContext */
305  econtext->ecxt_scantuple = NULL;
306  econtext->ecxt_innertuple = NULL;
307  econtext->ecxt_outertuple = NULL;
308 
310 
311  /*
312  * Create working memory for expression evaluation in this context.
313  */
314  econtext->ecxt_per_tuple_memory =
316  "ExprContext",
318 
319  econtext->ecxt_param_exec_vals = NULL;
320  econtext->ecxt_param_list_info = NULL;
321 
322  econtext->ecxt_aggvalues = NULL;
323  econtext->ecxt_aggnulls = NULL;
324 
325  econtext->caseValue_datum = (Datum) 0;
326  econtext->caseValue_isNull = true;
327 
328  econtext->domainValue_datum = (Datum) 0;
329  econtext->domainValue_isNull = true;
330 
331  econtext->ecxt_estate = NULL;
332 
333  econtext->ecxt_callbacks = NULL;
334 
335  return econtext;
336 }
Datum * ecxt_aggvalues
Definition: execnodes.h:213
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:203
Datum domainValue_datum
Definition: execnodes.h:221
Datum caseValue_datum
Definition: execnodes.h:217
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:228
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:165
TupleTableSlot * ecxt_innertuple
Definition: execnodes.h:198
ParamExecData * ecxt_param_exec_vals
Definition: execnodes.h:206
struct EState * ecxt_estate
Definition: execnodes.h:225
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
bool domainValue_isNull
Definition: execnodes.h:222
bool * ecxt_aggnulls
Definition: execnodes.h:214
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:322
uintptr_t Datum
Definition: postgres.h:372
#define makeNode(_type_)
Definition: nodes.h:558
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:199
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:197
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:202
bool caseValue_isNull
Definition: execnodes.h:218
ParamListInfo ecxt_param_list_info
Definition: execnodes.h:207

◆ ExecAssignExprContext()

◆ ExecAssignProjectionInfo()

void ExecAssignProjectionInfo ( PlanState planstate,
TupleDesc  inputDesc 
)

Definition at line 494 of file execUtils.c.

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

Referenced by ExecAssignScanProjectionInfoWithVarno(), ExecInitAgg(), ExecInitGather(), ExecInitGatherMerge(), ExecInitGroup(), ExecInitHashJoin(), ExecInitMergeJoin(), ExecInitNestLoop(), ExecInitResult(), and ExecInitWindowAgg().

496 {
497  planstate->ps_ProjInfo =
499  planstate->ps_ExprContext,
500  planstate->ps_ResultTupleSlot,
501  planstate,
502  inputDesc);
503 }
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:884
ExprContext * ps_ExprContext
Definition: execnodes.h:883
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:882
Plan * plan
Definition: execnodes.h:849
List * targetlist
Definition: plannodes.h:144
ProjectionInfo * ExecBuildProjectionInfo(List *targetList, ExprContext *econtext, TupleTableSlot *slot, PlanState *parent, TupleDesc inputDesc)
Definition: execExpr.c:301

◆ ExecAssignResultType()

void ExecAssignResultType ( PlanState planstate,
TupleDesc  tupDesc 
)

Definition at line 435 of file execUtils.c.

References ExecSetSlotDescriptor(), and PlanState::ps_ResultTupleSlot.

Referenced by ExecAssignResultTypeFromTL(), and ExecInitModifyTable().

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

◆ ExecAssignResultTypeFromTL()

void ExecAssignResultTypeFromTL ( PlanState planstate)

Definition at line 447 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(), ExecInitNamedTuplestoreScan(), ExecInitNestLoop(), ExecInitProjectSet(), ExecInitRecursiveUnion(), ExecInitResult(), ExecInitSampleScan(), ExecInitSeqScan(), ExecInitSetOp(), ExecInitSort(), ExecInitSubqueryScan(), ExecInitTableFuncScan(), ExecInitTidScan(), ExecInitUnique(), ExecInitValuesScan(), ExecInitWindowAgg(), and ExecInitWorkTableScan().

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

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

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

560 {
562  TupleDesc tupDesc;
563 
564  outerPlan = outerPlanState(scanstate);
565  tupDesc = ExecGetResultType(outerPlan);
566 
567  ExecAssignScanType(scanstate, tupDesc);
568 }
#define outerPlanState(node)
Definition: execnodes.h:895
#define outerPlan(node)
Definition: plannodes.h:174
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:476
void ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc)
Definition: execUtils.c:547

◆ ExecCleanTargetListLength()

int ExecCleanTargetListLength ( List targetlist)

Definition at line 1016 of file execUtils.c.

References lfirst_node, and TargetEntry::resjunk.

Referenced by check_sql_fn_retval(), and ExecTypeFromTLInternal().

1017 {
1018  int len = 0;
1019  ListCell *tl;
1020 
1021  foreach(tl, targetlist)
1022  {
1023  TargetEntry *curTle = lfirst_node(TargetEntry, tl);
1024 
1025  if (!curTle->resjunk)
1026  len++;
1027  }
1028  return len;
1029 }
bool resjunk
Definition: primnodes.h:1382
#define lfirst_node(type, lc)
Definition: pg_list.h:109

◆ ExecCloseScanRelation()

void ExecCloseScanRelation ( Relation  scanrel)

Definition at line 668 of file execUtils.c.

References heap_close, and NoLock.

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

669 {
670  heap_close(scanrel, NoLock);
671 }
#define heap_close(r, l)
Definition: heapam.h:97
#define NoLock
Definition: lockdefs.h:34

◆ ExecFreeExprContext()

◆ ExecGetResultType()

◆ ExecLockNonLeafAppendTables()

void ExecLockNonLeafAppendTables ( List partitioned_rels,
EState estate 
)

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

834 {
835  PlannedStmt *stmt = estate->es_plannedstmt;
836  ListCell *lc;
837 
838  foreach(lc, partitioned_rels)
839  {
840  ListCell *l;
841  Index rti = lfirst_int(lc);
842  bool is_result_rel = false;
843  Oid relid = getrelid(rti, estate->es_range_table);
844 
845  /* If this is a result relation, already locked in InitPlan */
846  foreach(l, stmt->nonleafResultRelations)
847  {
848  if (rti == lfirst_int(l))
849  {
850  is_result_rel = true;
851  break;
852  }
853  }
854 
855  /*
856  * Not a result relation; check if there is a RowMark that requires
857  * taking a RowShareLock on this rel.
858  */
859  if (!is_result_rel)
860  {
861  PlanRowMark *rc = NULL;
862 
863  foreach(l, stmt->rowMarks)
864  {
865  if (((PlanRowMark *) lfirst(l))->rti == rti)
866  {
867  rc = lfirst(l);
868  break;
869  }
870  }
871 
872  if (rc && RowMarkRequiresRowShareLock(rc->markType))
874  else
876  }
877  }
878 }
RowMarkType markType
Definition: plannodes.h:1020
List * nonleafResultRelations
Definition: plannodes.h:72
#define AccessShareLock
Definition: lockdefs.h:36
PlannedStmt * es_plannedstmt
Definition: execnodes.h:432
List * es_range_table
Definition: execnodes.h:431
unsigned int Oid
Definition: postgres_ext.h:31
#define RowMarkRequiresRowShareLock(marktype)
Definition: plannodes.h:973
#define lfirst_int(lc)
Definition: pg_list.h:107
#define RowShareLock
Definition: lockdefs.h:37
unsigned int Index
Definition: c.h:413
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 610 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().

611 {
612  Relation rel;
613  Oid reloid;
614  LOCKMODE lockmode;
615 
616  /*
617  * Determine the lock type we need. First, scan to see if target relation
618  * is a result relation. If not, check if it's a FOR UPDATE/FOR SHARE
619  * relation. In either of those cases, we got the lock already.
620  */
621  lockmode = AccessShareLock;
622  if (ExecRelationIsTargetRelation(estate, scanrelid))
623  lockmode = NoLock;
624  else
625  {
626  /* Keep this check in sync with InitPlan! */
627  ExecRowMark *erm = ExecFindRowMark(estate, scanrelid, true);
628 
629  if (erm != NULL && erm->relation != NULL)
630  lockmode = NoLock;
631  }
632 
633  /* Open the relation and acquire lock as needed */
634  reloid = getrelid(scanrelid, estate->es_range_table);
635  rel = heap_open(reloid, lockmode);
636 
637  /*
638  * Complain if we're attempting a scan of an unscannable relation, except
639  * when the query won't actually be run. This is a slightly klugy place
640  * to do this, perhaps, but there is no better place.
641  */
642  if ((eflags & (EXEC_FLAG_EXPLAIN_ONLY | EXEC_FLAG_WITH_NO_DATA)) == 0 &&
643  !RelationIsScannable(rel))
644  ereport(ERROR,
645  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
646  errmsg("materialized view \"%s\" has not been populated",
648  errhint("Use the REFRESH MATERIALIZED VIEW command.")));
649 
650  return rel;
651 }
int errhint(const char *fmt,...)
Definition: elog.c:987
int LOCKMODE
Definition: lockdefs.h:26
#define RelationIsScannable(relation)
Definition: rel.h:544
Relation relation
Definition: execnodes.h:536
#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:431
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:436
#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:584
ExecRowMark * ExecFindRowMark(EState *estate, Index rti, bool missing_ok)
Definition: execMain.c:2383

◆ ExecRelationIsTargetRelation()

bool ExecRelationIsTargetRelation ( EState estate,
Index  scanrelid 
)

Definition at line 584 of file execUtils.c.

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

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

585 {
586  ResultRelInfo *resultRelInfos;
587  int i;
588 
589  resultRelInfos = estate->es_result_relations;
590  for (i = 0; i < estate->es_num_result_relations; i++)
591  {
592  if (resultRelInfos[i].ri_RangeTableIndex == scanrelid)
593  return true;
594  }
595  return false;
596 }
ResultRelInfo * es_result_relations
Definition: execnodes.h:441
int es_num_result_relations
Definition: execnodes.h:442
int i

◆ ExecTargetListLength()

int ExecTargetListLength ( List targetlist)

Definition at line 1006 of file execUtils.c.

References list_length().

Referenced by ExecTypeFromTLInternal().

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

◆ executor_errposition()

int executor_errposition ( EState estate,
int  location 
)

Definition at line 712 of file execUtils.c.

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

Referenced by ExecInitFunc(), and init_sexpr().

713 {
714  int pos;
715 
716  /* No-op if location was not provided */
717  if (location < 0)
718  return 0;
719  /* Can't do anything if source text is not available */
720  if (estate == NULL || estate->es_sourceText == NULL)
721  return 0;
722  /* Convert offset to character number */
723  pos = pg_mbstrlen_with_len(estate->es_sourceText, location) + 1;
724  /* And pass it to the ereport mechanism */
725  return errposition(pos);
726 }
int pg_mbstrlen_with_len(const char *mbstr, int limit)
Definition: mbutils.c:794
const char * es_sourceText
Definition: execnodes.h:433
int errposition(int cursorpos)
Definition: elog.c:1125

◆ FreeExecutorState()

void FreeExecutorState ( EState estate)

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

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

◆ FreeExprContext()

void FreeExprContext ( ExprContext econtext,
bool  isCommit 
)

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

357 {
358  EState *estate;
359 
360  /* Call any registered callbacks */
361  ShutdownExprContext(econtext, isCommit);
362  /* And clean up the memory used */
364  /* Unlink self from owning EState, if any */
365  estate = econtext->ecxt_estate;
366  if (estate)
368  econtext);
369  /* And delete the ExprContext node */
370  pfree(econtext);
371 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:200
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:203
List * list_delete_ptr(List *list, void *datum)
Definition: list.c:590
void pfree(void *pointer)
Definition: mcxt.c:949
struct EState * ecxt_estate
Definition: execnodes.h:225
static void ShutdownExprContext(ExprContext *econtext, bool isCommit)
Definition: execUtils.c:796
List * es_exprcontexts
Definition: execnodes.h:484

◆ GetAttributeByName()

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

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

893 {
894  AttrNumber attrno;
895  Datum result;
896  Oid tupType;
897  int32 tupTypmod;
898  TupleDesc tupDesc;
899  HeapTupleData tmptup;
900  int i;
901 
902  if (attname == NULL)
903  elog(ERROR, "invalid attribute name");
904 
905  if (isNull == NULL)
906  elog(ERROR, "a NULL isNull pointer was passed");
907 
908  if (tuple == NULL)
909  {
910  /* Kinda bogus but compatible with old behavior... */
911  *isNull = true;
912  return (Datum) 0;
913  }
914 
915  tupType = HeapTupleHeaderGetTypeId(tuple);
916  tupTypmod = HeapTupleHeaderGetTypMod(tuple);
917  tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
918 
919  attrno = InvalidAttrNumber;
920  for (i = 0; i < tupDesc->natts; i++)
921  {
922  Form_pg_attribute att = TupleDescAttr(tupDesc, i);
923 
924  if (namestrcmp(&(att->attname), attname) == 0)
925  {
926  attrno = att->attnum;
927  break;
928  }
929  }
930 
931  if (attrno == InvalidAttrNumber)
932  elog(ERROR, "attribute \"%s\" does not exist", attname);
933 
934  /*
935  * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
936  * the fields in the struct just in case user tries to inspect system
937  * columns.
938  */
939  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
940  ItemPointerSetInvalid(&(tmptup.t_self));
941  tmptup.t_tableOid = InvalidOid;
942  tmptup.t_data = tuple;
943 
944  result = heap_getattr(&tmptup,
945  attrno,
946  tupDesc,
947  isNull);
948 
949  ReleaseTupleDesc(tupDesc);
950 
951  return result;
952 }
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:284
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 955 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.

958 {
959  Datum result;
960  Oid tupType;
961  int32 tupTypmod;
962  TupleDesc tupDesc;
963  HeapTupleData tmptup;
964 
965  if (!AttributeNumberIsValid(attrno))
966  elog(ERROR, "invalid attribute number %d", attrno);
967 
968  if (isNull == NULL)
969  elog(ERROR, "a NULL isNull pointer was passed");
970 
971  if (tuple == NULL)
972  {
973  /* Kinda bogus but compatible with old behavior... */
974  *isNull = true;
975  return (Datum) 0;
976  }
977 
978  tupType = HeapTupleHeaderGetTypeId(tuple);
979  tupTypmod = HeapTupleHeaderGetTypMod(tuple);
980  tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
981 
982  /*
983  * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
984  * the fields in the struct just in case user tries to inspect system
985  * columns.
986  */
987  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
988  ItemPointerSetInvalid(&(tmptup.t_self));
989  tmptup.t_tableOid = InvalidOid;
990  tmptup.t_data = tuple;
991 
992  result = heap_getattr(&tmptup,
993  attrno,
994  tupDesc,
995  isNull);
996 
997  ReleaseTupleDesc(tupDesc);
998 
999  return result;
1000 }
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:284
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 398 of file execUtils.c.

References CreateExprContext(), and EState::es_per_tuple_exprcontext.

399 {
400  if (estate->es_per_tuple_exprcontext == NULL)
402 
403  return estate->es_per_tuple_exprcontext;
404 }
ExprContext * es_per_tuple_exprcontext
Definition: execnodes.h:495
ExprContext * CreateExprContext(EState *estate)
Definition: execUtils.c:225

◆ RegisterExprContextCallback()

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

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

742 {
743  ExprContext_CB *ecxt_callback;
744 
745  /* Save the info in appropriate memory context */
746  ecxt_callback = (ExprContext_CB *)
748  sizeof(ExprContext_CB));
749 
750  ecxt_callback->function = function;
751  ecxt_callback->arg = arg;
752 
753  /* link to front of list for appropriate execution order */
754  ecxt_callback->next = econtext->ecxt_callbacks;
755  econtext->ecxt_callbacks = ecxt_callback;
756 }
ExprContextCallbackFunction function
Definition: execnodes.h:165
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:228
struct ExprContext_CB * next
Definition: execnodes.h:164
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:202
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:706
void * arg

◆ ReScanExprContext()

void ReScanExprContext ( ExprContext econtext)

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

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

◆ ShutdownExprContext()

static void ShutdownExprContext ( ExprContext econtext,
bool  isCommit 
)
static

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

797 {
798  ExprContext_CB *ecxt_callback;
799  MemoryContext oldcontext;
800 
801  /* Fast path in normal case where there's nothing to do. */
802  if (econtext->ecxt_callbacks == NULL)
803  return;
804 
805  /*
806  * Call the callbacks in econtext's per-tuple context. This ensures that
807  * any memory they might leak will get cleaned up.
808  */
809  oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
810 
811  /*
812  * Call each callback function in reverse registration order.
813  */
814  while ((ecxt_callback = econtext->ecxt_callbacks) != NULL)
815  {
816  econtext->ecxt_callbacks = ecxt_callback->next;
817  if (isCommit)
818  ecxt_callback->function(ecxt_callback->arg);
819  pfree(ecxt_callback);
820  }
821 
822  MemoryContextSwitchTo(oldcontext);
823 }
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:203
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void pfree(void *pointer)
Definition: mcxt.c:949
ExprContextCallbackFunction function
Definition: execnodes.h:165
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:228
struct ExprContext_CB * next
Definition: execnodes.h:164

◆ UnregisterExprContextCallback()

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

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

768 {
769  ExprContext_CB **prev_callback;
770  ExprContext_CB *ecxt_callback;
771 
772  prev_callback = &econtext->ecxt_callbacks;
773 
774  while ((ecxt_callback = *prev_callback) != NULL)
775  {
776  if (ecxt_callback->function == function && ecxt_callback->arg == arg)
777  {
778  *prev_callback = ecxt_callback->next;
779  pfree(ecxt_callback);
780  }
781  else
782  prev_callback = &ecxt_callback->next;
783  }
784 }
void pfree(void *pointer)
Definition: mcxt.c:949
ExprContextCallbackFunction function
Definition: execnodes.h:165
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:228
struct ExprContext_CB * next
Definition: execnodes.h:164
void * arg

◆ UpdateChangedParamSet()

void UpdateChangedParamSet ( PlanState node,
Bitmapset newchg 
)

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

679 {
680  Bitmapset *parmset;
681 
682  /*
683  * The plan node only depends on params listed in its allParam set. Don't
684  * include anything else into its chgParam set.
685  */
686  parmset = bms_intersect(node->plan->allParam, newchg);
687 
688  /*
689  * Keep node->chgParam == NULL if there's not actually any members; this
690  * allows the simplest possible tests in executor node files.
691  */
692  if (!bms_is_empty(parmset))
693  node->chgParam = bms_join(node->chgParam, parmset);
694  else
695  bms_free(parmset);
696 }
Bitmapset * bms_join(Bitmapset *a, Bitmapset *b)
Definition: bitmapset.c:838
Bitmapset * allParam
Definition: plannodes.h:163
Bitmapset * chgParam
Definition: execnodes.h:877
bool bms_is_empty(const Bitmapset *a)
Definition: bitmapset.c:663
Bitmapset * bms_intersect(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:252
Plan * plan
Definition: execnodes.h:849
void bms_free(Bitmapset *a)
Definition: bitmapset.c:201