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_num_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_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(), NIL, and NULL.

Referenced by afterTriggerInvokeEvents(), ATRewriteTable(), 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_trig_target_relations = NIL;
119  estate->es_trig_tuple_slot = NULL;
120  estate->es_trig_oldtup_slot = NULL;
121  estate->es_trig_newtup_slot = NULL;
122 
123  estate->es_param_list_info = NULL;
124  estate->es_param_exec_vals = NULL;
125 
126  estate->es_queryEnv = NULL;
127 
128  estate->es_query_cxt = qcontext;
129 
130  estate->es_tupleTable = NIL;
131 
132  estate->es_rowMarks = NIL;
133 
134  estate->es_processed = 0;
135  estate->es_lastoid = InvalidOid;
136 
137  estate->es_top_eflags = 0;
138  estate->es_instrument = 0;
139  estate->es_finished = false;
140 
141  estate->es_exprcontexts = NIL;
142 
143  estate->es_subplanstates = NIL;
144 
145  estate->es_auxmodifytables = NIL;
146 
147  estate->es_per_tuple_exprcontext = NULL;
148 
149  estate->es_epqTuple = NULL;
150  estate->es_epqTupleSet = NULL;
151  estate->es_epqScanDone = NULL;
152  estate->es_sourceText = NULL;
153 
154  /*
155  * Return the executor state structure
156  */
157  MemoryContextSwitchTo(oldcontext);
158 
159  return estate;
160 }
#define NIL
Definition: pg_list.h:69
uint32 CommandId
Definition: c.h:411
HeapTuple * es_epqTuple
Definition: execnodes.h:483
JunkFilter * es_junkFilter
Definition: execnodes.h:415
CommandId es_output_cid
Definition: execnodes.h:418
TupleTableSlot * es_trig_newtup_slot
Definition: execnodes.h:439
Oid es_lastoid
Definition: execnodes.h:455
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
PlannedStmt * es_plannedstmt
Definition: execnodes.h:412
Snapshot es_crosscheck_snapshot
Definition: execnodes.h:410
ExprContext * es_per_tuple_exprcontext
Definition: execnodes.h:472
Snapshot es_snapshot
Definition: execnodes.h:409
List * es_range_table
Definition: execnodes.h:411
ScanDirection es_direction
Definition: execnodes.h:408
const char * es_sourceText
Definition: execnodes.h:413
ParamExecData * es_param_exec_vals
Definition: execnodes.h:443
MemoryContext es_query_cxt
Definition: execnodes.h:448
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:165
ResultRelInfo * es_result_relations
Definition: execnodes.h:421
TupleTableSlot * es_trig_oldtup_slot
Definition: execnodes.h:438
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
int es_instrument
Definition: execnodes.h:458
TupleTableSlot * es_trig_tuple_slot
Definition: execnodes.h:437
QueryEnvironment * es_queryEnv
Definition: execnodes.h:445
#define InvalidSnapshot
Definition: snapshot.h:25
List * es_trig_target_relations
Definition: execnodes.h:436
List * es_tupleTable
Definition: execnodes.h:450
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:322
List * es_auxmodifytables
Definition: execnodes.h:465
int es_num_result_relations
Definition: execnodes.h:422
#define InvalidOid
Definition: postgres_ext.h:36
bool es_finished
Definition: execnodes.h:459
#define makeNode(_type_)
Definition: nodes.h:557
#define NULL
Definition: c.h:229
uint64 es_processed
Definition: execnodes.h:454
bool * es_epqTupleSet
Definition: execnodes.h:484
List * es_subplanstates
Definition: execnodes.h:463
List * es_rowMarks
Definition: execnodes.h:452
int es_top_eflags
Definition: execnodes.h:457
bool * es_epqScanDone
Definition: execnodes.h:485
ParamListInfo es_param_list_info
Definition: execnodes.h:442
List * es_exprcontexts
Definition: execnodes.h:461
ResultRelInfo * es_result_relation_info
Definition: execnodes.h:423
ExprContext* CreateExprContext ( EState estate)

Definition at line 218 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, MemoryContextSwitchTo(), and NULL.

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

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

Definition at line 290 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, makeNode, and NULL.

Referenced by domain_check_input().

291 {
292  ExprContext *econtext;
293 
294  /* Create the ExprContext node within the caller's memory context */
295  econtext = makeNode(ExprContext);
296 
297  /* Initialize fields of ExprContext */
298  econtext->ecxt_scantuple = NULL;
299  econtext->ecxt_innertuple = NULL;
300  econtext->ecxt_outertuple = NULL;
301 
303 
304  /*
305  * Create working memory for expression evaluation in this context.
306  */
307  econtext->ecxt_per_tuple_memory =
309  "ExprContext",
311 
312  econtext->ecxt_param_exec_vals = NULL;
313  econtext->ecxt_param_list_info = NULL;
314 
315  econtext->ecxt_aggvalues = NULL;
316  econtext->ecxt_aggnulls = NULL;
317 
318  econtext->caseValue_datum = (Datum) 0;
319  econtext->caseValue_isNull = true;
320 
321  econtext->domainValue_datum = (Datum) 0;
322  econtext->domainValue_isNull = true;
323 
324  econtext->ecxt_estate = NULL;
325 
326  econtext->ecxt_callbacks = NULL;
327 
328  return econtext;
329 }
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
#define NULL
Definition: c.h:229
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 487 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().

489 {
490  planstate->ps_ProjInfo =
492  planstate->ps_ExprContext,
493  planstate->ps_ResultTupleSlot,
494  planstate,
495  inputDesc);
496 }
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:844
ExprContext * ps_ExprContext
Definition: execnodes.h:843
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:842
Plan * plan
Definition: execnodes.h:813
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 428 of file execUtils.c.

References ExecSetSlotDescriptor(), and PlanState::ps_ResultTupleSlot.

Referenced by ExecAssignResultTypeFromTL(), and ExecInitModifyTable().

429 {
430  TupleTableSlot *slot = planstate->ps_ResultTupleSlot;
431 
432  ExecSetSlotDescriptor(slot, tupDesc);
433 }
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:842
void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc)
Definition: execTuples.c:247
void ExecAssignResultTypeFromTL ( PlanState planstate)

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

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

Definition at line 552 of file execUtils.c.

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

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

553 {
555  TupleDesc tupDesc;
556 
557  outerPlan = outerPlanState(scanstate);
558  tupDesc = ExecGetResultType(outerPlan);
559 
560  ExecAssignScanType(scanstate, tupDesc);
561 }
#define outerPlanState(node)
Definition: execnodes.h:855
#define outerPlan(node)
Definition: plannodes.h:174
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:469
void ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc)
Definition: execUtils.c:540
int ExecCleanTargetListLength ( List targetlist)

Definition at line 1007 of file execUtils.c.

References lfirst_node, and TargetEntry::resjunk.

Referenced by check_sql_fn_retval(), and ExecTypeFromTLInternal().

1008 {
1009  int len = 0;
1010  ListCell *tl;
1011 
1012  foreach(tl, targetlist)
1013  {
1014  TargetEntry *curTle = lfirst_node(TargetEntry, tl);
1015 
1016  if (!curTle->resjunk)
1017  len++;
1018  }
1019  return len;
1020 }
bool resjunk
Definition: primnodes.h:1374
#define lfirst_node(type, lc)
Definition: pg_list.h:109
void ExecCloseScanRelation ( Relation  scanrel)

Definition at line 661 of file execUtils.c.

References heap_close, and NoLock.

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

662 {
663  heap_close(scanrel, NoLock);
664 }
#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 826 of file execUtils.c.

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

Referenced by ExecInitAppend(), and ExecInitMergeAppend().

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

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

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

Definition at line 577 of file execUtils.c.

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

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

578 {
579  ResultRelInfo *resultRelInfos;
580  int i;
581 
582  resultRelInfos = estate->es_result_relations;
583  for (i = 0; i < estate->es_num_result_relations; i++)
584  {
585  if (resultRelInfos[i].ri_RangeTableIndex == scanrelid)
586  return true;
587  }
588  return false;
589 }
ResultRelInfo * es_result_relations
Definition: execnodes.h:421
int es_num_result_relations
Definition: execnodes.h:422
int i
int ExecTargetListLength ( List targetlist)

Definition at line 997 of file execUtils.c.

References list_length().

Referenced by ExecTypeFromTLInternal().

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

Definition at line 705 of file execUtils.c.

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

Referenced by ExecInitFunc(), and init_sexpr().

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

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

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

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

350 {
351  EState *estate;
352 
353  /* Call any registered callbacks */
354  ShutdownExprContext(econtext, isCommit);
355  /* And clean up the memory used */
357  /* Unlink self from owning EState, if any */
358  estate = econtext->ecxt_estate;
359  if (estate)
361  econtext);
362  /* And delete the ExprContext node */
363  pfree(econtext);
364 }
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:950
struct EState * ecxt_estate
Definition: execnodes.h:225
static void ShutdownExprContext(ExprContext *econtext, bool isCommit)
Definition: execUtils.c:789
List * es_exprcontexts
Definition: execnodes.h:461
Datum GetAttributeByName ( HeapTupleHeader  tuple,
const char *  attname,
bool isNull 
)

Definition at line 885 of file execUtils.c.

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

Referenced by c_overpaid(), and overpaid().

886 {
887  AttrNumber attrno;
888  Datum result;
889  Oid tupType;
890  int32 tupTypmod;
891  TupleDesc tupDesc;
892  HeapTupleData tmptup;
893  int i;
894 
895  if (attname == NULL)
896  elog(ERROR, "invalid attribute name");
897 
898  if (isNull == NULL)
899  elog(ERROR, "a NULL isNull pointer was passed");
900 
901  if (tuple == NULL)
902  {
903  /* Kinda bogus but compatible with old behavior... */
904  *isNull = true;
905  return (Datum) 0;
906  }
907 
908  tupType = HeapTupleHeaderGetTypeId(tuple);
909  tupTypmod = HeapTupleHeaderGetTypMod(tuple);
910  tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
911 
912  attrno = InvalidAttrNumber;
913  for (i = 0; i < tupDesc->natts; i++)
914  {
915  if (namestrcmp(&(tupDesc->attrs[i]->attname), attname) == 0)
916  {
917  attrno = tupDesc->attrs[i]->attnum;
918  break;
919  }
920  }
921 
922  if (attrno == InvalidAttrNumber)
923  elog(ERROR, "attribute \"%s\" does not exist", attname);
924 
925  /*
926  * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
927  * the fields in the struct just in case user tries to inspect system
928  * columns.
929  */
930  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
931  ItemPointerSetInvalid(&(tmptup.t_self));
932  tmptup.t_tableOid = InvalidOid;
933  tmptup.t_data = tuple;
934 
935  result = heap_getattr(&tmptup,
936  attrno,
937  tupDesc,
938  isNull);
939 
940  ReleaseTupleDesc(tupDesc);
941 
942  return result;
943 }
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition: typcache.c:1257
Form_pg_attribute * attrs
Definition: tupdesc.h:74
int namestrcmp(Name name, const char *str)
Definition: name.c:248
return result
Definition: formatting.c:1632
unsigned int Oid
Definition: postgres_ext.h:31
int natts
Definition: tupdesc.h:73
signed int int32
Definition: c.h:256
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
uintptr_t Datum
Definition: postgres.h:372
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:445
#define InvalidOid
Definition: postgres_ext.h:36
#define NULL
Definition: c.h:229
#define InvalidAttrNumber
Definition: attnum.h:23
#define ItemPointerSetInvalid(pointer)
Definition: itemptr.h:149
int i
#define elog
Definition: elog.h:219
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:107
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 946 of file execUtils.c.

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

949 {
950  Datum result;
951  Oid tupType;
952  int32 tupTypmod;
953  TupleDesc tupDesc;
954  HeapTupleData tmptup;
955 
956  if (!AttributeNumberIsValid(attrno))
957  elog(ERROR, "invalid attribute number %d", attrno);
958 
959  if (isNull == NULL)
960  elog(ERROR, "a NULL isNull pointer was passed");
961 
962  if (tuple == NULL)
963  {
964  /* Kinda bogus but compatible with old behavior... */
965  *isNull = true;
966  return (Datum) 0;
967  }
968 
969  tupType = HeapTupleHeaderGetTypeId(tuple);
970  tupTypmod = HeapTupleHeaderGetTypMod(tuple);
971  tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
972 
973  /*
974  * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
975  * the fields in the struct just in case user tries to inspect system
976  * columns.
977  */
978  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
979  ItemPointerSetInvalid(&(tmptup.t_self));
980  tmptup.t_tableOid = InvalidOid;
981  tmptup.t_data = tuple;
982 
983  result = heap_getattr(&tmptup,
984  attrno,
985  tupDesc,
986  isNull);
987 
988  ReleaseTupleDesc(tupDesc);
989 
990  return result;
991 }
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition: typcache.c:1257
return result
Definition: formatting.c:1632
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:256
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 NULL
Definition: c.h:229
#define ItemPointerSetInvalid(pointer)
Definition: itemptr.h:149
#define elog
Definition: elog.h:219
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:107
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:439
ExprContext* MakePerTupleExprContext ( EState estate)

Definition at line 391 of file execUtils.c.

References CreateExprContext(), EState::es_per_tuple_exprcontext, and NULL.

392 {
393  if (estate->es_per_tuple_exprcontext == NULL)
395 
396  return estate->es_per_tuple_exprcontext;
397 }
ExprContext * es_per_tuple_exprcontext
Definition: execnodes.h:472
#define NULL
Definition: c.h:229
ExprContext * CreateExprContext(EState *estate)
Definition: execUtils.c:218
void RegisterExprContextCallback ( ExprContext econtext,
ExprContextCallbackFunction  function,
Datum  arg 
)

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

735 {
736  ExprContext_CB *ecxt_callback;
737 
738  /* Save the info in appropriate memory context */
739  ecxt_callback = (ExprContext_CB *)
741  sizeof(ExprContext_CB));
742 
743  ecxt_callback->function = function;
744  ecxt_callback->arg = arg;
745 
746  /* link to front of list for appropriate execution order */
747  ecxt_callback->next = econtext->ecxt_callbacks;
748  econtext->ecxt_callbacks = ecxt_callback;
749 }
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:707
void * arg
void ReScanExprContext ( ExprContext econtext)

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

377 {
378  /* Call any registered callbacks */
379  ShutdownExprContext(econtext, true);
380  /* And clean up the memory used */
382 }
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:789
static void ShutdownExprContext ( ExprContext econtext,
bool  isCommit 
)
static

Definition at line 789 of file execUtils.c.

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

Referenced by FreeExprContext(), and ReScanExprContext().

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

Definition at line 758 of file execUtils.c.

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

Referenced by end_MultiFuncCall(), and fmgr_sql().

761 {
762  ExprContext_CB **prev_callback;
763  ExprContext_CB *ecxt_callback;
764 
765  prev_callback = &econtext->ecxt_callbacks;
766 
767  while ((ecxt_callback = *prev_callback) != NULL)
768  {
769  if (ecxt_callback->function == function && ecxt_callback->arg == arg)
770  {
771  *prev_callback = ecxt_callback->next;
772  pfree(ecxt_callback);
773  }
774  else
775  prev_callback = &ecxt_callback->next;
776  }
777 }
void pfree(void *pointer)
Definition: mcxt.c:950
ExprContextCallbackFunction function
Definition: execnodes.h:165
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:228
struct ExprContext_CB * next
Definition: execnodes.h:164
#define NULL
Definition: c.h:229
void * arg
void UpdateChangedParamSet ( PlanState node,
Bitmapset newchg 
)

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

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