PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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

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, 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  /*
160  * Return the executor state structure
161  */
162  MemoryContextSwitchTo(oldcontext);
163 
164  return estate;
165 }
#define NIL
Definition: pg_list.h:69
uint32 CommandId
Definition: c.h:405
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
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:557
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
ExprContext* CreateExprContext ( EState estate)

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

224 {
225  ExprContext *econtext;
226  MemoryContext oldcontext;
227 
228  /* Create the ExprContext node within the per-query memory context */
229  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
230 
231  econtext = makeNode(ExprContext);
232 
233  /* Initialize fields of ExprContext */
234  econtext->ecxt_scantuple = NULL;
235  econtext->ecxt_innertuple = NULL;
236  econtext->ecxt_outertuple = NULL;
237 
238  econtext->ecxt_per_query_memory = estate->es_query_cxt;
239 
240  /*
241  * Create working memory for expression evaluation in this context.
242  */
243  econtext->ecxt_per_tuple_memory =
245  "ExprContext",
247 
248  econtext->ecxt_param_exec_vals = estate->es_param_exec_vals;
249  econtext->ecxt_param_list_info = estate->es_param_list_info;
250 
251  econtext->ecxt_aggvalues = NULL;
252  econtext->ecxt_aggnulls = NULL;
253 
254  econtext->caseValue_datum = (Datum) 0;
255  econtext->caseValue_isNull = true;
256 
257  econtext->domainValue_datum = (Datum) 0;
258  econtext->domainValue_isNull = true;
259 
260  econtext->ecxt_estate = estate;
261 
262  econtext->ecxt_callbacks = NULL;
263 
264  /*
265  * Link the ExprContext into the EState to ensure it is shut down when the
266  * EState is freed. Because we use lcons(), shutdowns will occur in
267  * reverse order of creation, which may not be essential but can't hurt.
268  */
269  estate->es_exprcontexts = lcons(econtext, estate->es_exprcontexts);
270 
271  MemoryContextSwitchTo(oldcontext);
272 
273  return econtext;
274 }
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:557
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
ExprContext* CreateStandaloneExprContext ( void  )

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

296 {
297  ExprContext *econtext;
298 
299  /* Create the ExprContext node within the caller's memory context */
300  econtext = makeNode(ExprContext);
301 
302  /* Initialize fields of ExprContext */
303  econtext->ecxt_scantuple = NULL;
304  econtext->ecxt_innertuple = NULL;
305  econtext->ecxt_outertuple = NULL;
306 
308 
309  /*
310  * Create working memory for expression evaluation in this context.
311  */
312  econtext->ecxt_per_tuple_memory =
314  "ExprContext",
316 
317  econtext->ecxt_param_exec_vals = NULL;
318  econtext->ecxt_param_list_info = NULL;
319 
320  econtext->ecxt_aggvalues = NULL;
321  econtext->ecxt_aggnulls = NULL;
322 
323  econtext->caseValue_datum = (Datum) 0;
324  econtext->caseValue_isNull = true;
325 
326  econtext->domainValue_datum = (Datum) 0;
327  econtext->domainValue_isNull = true;
328 
329  econtext->ecxt_estate = NULL;
330 
331  econtext->ecxt_callbacks = NULL;
332 
333  return econtext;
334 }
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:557
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
void ExecAssignProjectionInfo ( PlanState planstate,
TupleDesc  inputDesc 
)

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

494 {
495  planstate->ps_ProjInfo =
497  planstate->ps_ExprContext,
498  planstate->ps_ResultTupleSlot,
499  planstate,
500  inputDesc);
501 }
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:882
ExprContext * ps_ExprContext
Definition: execnodes.h:881
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:880
Plan * plan
Definition: execnodes.h:847
List * targetlist
Definition: plannodes.h:144
ProjectionInfo * ExecBuildProjectionInfo(List *targetList, ExprContext *econtext, TupleTableSlot *slot, PlanState *parent, TupleDesc inputDesc)
Definition: execExpr.c:301
void ExecAssignResultType ( PlanState planstate,
TupleDesc  tupDesc 
)

Definition at line 433 of file execUtils.c.

References ExecSetSlotDescriptor(), and PlanState::ps_ResultTupleSlot.

Referenced by ExecAssignResultTypeFromTL(), and ExecInitModifyTable().

434 {
435  TupleTableSlot *slot = planstate->ps_ResultTupleSlot;
436 
437  ExecSetSlotDescriptor(slot, tupDesc);
438 }
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:880
void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc)
Definition: execTuples.c:247
void ExecAssignResultTypeFromTL ( PlanState planstate)

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

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

Definition at line 557 of file execUtils.c.

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

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

558 {
560  TupleDesc tupDesc;
561 
562  outerPlan = outerPlanState(scanstate);
563  tupDesc = ExecGetResultType(outerPlan);
564 
565  ExecAssignScanType(scanstate, tupDesc);
566 }
#define outerPlanState(node)
Definition: execnodes.h:893
#define outerPlan(node)
Definition: plannodes.h:174
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:474
void ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc)
Definition: execUtils.c:545
int ExecCleanTargetListLength ( List targetlist)

Definition at line 1014 of file execUtils.c.

References lfirst_node, and TargetEntry::resjunk.

Referenced by check_sql_fn_retval(), and ExecTypeFromTLInternal().

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

Definition at line 666 of file execUtils.c.

References heap_close, and NoLock.

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

667 {
668  heap_close(scanrel, NoLock);
669 }
#define heap_close(r, l)
Definition: heapam.h:97
#define NoLock
Definition: lockdefs.h:34
void ExecLockNonLeafAppendTables ( List partitioned_rels,
EState estate 
)

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

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

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

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

Definition at line 582 of file execUtils.c.

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

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

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

Definition at line 1004 of file execUtils.c.

References list_length().

Referenced by ExecTypeFromTLInternal().

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

Definition at line 710 of file execUtils.c.

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

Referenced by ExecInitFunc(), and init_sexpr().

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

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

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

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

355 {
356  EState *estate;
357 
358  /* Call any registered callbacks */
359  ShutdownExprContext(econtext, isCommit);
360  /* And clean up the memory used */
362  /* Unlink self from owning EState, if any */
363  estate = econtext->ecxt_estate;
364  if (estate)
366  econtext);
367  /* And delete the ExprContext node */
368  pfree(econtext);
369 }
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:794
List * es_exprcontexts
Definition: execnodes.h:484
Datum GetAttributeByName ( HeapTupleHeader  tuple,
const char *  attname,
bool isNull 
)

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

891 {
892  AttrNumber attrno;
893  Datum result;
894  Oid tupType;
895  int32 tupTypmod;
896  TupleDesc tupDesc;
897  HeapTupleData tmptup;
898  int i;
899 
900  if (attname == NULL)
901  elog(ERROR, "invalid attribute name");
902 
903  if (isNull == NULL)
904  elog(ERROR, "a NULL isNull pointer was passed");
905 
906  if (tuple == NULL)
907  {
908  /* Kinda bogus but compatible with old behavior... */
909  *isNull = true;
910  return (Datum) 0;
911  }
912 
913  tupType = HeapTupleHeaderGetTypeId(tuple);
914  tupTypmod = HeapTupleHeaderGetTypMod(tuple);
915  tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
916 
917  attrno = InvalidAttrNumber;
918  for (i = 0; i < tupDesc->natts; i++)
919  {
920  Form_pg_attribute att = TupleDescAttr(tupDesc, i);
921 
922  if (namestrcmp(&(att->attname), attname) == 0)
923  {
924  attrno = att->attnum;
925  break;
926  }
927  }
928 
929  if (attrno == InvalidAttrNumber)
930  elog(ERROR, "attribute \"%s\" does not exist", attname);
931 
932  /*
933  * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
934  * the fields in the struct just in case user tries to inspect system
935  * columns.
936  */
937  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
938  ItemPointerSetInvalid(&(tmptup.t_self));
939  tmptup.t_tableOid = InvalidOid;
940  tmptup.t_data = tuple;
941 
942  result = heap_getattr(&tmptup,
943  attrno,
944  tupDesc,
945  isNull);
946 
947  ReleaseTupleDesc(tupDesc);
948 
949  return result;
950 }
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition: typcache.c:1486
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:84
int namestrcmp(Name name, const char *str)
Definition: name.c:247
unsigned int Oid
Definition: postgres_ext.h:31
int natts
Definition: tupdesc.h:73
signed int int32
Definition: c.h:246
HeapTupleHeader t_data
Definition: htup.h:67
#define HeapTupleHeaderGetTypMod(tup)
Definition: htup_details.h:455
#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:769
uintptr_t Datum
Definition: postgres.h:372
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:445
#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:115
int16 AttrNumber
Definition: attnum.h:21
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:439
Datum GetAttributeByNum ( HeapTupleHeader  tuple,
AttrNumber  attrno,
bool isNull 
)

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

956 {
957  Datum result;
958  Oid tupType;
959  int32 tupTypmod;
960  TupleDesc tupDesc;
961  HeapTupleData tmptup;
962 
963  if (!AttributeNumberIsValid(attrno))
964  elog(ERROR, "invalid attribute number %d", attrno);
965 
966  if (isNull == NULL)
967  elog(ERROR, "a NULL isNull pointer was passed");
968 
969  if (tuple == NULL)
970  {
971  /* Kinda bogus but compatible with old behavior... */
972  *isNull = true;
973  return (Datum) 0;
974  }
975 
976  tupType = HeapTupleHeaderGetTypeId(tuple);
977  tupTypmod = HeapTupleHeaderGetTypMod(tuple);
978  tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
979 
980  /*
981  * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
982  * the fields in the struct just in case user tries to inspect system
983  * columns.
984  */
985  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
986  ItemPointerSetInvalid(&(tmptup.t_self));
987  tmptup.t_tableOid = InvalidOid;
988  tmptup.t_data = tuple;
989 
990  result = heap_getattr(&tmptup,
991  attrno,
992  tupDesc,
993  isNull);
994 
995  ReleaseTupleDesc(tupDesc);
996 
997  return result;
998 }
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition: typcache.c:1486
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:246
HeapTupleHeader t_data
Definition: htup.h:67
#define HeapTupleHeaderGetTypMod(tup)
Definition: htup_details.h:455
#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:769
#define AttributeNumberIsValid(attributeNumber)
Definition: attnum.h:34
uintptr_t Datum
Definition: postgres.h:372
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:445
#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:115
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:439
ExprContext* MakePerTupleExprContext ( EState estate)

Definition at line 396 of file execUtils.c.

References CreateExprContext(), and EState::es_per_tuple_exprcontext.

397 {
398  if (estate->es_per_tuple_exprcontext == NULL)
400 
401  return estate->es_per_tuple_exprcontext;
402 }
ExprContext * es_per_tuple_exprcontext
Definition: execnodes.h:495
ExprContext * CreateExprContext(EState *estate)
Definition: execUtils.c:223
void RegisterExprContextCallback ( ExprContext econtext,
ExprContextCallbackFunction  function,
Datum  arg 
)

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

740 {
741  ExprContext_CB *ecxt_callback;
742 
743  /* Save the info in appropriate memory context */
744  ecxt_callback = (ExprContext_CB *)
746  sizeof(ExprContext_CB));
747 
748  ecxt_callback->function = function;
749  ecxt_callback->arg = arg;
750 
751  /* link to front of list for appropriate execution order */
752  ecxt_callback->next = econtext->ecxt_callbacks;
753  econtext->ecxt_callbacks = ecxt_callback;
754 }
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
void ReScanExprContext ( ExprContext econtext)

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

382 {
383  /* Call any registered callbacks */
384  ShutdownExprContext(econtext, true);
385  /* And clean up the memory used */
387 }
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:794
static void ShutdownExprContext ( ExprContext econtext,
bool  isCommit 
)
static

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

795 {
796  ExprContext_CB *ecxt_callback;
797  MemoryContext oldcontext;
798 
799  /* Fast path in normal case where there's nothing to do. */
800  if (econtext->ecxt_callbacks == NULL)
801  return;
802 
803  /*
804  * Call the callbacks in econtext's per-tuple context. This ensures that
805  * any memory they might leak will get cleaned up.
806  */
807  oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
808 
809  /*
810  * Call each callback function in reverse registration order.
811  */
812  while ((ecxt_callback = econtext->ecxt_callbacks) != NULL)
813  {
814  econtext->ecxt_callbacks = ecxt_callback->next;
815  if (isCommit)
816  ecxt_callback->function(ecxt_callback->arg);
817  pfree(ecxt_callback);
818  }
819 
820  MemoryContextSwitchTo(oldcontext);
821 }
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
void UnregisterExprContextCallback ( ExprContext econtext,
ExprContextCallbackFunction  function,
Datum  arg 
)

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

766 {
767  ExprContext_CB **prev_callback;
768  ExprContext_CB *ecxt_callback;
769 
770  prev_callback = &econtext->ecxt_callbacks;
771 
772  while ((ecxt_callback = *prev_callback) != NULL)
773  {
774  if (ecxt_callback->function == function && ecxt_callback->arg == arg)
775  {
776  *prev_callback = ecxt_callback->next;
777  pfree(ecxt_callback);
778  }
779  else
780  prev_callback = &ecxt_callback->next;
781  }
782 }
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
void UpdateChangedParamSet ( PlanState node,
Bitmapset newchg 
)

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

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