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

Go to the source code of this file.

Functions

static bool tlist_matches_tupdesc (PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc)
 
static void ShutdownExprContext (ExprContext *econtext, bool isCommit)
 
EStateCreateExecutorState (void)
 
void FreeExecutorState (EState *estate)
 
static ExprContextCreateExprContextInternal (EState *estate, Size minContextSize, Size initBlockSize, Size maxBlockSize)
 
ExprContextCreateExprContext (EState *estate)
 
ExprContextCreateWorkExprContext (EState *estate)
 
ExprContextCreateStandaloneExprContext (void)
 
void FreeExprContext (ExprContext *econtext, bool isCommit)
 
void ReScanExprContext (ExprContext *econtext)
 
ExprContextMakePerTupleExprContext (EState *estate)
 
void ExecAssignExprContext (EState *estate, PlanState *planstate)
 
TupleDesc ExecGetResultType (PlanState *planstate)
 
const TupleTableSlotOpsExecGetResultSlotOps (PlanState *planstate, bool *isfixed)
 
void ExecAssignProjectionInfo (PlanState *planstate, TupleDesc inputDesc)
 
void ExecConditionalAssignProjectionInfo (PlanState *planstate, TupleDesc inputDesc, Index varno)
 
void ExecFreeExprContext (PlanState *planstate)
 
void ExecAssignScanType (ScanState *scanstate, TupleDesc tupDesc)
 
void ExecCreateScanSlotFromOuterPlan (EState *estate, ScanState *scanstate, const TupleTableSlotOps *tts_ops)
 
bool ExecRelationIsTargetRelation (EState *estate, Index scanrelid)
 
Relation ExecOpenScanRelation (EState *estate, Index scanrelid, int eflags)
 
void ExecInitRangeTable (EState *estate, List *rangeTable)
 
Relation ExecGetRangeTableRelation (EState *estate, Index rti)
 
void ExecInitResultRelation (EState *estate, ResultRelInfo *resultRelInfo, Index rti)
 
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)
 
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)
 
TupleTableSlotExecGetTriggerOldSlot (EState *estate, ResultRelInfo *relInfo)
 
TupleTableSlotExecGetTriggerNewSlot (EState *estate, ResultRelInfo *relInfo)
 
TupleTableSlotExecGetReturningSlot (EState *estate, ResultRelInfo *relInfo)
 
TupleConversionMapExecGetChildToRootMap (ResultRelInfo *resultRelInfo)
 
BitmapsetExecGetInsertedCols (ResultRelInfo *relinfo, EState *estate)
 
BitmapsetExecGetUpdatedCols (ResultRelInfo *relinfo, EState *estate)
 
BitmapsetExecGetExtraUpdatedCols (ResultRelInfo *relinfo, EState *estate)
 
BitmapsetExecGetAllUpdatedCols (ResultRelInfo *relinfo, EState *estate)
 

Function Documentation

◆ CreateExecutorState()

EState* CreateExecutorState ( void  )

Definition at line 90 of file execUtils.c.

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, CurrentMemoryContext, EState::es_auxmodifytables, EState::es_crosscheck_snapshot, EState::es_direction, EState::es_exprcontexts, EState::es_finished, EState::es_instrument, EState::es_jit, EState::es_jit_flags, EState::es_junkFilter, EState::es_opened_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_range_table_size, EState::es_relations, EState::es_result_relations, EState::es_rowmarks, EState::es_snapshot, EState::es_sourceText, EState::es_subplanstates, EState::es_top_eflags, EState::es_trig_target_relations, EState::es_tuple_routing_result_relations, EState::es_tupleTable, EState::es_use_parallel_mode, ForwardScanDirection, InvalidSnapshot, makeNode, MemoryContextSwitchTo(), and NIL.

Referenced by afterTriggerInvokeEvents(), ATRewriteTable(), check_default_partition_contents(), compute_expr_stats(), compute_index_stats(), CopyFrom(), create_edata_for_relation(), EvalPlanQualStart(), evaluate_expr(), ExecuteCallStmt(), ExecuteQuery(), ExecuteTruncateGuts(), ExplainExecuteQuery(), get_qual_for_range(), heapam_index_build_range_scan(), heapam_index_validate_scan(), IndexCheckExclusion(), make_build_data(), operator_predicate_proof(), plpgsql_create_econtext(), plpgsql_inline_handler(), standard_ExecutorStart(), StoreAttrDefault(), tuplesort_begin_cluster(), unique_key_recheck(), and validateDomainConstraint().

91 {
92  EState *estate;
93  MemoryContext qcontext;
94  MemoryContext oldcontext;
95 
96  /*
97  * Create the per-query context for this Executor run.
98  */
100  "ExecutorState",
102 
103  /*
104  * Make the EState node within the per-query context. This way, we don't
105  * need a separate pfree() operation for it at shutdown.
106  */
107  oldcontext = MemoryContextSwitchTo(qcontext);
108 
109  estate = makeNode(EState);
110 
111  /*
112  * Initialize all fields of the Executor State structure
113  */
115  estate->es_snapshot = InvalidSnapshot; /* caller must initialize this */
116  estate->es_crosscheck_snapshot = InvalidSnapshot; /* no crosscheck */
117  estate->es_range_table = NIL;
118  estate->es_range_table_size = 0;
119  estate->es_relations = NULL;
120  estate->es_rowmarks = NULL;
121  estate->es_plannedstmt = NULL;
122 
123  estate->es_junkFilter = NULL;
124 
125  estate->es_output_cid = (CommandId) 0;
126 
127  estate->es_result_relations = NULL;
130  estate->es_trig_target_relations = NIL;
131 
132  estate->es_param_list_info = NULL;
133  estate->es_param_exec_vals = NULL;
134 
135  estate->es_queryEnv = NULL;
136 
137  estate->es_query_cxt = qcontext;
138 
139  estate->es_tupleTable = NIL;
140 
141  estate->es_processed = 0;
142 
143  estate->es_top_eflags = 0;
144  estate->es_instrument = 0;
145  estate->es_finished = false;
146 
147  estate->es_exprcontexts = NIL;
148 
149  estate->es_subplanstates = NIL;
150 
151  estate->es_auxmodifytables = NIL;
152 
153  estate->es_per_tuple_exprcontext = NULL;
154 
155  estate->es_sourceText = NULL;
156 
157  estate->es_use_parallel_mode = false;
158 
159  estate->es_jit_flags = 0;
160  estate->es_jit = NULL;
161 
162  /*
163  * Return the executor state structure
164  */
165  MemoryContextSwitchTo(oldcontext);
166 
167  return estate;
168 }
#define NIL
Definition: pg_list.h:65
uint32 CommandId
Definition: c.h:601
JunkFilter * es_junkFilter
Definition: execnodes.h:569
#define AllocSetContextCreate
Definition: memutils.h:173
CommandId es_output_cid
Definition: execnodes.h:572
struct JitContext * es_jit
Definition: execnodes.h:646
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
PlannedStmt * es_plannedstmt
Definition: execnodes.h:566
Snapshot es_crosscheck_snapshot
Definition: execnodes.h:559
ExprContext * es_per_tuple_exprcontext
Definition: execnodes.h:621
Snapshot es_snapshot
Definition: execnodes.h:558
List * es_range_table
Definition: execnodes.h:560
ScanDirection es_direction
Definition: execnodes.h:557
bool es_use_parallel_mode
Definition: execnodes.h:631
struct ExecRowMark ** es_rowmarks
Definition: execnodes.h:564
const char * es_sourceText
Definition: execnodes.h:567
ParamExecData * es_param_exec_vals
Definition: execnodes.h:595
MemoryContext es_query_cxt
Definition: execnodes.h:600
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:195
int es_jit_flags
Definition: execnodes.h:645
List * es_opened_result_relations
Definition: execnodes.h:578
MemoryContext CurrentMemoryContext
Definition: mcxt.c:42
int es_instrument
Definition: execnodes.h:607
ResultRelInfo ** es_result_relations
Definition: execnodes.h:575
QueryEnvironment * es_queryEnv
Definition: execnodes.h:597
#define InvalidSnapshot
Definition: snapshot.h:123
List * es_trig_target_relations
Definition: execnodes.h:591
List * es_tupleTable
Definition: execnodes.h:602
List * es_auxmodifytables
Definition: execnodes.h:614
List * es_tuple_routing_result_relations
Definition: execnodes.h:588
bool es_finished
Definition: execnodes.h:608
#define makeNode(_type_)
Definition: nodes.h:587
Relation * es_relations
Definition: execnodes.h:562
uint64 es_processed
Definition: execnodes.h:604
Index es_range_table_size
Definition: execnodes.h:561
List * es_subplanstates
Definition: execnodes.h:612
int es_top_eflags
Definition: execnodes.h:606
ParamListInfo es_param_list_info
Definition: execnodes.h:594
List * es_exprcontexts
Definition: execnodes.h:610

◆ CreateExprContext()

ExprContext* CreateExprContext ( EState estate)

Definition at line 301 of file execUtils.c.

References ALLOCSET_DEFAULT_SIZES, and CreateExprContextInternal().

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

302 {
304 }
static ExprContext * CreateExprContextInternal(EState *estate, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: execUtils.c:231
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:195

◆ CreateExprContextInternal()

static ExprContext* CreateExprContextInternal ( EState estate,
Size  minContextSize,
Size  initBlockSize,
Size  maxBlockSize 
)
static

Definition at line 231 of file execUtils.c.

References 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 CreateExprContext(), and CreateWorkExprContext().

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

◆ CreateStandaloneExprContext()

ExprContext* CreateStandaloneExprContext ( void  )

Definition at line 352 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 BuildTupleHashTableExt(), domain_check_input(), and hypothetical_dense_rank_final().

353 {
354  ExprContext *econtext;
355 
356  /* Create the ExprContext node within the caller's memory context */
357  econtext = makeNode(ExprContext);
358 
359  /* Initialize fields of ExprContext */
360  econtext->ecxt_scantuple = NULL;
361  econtext->ecxt_innertuple = NULL;
362  econtext->ecxt_outertuple = NULL;
363 
365 
366  /*
367  * Create working memory for expression evaluation in this context.
368  */
369  econtext->ecxt_per_tuple_memory =
371  "ExprContext",
373 
374  econtext->ecxt_param_exec_vals = NULL;
375  econtext->ecxt_param_list_info = NULL;
376 
377  econtext->ecxt_aggvalues = NULL;
378  econtext->ecxt_aggnulls = NULL;
379 
380  econtext->caseValue_datum = (Datum) 0;
381  econtext->caseValue_isNull = true;
382 
383  econtext->domainValue_datum = (Datum) 0;
384  econtext->domainValue_isNull = true;
385 
386  econtext->ecxt_estate = NULL;
387 
388  econtext->ecxt_callbacks = NULL;
389 
390  return econtext;
391 }
#define AllocSetContextCreate
Definition: memutils.h:173
Datum * ecxt_aggvalues
Definition: execnodes.h:245
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:234
Datum domainValue_datum
Definition: execnodes.h:257
Datum caseValue_datum
Definition: execnodes.h:251
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:265
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:195
TupleTableSlot * ecxt_innertuple
Definition: execnodes.h:228
ParamExecData * ecxt_param_exec_vals
Definition: execnodes.h:237
struct EState * ecxt_estate
Definition: execnodes.h:262
MemoryContext CurrentMemoryContext
Definition: mcxt.c:42
bool domainValue_isNull
Definition: execnodes.h:259
bool * ecxt_aggnulls
Definition: execnodes.h:247
uintptr_t Datum
Definition: postgres.h:411
#define makeNode(_type_)
Definition: nodes.h:587
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:230
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:226
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:233
bool caseValue_isNull
Definition: execnodes.h:253
ParamListInfo ecxt_param_list_info
Definition: execnodes.h:238

◆ CreateWorkExprContext()

ExprContext* CreateWorkExprContext ( EState estate)

Definition at line 316 of file execUtils.c.

References ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE, ALLOCSET_DEFAULT_MINSIZE, CreateExprContextInternal(), and work_mem.

Referenced by ExecInitAgg().

317 {
318  Size minContextSize = ALLOCSET_DEFAULT_MINSIZE;
319  Size initBlockSize = ALLOCSET_DEFAULT_INITSIZE;
320  Size maxBlockSize = ALLOCSET_DEFAULT_MAXSIZE;
321 
322  /* choose the maxBlockSize to be no larger than 1/16 of work_mem */
323  while (16 * maxBlockSize > work_mem * 1024L)
324  maxBlockSize >>= 1;
325 
326  if (maxBlockSize < ALLOCSET_DEFAULT_INITSIZE)
327  maxBlockSize = ALLOCSET_DEFAULT_INITSIZE;
328 
329  return CreateExprContextInternal(estate, minContextSize,
330  initBlockSize, maxBlockSize);
331 }
static ExprContext * CreateExprContextInternal(EState *estate, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: execUtils.c:231
#define ALLOCSET_DEFAULT_MINSIZE
Definition: memutils.h:192
int work_mem
Definition: globals.c:124
size_t Size
Definition: c.h:540
#define ALLOCSET_DEFAULT_INITSIZE
Definition: memutils.h:193
#define ALLOCSET_DEFAULT_MAXSIZE
Definition: memutils.h:194

◆ ExecAssignExprContext()

◆ ExecAssignProjectionInfo()

void ExecAssignProjectionInfo ( PlanState planstate,
TupleDesc  inputDesc 
)

Definition at line 535 of file execUtils.c.

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

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

537 {
538  planstate->ps_ProjInfo =
540  planstate->ps_ExprContext,
541  planstate->ps_ResultTupleSlot,
542  planstate,
543  inputDesc);
544 }
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:1006
ExprContext * ps_ExprContext
Definition: execnodes.h:1005
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:1004
Plan * plan
Definition: execnodes.h:966
List * targetlist
Definition: plannodes.h:141
ProjectionInfo * ExecBuildProjectionInfo(List *targetList, ExprContext *econtext, TupleTableSlot *slot, PlanState *parent, TupleDesc inputDesc)
Definition: execExpr.c:353

◆ ExecAssignScanType()

void ExecAssignScanType ( ScanState scanstate,
TupleDesc  tupDesc 
)

Definition at line 670 of file execUtils.c.

References ExecSetSlotDescriptor(), and ScanState::ss_ScanTupleSlot.

Referenced by ExecWorkTableScan().

671 {
672  TupleTableSlot *slot = scanstate->ss_ScanTupleSlot;
673 
674  ExecSetSlotDescriptor(slot, tupDesc);
675 }
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1380
void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc)
Definition: execTuples.c:1289

◆ ExecCleanTargetListLength()

int ExecCleanTargetListLength ( List targetlist)

Definition at line 1147 of file execUtils.c.

References lfirst_node, and TargetEntry::resjunk.

Referenced by check_sql_fn_retval(), exec_rt_fetch(), and ExecTypeFromTLInternal().

1148 {
1149  int len = 0;
1150  ListCell *tl;
1151 
1152  foreach(tl, targetlist)
1153  {
1154  TargetEntry *curTle = lfirst_node(TargetEntry, tl);
1155 
1156  if (!curTle->resjunk)
1157  len++;
1158  }
1159  return len;
1160 }
bool resjunk
Definition: primnodes.h:1461
#define lfirst_node(type, lc)
Definition: pg_list.h:172

◆ ExecConditionalAssignProjectionInfo()

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

Definition at line 555 of file execUtils.c.

References ExecAssignProjectionInfo(), ExecInitResultSlot(), PlanState::plan, PlanState::ps_ProjInfo, PlanState::ps_ResultTupleSlot, PlanState::resultops, PlanState::resultopsfixed, PlanState::resultopsset, PlanState::scanops, PlanState::scanopsfixed, PlanState::scanopsset, Plan::targetlist, tlist_matches_tupdesc(), and TTSOpsVirtual.

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

557 {
558  if (tlist_matches_tupdesc(planstate,
559  planstate->plan->targetlist,
560  varno,
561  inputDesc))
562  {
563  planstate->ps_ProjInfo = NULL;
564  planstate->resultopsset = planstate->scanopsset;
565  planstate->resultopsfixed = planstate->scanopsfixed;
566  planstate->resultops = planstate->scanops;
567  }
568  else
569  {
570  if (!planstate->ps_ResultTupleSlot)
571  {
572  ExecInitResultSlot(planstate, &TTSOpsVirtual);
573  planstate->resultops = &TTSOpsVirtual;
574  planstate->resultopsfixed = true;
575  planstate->resultopsset = true;
576  }
577  ExecAssignProjectionInfo(planstate, inputDesc);
578  }
579 }
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:1006
const TupleTableSlotOps TTSOpsVirtual
Definition: execTuples.c:83
const TupleTableSlotOps * resultops
Definition: execnodes.h:1043
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:1004
const TupleTableSlotOps * scanops
Definition: execnodes.h:1040
void ExecAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc)
Definition: execUtils.c:535
bool resultopsset
Definition: execnodes.h:1051
Plan * plan
Definition: execnodes.h:966
bool scanopsfixed
Definition: execnodes.h:1044
void ExecInitResultSlot(PlanState *planstate, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1779
static bool tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc)
Definition: execUtils.c:582
bool scanopsset
Definition: execnodes.h:1048
List * targetlist
Definition: plannodes.h:141
bool resultopsfixed
Definition: execnodes.h:1047

◆ ExecCreateScanSlotFromOuterPlan()

void ExecCreateScanSlotFromOuterPlan ( EState estate,
ScanState scanstate,
const TupleTableSlotOps tts_ops 
)

Definition at line 682 of file execUtils.c.

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

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

685 {
687  TupleDesc tupDesc;
688 
689  outerPlan = outerPlanState(scanstate);
690  tupDesc = ExecGetResultType(outerPlan);
691 
692  ExecInitScanTupleSlot(estate, scanstate, tupDesc, tts_ops);
693 }
#define outerPlanState(node)
Definition: execnodes.h:1062
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1811
#define outerPlan(node)
Definition: plannodes.h:171
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:490

◆ ExecFreeExprContext()

◆ ExecGetAllUpdatedCols()

Bitmapset* ExecGetAllUpdatedCols ( ResultRelInfo relinfo,
EState estate 
)

Definition at line 1347 of file execUtils.c.

References bms_union(), ExecGetExtraUpdatedCols(), and ExecGetUpdatedCols().

Referenced by exec_rt_fetch(), ExecARUpdateTriggers(), ExecASUpdateTriggers(), ExecBRUpdateTriggers(), ExecBSUpdateTriggers(), and ExecUpdateLockMode().

1348 {
1349  return bms_union(ExecGetUpdatedCols(relinfo, estate),
1350  ExecGetExtraUpdatedCols(relinfo, estate));
1351 }
Bitmapset * ExecGetExtraUpdatedCols(ResultRelInfo *relinfo, EState *estate)
Definition: execUtils.c:1321
Bitmapset * ExecGetUpdatedCols(ResultRelInfo *relinfo, EState *estate)
Definition: execUtils.c:1295
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:225

◆ ExecGetChildToRootMap()

TupleConversionMap* ExecGetChildToRootMap ( ResultRelInfo resultRelInfo)

Definition at line 1234 of file execUtils.c.

References convert_tuples_by_name(), RelationGetDescr, ResultRelInfo::ri_ChildToRootMap, ResultRelInfo::ri_ChildToRootMapValid, ResultRelInfo::ri_RelationDesc, and ResultRelInfo::ri_RootResultRelInfo.

Referenced by adjust_partition_colnos(), AfterTriggerSaveEvent(), exec_rt_fetch(), and ExecCrossPartitionUpdate().

1235 {
1236  /* If we didn't already do so, compute the map for this child. */
1237  if (!resultRelInfo->ri_ChildToRootMapValid)
1238  {
1239  ResultRelInfo *rootRelInfo = resultRelInfo->ri_RootResultRelInfo;
1240 
1241  if (rootRelInfo)
1242  resultRelInfo->ri_ChildToRootMap =
1244  RelationGetDescr(rootRelInfo->ri_RelationDesc));
1245  else /* this isn't a child result rel */
1246  resultRelInfo->ri_ChildToRootMap = NULL;
1247 
1248  resultRelInfo->ri_ChildToRootMapValid = true;
1249  }
1250 
1251  return resultRelInfo->ri_ChildToRootMap;
1252 }
Relation ri_RelationDesc
Definition: execnodes.h:411
#define RelationGetDescr(relation)
Definition: rel.h:503
TupleConversionMap * ri_ChildToRootMap
Definition: execnodes.h:522
bool ri_ChildToRootMapValid
Definition: execnodes.h:523
struct ResultRelInfo * ri_RootResultRelInfo
Definition: execnodes.h:512
TupleConversionMap * convert_tuples_by_name(TupleDesc indesc, TupleDesc outdesc)
Definition: tupconvert.c:102

◆ ExecGetExtraUpdatedCols()

Bitmapset* ExecGetExtraUpdatedCols ( ResultRelInfo relinfo,
EState estate 
)

Definition at line 1321 of file execUtils.c.

References TupleConversionMap::attrMap, exec_rt_fetch(), execute_attr_map_cols(), RangeTblEntry::extraUpdatedCols, ResultRelInfo::ri_RangeTableIndex, ResultRelInfo::ri_RootResultRelInfo, and ResultRelInfo::ri_RootToPartitionMap.

Referenced by exec_rt_fetch(), ExecComputeStoredGenerated(), ExecGetAllUpdatedCols(), and index_unchanged_by_update().

1322 {
1323  /* see ExecGetInsertedCols() */
1324  if (relinfo->ri_RangeTableIndex != 0)
1325  {
1326  RangeTblEntry *rte = exec_rt_fetch(relinfo->ri_RangeTableIndex, estate);
1327 
1328  return rte->extraUpdatedCols;
1329  }
1330  else if (relinfo->ri_RootResultRelInfo)
1331  {
1332  ResultRelInfo *rootRelInfo = relinfo->ri_RootResultRelInfo;
1333  RangeTblEntry *rte = exec_rt_fetch(rootRelInfo->ri_RangeTableIndex, estate);
1334 
1335  if (relinfo->ri_RootToPartitionMap != NULL)
1337  rte->extraUpdatedCols);
1338  else
1339  return rte->extraUpdatedCols;
1340  }
1341  else
1342  return NULL;
1343 }
Index ri_RangeTableIndex
Definition: execnodes.h:408
Bitmapset * extraUpdatedCols
Definition: parsenodes.h:1150
struct ResultRelInfo * ri_RootResultRelInfo
Definition: execnodes.h:512
static RangeTblEntry * exec_rt_fetch(Index rti, EState *estate)
Definition: executor.h:571
AttrMap * attrMap
Definition: tupconvert.h:28
TupleConversionMap * ri_RootToPartitionMap
Definition: execnodes.h:513
Bitmapset * execute_attr_map_cols(AttrMap *attrMap, Bitmapset *in_cols)
Definition: tupconvert.c:237

◆ ExecGetInsertedCols()

Bitmapset* ExecGetInsertedCols ( ResultRelInfo relinfo,
EState estate 
)

Definition at line 1256 of file execUtils.c.

References TupleConversionMap::attrMap, exec_rt_fetch(), execute_attr_map_cols(), RangeTblEntry::insertedCols, ResultRelInfo::ri_RangeTableIndex, ResultRelInfo::ri_RootResultRelInfo, and ResultRelInfo::ri_RootToPartitionMap.

Referenced by exec_rt_fetch(), ExecConstraints(), ExecPartitionCheckEmitError(), and ExecWithCheckOptions().

1257 {
1258  /*
1259  * The columns are stored in the range table entry. If this ResultRelInfo
1260  * represents a partition routing target, and doesn't have an entry of its
1261  * own in the range table, fetch the parent's RTE and map the columns to
1262  * the order they are in the partition.
1263  */
1264  if (relinfo->ri_RangeTableIndex != 0)
1265  {
1266  RangeTblEntry *rte = exec_rt_fetch(relinfo->ri_RangeTableIndex, estate);
1267 
1268  return rte->insertedCols;
1269  }
1270  else if (relinfo->ri_RootResultRelInfo)
1271  {
1272  ResultRelInfo *rootRelInfo = relinfo->ri_RootResultRelInfo;
1273  RangeTblEntry *rte = exec_rt_fetch(rootRelInfo->ri_RangeTableIndex, estate);
1274 
1275  if (relinfo->ri_RootToPartitionMap != NULL)
1277  rte->insertedCols);
1278  else
1279  return rte->insertedCols;
1280  }
1281  else
1282  {
1283  /*
1284  * The relation isn't in the range table and it isn't a partition
1285  * routing target. This ResultRelInfo must've been created only for
1286  * firing triggers and the relation is not being inserted into. (See
1287  * ExecGetTriggerResultRel.)
1288  */
1289  return NULL;
1290  }
1291 }
Index ri_RangeTableIndex
Definition: execnodes.h:408
struct ResultRelInfo * ri_RootResultRelInfo
Definition: execnodes.h:512
static RangeTblEntry * exec_rt_fetch(Index rti, EState *estate)
Definition: executor.h:571
AttrMap * attrMap
Definition: tupconvert.h:28
TupleConversionMap * ri_RootToPartitionMap
Definition: execnodes.h:513
Bitmapset * insertedCols
Definition: parsenodes.h:1148
Bitmapset * execute_attr_map_cols(AttrMap *attrMap, Bitmapset *in_cols)
Definition: tupconvert.c:237

◆ ExecGetRangeTableRelation()

Relation ExecGetRangeTableRelation ( EState estate,
Index  rti 
)

Definition at line 782 of file execUtils.c.

References AccessShareLock, Assert, CheckRelationLockedByMe(), EState::es_relations, exec_rt_fetch(), IsParallelWorker, NoLock, RangeTblEntry::relid, RangeTblEntry::rellockmode, RTE_RELATION, RangeTblEntry::rtekind, and table_open().

Referenced by exec_rt_fetch(), ExecCreatePartitionPruneState(), ExecInitResultRelation(), ExecOpenScanRelation(), and InitPlan().

783 {
784  Relation rel;
785 
786  Assert(rti > 0 && rti <= estate->es_range_table_size);
787 
788  rel = estate->es_relations[rti - 1];
789  if (rel == NULL)
790  {
791  /* First time through, so open the relation */
792  RangeTblEntry *rte = exec_rt_fetch(rti, estate);
793 
794  Assert(rte->rtekind == RTE_RELATION);
795 
796  if (!IsParallelWorker())
797  {
798  /*
799  * In a normal query, we should already have the appropriate lock,
800  * but verify that through an Assert. Since there's already an
801  * Assert inside table_open that insists on holding some lock, it
802  * seems sufficient to check this only when rellockmode is higher
803  * than the minimum.
804  */
805  rel = table_open(rte->relid, NoLock);
807  CheckRelationLockedByMe(rel, rte->rellockmode, false));
808  }
809  else
810  {
811  /*
812  * If we are a parallel worker, we need to obtain our own local
813  * lock on the relation. This ensures sane behavior in case the
814  * parent process exits before we do.
815  */
816  rel = table_open(rte->relid, rte->rellockmode);
817  }
818 
819  estate->es_relations[rti - 1] = rel;
820  }
821 
822  return rel;
823 }
#define AccessShareLock
Definition: lockdefs.h:36
#define NoLock
Definition: lockdefs.h:34
static RangeTblEntry * exec_rt_fetch(Index rti, EState *estate)
Definition: executor.h:571
#define IsParallelWorker()
Definition: parallel.h:61
#define Assert(condition)
Definition: c.h:804
Relation * es_relations
Definition: execnodes.h:562
bool CheckRelationLockedByMe(Relation relation, LOCKMODE lockmode, bool orstronger)
Definition: lmgr.c:303
RTEKind rtekind
Definition: parsenodes.h:995
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ ExecGetResultSlotOps()

const TupleTableSlotOps* ExecGetResultSlotOps ( PlanState planstate,
bool isfixed 
)

Definition at line 499 of file execUtils.c.

References PlanState::ps_ResultTupleSlot, PlanState::resultops, PlanState::resultopsfixed, PlanState::resultopsset, TTS_FIXED, TupleTableSlot::tts_ops, and TTSOpsVirtual.

Referenced by ExecComputeSlotInfo(), ExecInitAgg(), ExecInitGroup(), ExecInitHashJoin(), ExecInitLimit(), ExecInitLockRows(), ExecInitMergeJoin(), and ExecInitSubqueryScan().

500 {
501  if (planstate->resultopsset && planstate->resultops)
502  {
503  if (isfixed)
504  *isfixed = planstate->resultopsfixed;
505  return planstate->resultops;
506  }
507 
508  if (isfixed)
509  {
510  if (planstate->resultopsset)
511  *isfixed = planstate->resultopsfixed;
512  else if (planstate->ps_ResultTupleSlot)
513  *isfixed = TTS_FIXED(planstate->ps_ResultTupleSlot);
514  else
515  *isfixed = false;
516  }
517 
518  if (!planstate->ps_ResultTupleSlot)
519  return &TTSOpsVirtual;
520 
521  return planstate->ps_ResultTupleSlot->tts_ops;
522 }
#define TTS_FIXED(slot)
Definition: tuptable.h:109
const TupleTableSlotOps TTSOpsVirtual
Definition: execTuples.c:83
const TupleTableSlotOps *const tts_ops
Definition: tuptable.h:122
const TupleTableSlotOps * resultops
Definition: execnodes.h:1043
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:1004
bool resultopsset
Definition: execnodes.h:1051
bool resultopsfixed
Definition: execnodes.h:1047

◆ ExecGetResultType()

◆ ExecGetReturningSlot()

TupleTableSlot* ExecGetReturningSlot ( EState estate,
ResultRelInfo relInfo 
)

Definition at line 1210 of file execUtils.c.

References EState::es_query_cxt, ExecInitExtraTupleSlot(), MemoryContextSwitchTo(), RelationGetDescr, ResultRelInfo::ri_RelationDesc, ResultRelInfo::ri_ReturningSlot, and table_slot_callbacks().

Referenced by apply_returning_filter(), exec_rt_fetch(), ExecDelete(), and ExecInsert().

1211 {
1212  if (relInfo->ri_ReturningSlot == NULL)
1213  {
1214  Relation rel = relInfo->ri_RelationDesc;
1215  MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1216 
1217  relInfo->ri_ReturningSlot =
1218  ExecInitExtraTupleSlot(estate,
1219  RelationGetDescr(rel),
1220  table_slot_callbacks(rel));
1221 
1222  MemoryContextSwitchTo(oldcontext);
1223  }
1224 
1225  return relInfo->ri_ReturningSlot;
1226 }
Relation ri_RelationDesc
Definition: execnodes.h:411
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1831
#define RelationGetDescr(relation)
Definition: rel.h:503
const TupleTableSlotOps * table_slot_callbacks(Relation relation)
Definition: tableam.c:58
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext es_query_cxt
Definition: execnodes.h:600
TupleTableSlot * ri_ReturningSlot
Definition: execnodes.h:450

◆ ExecGetTriggerNewSlot()

TupleTableSlot* ExecGetTriggerNewSlot ( EState estate,
ResultRelInfo relInfo 
)

Definition at line 1188 of file execUtils.c.

References EState::es_query_cxt, ExecInitExtraTupleSlot(), MemoryContextSwitchTo(), RelationGetDescr, ResultRelInfo::ri_RelationDesc, ResultRelInfo::ri_TrigNewSlot, and table_slot_callbacks().

Referenced by AfterTriggerExecute(), and exec_rt_fetch().

1189 {
1190  if (relInfo->ri_TrigNewSlot == NULL)
1191  {
1192  Relation rel = relInfo->ri_RelationDesc;
1193  MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1194 
1195  relInfo->ri_TrigNewSlot =
1196  ExecInitExtraTupleSlot(estate,
1197  RelationGetDescr(rel),
1198  table_slot_callbacks(rel));
1199 
1200  MemoryContextSwitchTo(oldcontext);
1201  }
1202 
1203  return relInfo->ri_TrigNewSlot;
1204 }
Relation ri_RelationDesc
Definition: execnodes.h:411
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1831
#define RelationGetDescr(relation)
Definition: rel.h:503
const TupleTableSlotOps * table_slot_callbacks(Relation relation)
Definition: tableam.c:58
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
TupleTableSlot * ri_TrigNewSlot
Definition: execnodes.h:452
MemoryContext es_query_cxt
Definition: execnodes.h:600

◆ ExecGetTriggerOldSlot()

TupleTableSlot* ExecGetTriggerOldSlot ( EState estate,
ResultRelInfo relInfo 
)

Definition at line 1166 of file execUtils.c.

References EState::es_query_cxt, ExecInitExtraTupleSlot(), MemoryContextSwitchTo(), RelationGetDescr, ResultRelInfo::ri_RelationDesc, ResultRelInfo::ri_TrigOldSlot, and table_slot_callbacks().

Referenced by AfterTriggerExecute(), exec_rt_fetch(), ExecARDeleteTriggers(), ExecARUpdateTriggers(), ExecBRDeleteTriggers(), ExecBRUpdateTriggers(), ExecIRDeleteTriggers(), and ExecIRUpdateTriggers().

1167 {
1168  if (relInfo->ri_TrigOldSlot == NULL)
1169  {
1170  Relation rel = relInfo->ri_RelationDesc;
1171  MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1172 
1173  relInfo->ri_TrigOldSlot =
1174  ExecInitExtraTupleSlot(estate,
1175  RelationGetDescr(rel),
1176  table_slot_callbacks(rel));
1177 
1178  MemoryContextSwitchTo(oldcontext);
1179  }
1180 
1181  return relInfo->ri_TrigOldSlot;
1182 }
Relation ri_RelationDesc
Definition: execnodes.h:411
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1831
#define RelationGetDescr(relation)
Definition: rel.h:503
const TupleTableSlotOps * table_slot_callbacks(Relation relation)
Definition: tableam.c:58
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext es_query_cxt
Definition: execnodes.h:600
TupleTableSlot * ri_TrigOldSlot
Definition: execnodes.h:451

◆ ExecGetUpdatedCols()

Bitmapset* ExecGetUpdatedCols ( ResultRelInfo relinfo,
EState estate 
)

Definition at line 1295 of file execUtils.c.

References TupleConversionMap::attrMap, exec_rt_fetch(), execute_attr_map_cols(), ResultRelInfo::ri_RangeTableIndex, ResultRelInfo::ri_RootResultRelInfo, ResultRelInfo::ri_RootToPartitionMap, and RangeTblEntry::updatedCols.

Referenced by exec_rt_fetch(), ExecConstraints(), ExecGetAllUpdatedCols(), ExecPartitionCheckEmitError(), ExecWithCheckOptions(), and index_unchanged_by_update().

1296 {
1297  /* see ExecGetInsertedCols() */
1298  if (relinfo->ri_RangeTableIndex != 0)
1299  {
1300  RangeTblEntry *rte = exec_rt_fetch(relinfo->ri_RangeTableIndex, estate);
1301 
1302  return rte->updatedCols;
1303  }
1304  else if (relinfo->ri_RootResultRelInfo)
1305  {
1306  ResultRelInfo *rootRelInfo = relinfo->ri_RootResultRelInfo;
1307  RangeTblEntry *rte = exec_rt_fetch(rootRelInfo->ri_RangeTableIndex, estate);
1308 
1309  if (relinfo->ri_RootToPartitionMap != NULL)
1311  rte->updatedCols);
1312  else
1313  return rte->updatedCols;
1314  }
1315  else
1316  return NULL;
1317 }
Index ri_RangeTableIndex
Definition: execnodes.h:408
struct ResultRelInfo * ri_RootResultRelInfo
Definition: execnodes.h:512
static RangeTblEntry * exec_rt_fetch(Index rti, EState *estate)
Definition: executor.h:571
AttrMap * attrMap
Definition: tupconvert.h:28
Bitmapset * updatedCols
Definition: parsenodes.h:1149
TupleConversionMap * ri_RootToPartitionMap
Definition: execnodes.h:513
Bitmapset * execute_attr_map_cols(AttrMap *attrMap, Bitmapset *in_cols)
Definition: tupconvert.c:237

◆ ExecInitRangeTable()

void ExecInitRangeTable ( EState estate,
List rangeTable 
)

Definition at line 751 of file execUtils.c.

References EState::es_range_table, EState::es_range_table_size, EState::es_relations, EState::es_result_relations, EState::es_rowmarks, list_length(), and palloc0().

Referenced by CopyFrom(), create_edata_for_relation(), and InitPlan().

752 {
753  /* Remember the range table List as-is */
754  estate->es_range_table = rangeTable;
755 
756  /* Set size of associated arrays */
757  estate->es_range_table_size = list_length(rangeTable);
758 
759  /*
760  * Allocate an array to store an open Relation corresponding to each
761  * rangetable entry, and initialize entries to NULL. Relations are opened
762  * and stored here as needed.
763  */
764  estate->es_relations = (Relation *)
765  palloc0(estate->es_range_table_size * sizeof(Relation));
766 
767  /*
768  * es_result_relations and es_rowmarks are also parallel to
769  * es_range_table, but are allocated only if needed.
770  */
771  estate->es_result_relations = NULL;
772  estate->es_rowmarks = NULL;
773 }
List * es_range_table
Definition: execnodes.h:560
struct ExecRowMark ** es_rowmarks
Definition: execnodes.h:564
ResultRelInfo ** es_result_relations
Definition: execnodes.h:575
void * palloc0(Size size)
Definition: mcxt.c:1093
Relation * es_relations
Definition: execnodes.h:562
static int list_length(const List *l)
Definition: pg_list.h:149
Index es_range_table_size
Definition: execnodes.h:561

◆ ExecInitResultRelation()

void ExecInitResultRelation ( EState estate,
ResultRelInfo resultRelInfo,
Index  rti 
)

Definition at line 834 of file execUtils.c.

References EState::es_instrument, EState::es_opened_result_relations, EState::es_range_table_size, EState::es_result_relations, ExecGetRangeTableRelation(), InitResultRelInfo(), lappend(), and palloc0().

Referenced by CopyFrom(), exec_rt_fetch(), and ExecInitModifyTable().

836 {
837  Relation resultRelationDesc;
838 
839  resultRelationDesc = ExecGetRangeTableRelation(estate, rti);
840  InitResultRelInfo(resultRelInfo,
841  resultRelationDesc,
842  rti,
843  NULL,
844  estate->es_instrument);
845 
846  if (estate->es_result_relations == NULL)
847  estate->es_result_relations = (ResultRelInfo **)
848  palloc0(estate->es_range_table_size * sizeof(ResultRelInfo *));
849  estate->es_result_relations[rti - 1] = resultRelInfo;
850 
851  /*
852  * Saving in the list allows to avoid needlessly traversing the whole
853  * array when only a few of its entries are possibly non-NULL.
854  */
856  lappend(estate->es_opened_result_relations, resultRelInfo);
857 }
List * es_opened_result_relations
Definition: execnodes.h:578
int es_instrument
Definition: execnodes.h:607
ResultRelInfo ** es_result_relations
Definition: execnodes.h:575
List * lappend(List *list, void *datum)
Definition: list.c:336
void * palloc0(Size size)
Definition: mcxt.c:1093
void InitResultRelInfo(ResultRelInfo *resultRelInfo, Relation resultRelationDesc, Index resultRelationIndex, ResultRelInfo *partition_root_rri, int instrument_options)
Definition: execMain.c:1193
Relation ExecGetRangeTableRelation(EState *estate, Index rti)
Definition: execUtils.c:782
Index es_range_table_size
Definition: execnodes.h:561

◆ ExecOpenScanRelation()

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

Definition at line 720 of file execUtils.c.

References ereport, errcode(), errhint(), errmsg(), ERROR, EXEC_FLAG_EXPLAIN_ONLY, EXEC_FLAG_WITH_NO_DATA, ExecGetRangeTableRelation(), RelationGetRelationName, and RelationIsScannable.

Referenced by ExecInitBitmapHeapScan(), ExecInitCustomScan(), ExecInitForeignScan(), ExecInitIndexOnlyScan(), ExecInitIndexScan(), ExecInitSampleScan(), ExecInitSeqScan(), ExecInitTidRangeScan(), ExecInitTidScan(), and postgresBeginDirectModify().

721 {
722  Relation rel;
723 
724  /* Open the relation. */
725  rel = ExecGetRangeTableRelation(estate, scanrelid);
726 
727  /*
728  * Complain if we're attempting a scan of an unscannable relation, except
729  * when the query won't actually be run. This is a slightly klugy place
730  * to do this, perhaps, but there is no better place.
731  */
732  if ((eflags & (EXEC_FLAG_EXPLAIN_ONLY | EXEC_FLAG_WITH_NO_DATA)) == 0 &&
733  !RelationIsScannable(rel))
734  ereport(ERROR,
735  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
736  errmsg("materialized view \"%s\" has not been populated",
738  errhint("Use the REFRESH MATERIALIZED VIEW command.")));
739 
740  return rel;
741 }
int errhint(const char *fmt,...)
Definition: elog.c:1156
#define RelationIsScannable(relation)
Definition: rel.h:642
int errcode(int sqlerrcode)
Definition: elog.c:698
#define EXEC_FLAG_WITH_NO_DATA
Definition: executor.h:61
#define ERROR
Definition: elog.h:46
#define RelationGetRelationName(relation)
Definition: rel.h:511
#define ereport(elevel,...)
Definition: elog.h:157
Relation ExecGetRangeTableRelation(EState *estate, Index rti)
Definition: execUtils.c:782
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define EXEC_FLAG_EXPLAIN_ONLY
Definition: executor.h:56

◆ ExecRelationIsTargetRelation()

bool ExecRelationIsTargetRelation ( EState estate,
Index  scanrelid 
)

Definition at line 707 of file execUtils.c.

References EState::es_plannedstmt, list_member_int(), and PlannedStmt::resultRelations.

708 {
709  return list_member_int(estate->es_plannedstmt->resultRelations, scanrelid);
710 }
PlannedStmt * es_plannedstmt
Definition: execnodes.h:566
bool list_member_int(const List *list, int datum)
Definition: list.c:669
List * resultRelations
Definition: plannodes.h:69

◆ ExecTargetListLength()

int ExecTargetListLength ( List targetlist)

Definition at line 1137 of file execUtils.c.

References list_length().

Referenced by exec_rt_fetch(), and ExecTypeFromTLInternal().

1138 {
1139  /* This used to be more complex, but fjoins are dead */
1140  return list_length(targetlist);
1141 }
static int list_length(const List *l)
Definition: pg_list.h:149

◆ executor_errposition()

int executor_errposition ( EState estate,
int  location 
)

Definition at line 898 of file execUtils.c.

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

Referenced by exec_rt_fetch(), ExecInitFunc(), ExecInitSubscriptingRef(), and init_sexpr().

899 {
900  int pos;
901 
902  /* No-op if location was not provided */
903  if (location < 0)
904  return 0;
905  /* Can't do anything if source text is not available */
906  if (estate == NULL || estate->es_sourceText == NULL)
907  return 0;
908  /* Convert offset to character number */
909  pos = pg_mbstrlen_with_len(estate->es_sourceText, location) + 1;
910  /* And pass it to the ereport mechanism */
911  return errposition(pos);
912 }
int pg_mbstrlen_with_len(const char *mbstr, int limit)
Definition: mbutils.c:1000
const char * es_sourceText
Definition: execnodes.h:567
int errposition(int cursorpos)
Definition: elog.c:1285

◆ FreeExecutorState()

void FreeExecutorState ( EState estate)

Definition at line 186 of file execUtils.c.

References DestroyPartitionDirectory(), EState::es_exprcontexts, EState::es_jit, EState::es_partition_directory, EState::es_query_cxt, FreeExprContext(), jit_release_context(), linitial, and MemoryContextDelete().

Referenced by afterTriggerInvokeEvents(), ATRewriteTable(), check_default_partition_contents(), compute_expr_stats(), compute_index_stats(), CopyFrom(), EvalPlanQualEnd(), evaluate_expr(), ExecuteCallStmt(), ExecuteQuery(), ExecuteTruncateGuts(), ExplainExecuteQuery(), finish_edata(), get_qual_for_range(), heapam_index_build_range_scan(), heapam_index_validate_scan(), IndexCheckExclusion(), make_build_data(), operator_predicate_proof(), plpgsql_inline_handler(), plpgsql_xact_cb(), standard_ExecutorEnd(), StoreAttrDefault(), tuplesort_free(), unique_key_recheck(), and validateDomainConstraint().

187 {
188  /*
189  * Shut down and free any remaining ExprContexts. We do this explicitly
190  * to ensure that any remaining shutdown callbacks get called (since they
191  * might need to release resources that aren't simply memory within the
192  * per-query memory context).
193  */
194  while (estate->es_exprcontexts)
195  {
196  /*
197  * XXX: seems there ought to be a faster way to implement this than
198  * repeated list_delete(), no?
199  */
201  true);
202  /* FreeExprContext removed the list link for us */
203  }
204 
205  /* release JIT context, if allocated */
206  if (estate->es_jit)
207  {
208  jit_release_context(estate->es_jit);
209  estate->es_jit = NULL;
210  }
211 
212  /* release partition directory, if allocated */
213  if (estate->es_partition_directory)
214  {
216  estate->es_partition_directory = NULL;
217  }
218 
219  /*
220  * Free the per-query memory context, thereby releasing all working
221  * memory, including the EState node itself.
222  */
224 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:218
struct JitContext * es_jit
Definition: execnodes.h:646
MemoryContext es_query_cxt
Definition: execnodes.h:600
#define linitial(l)
Definition: pg_list.h:174
void DestroyPartitionDirectory(PartitionDirectory pdir)
Definition: partdesc.c:438
void FreeExprContext(ExprContext *econtext, bool isCommit)
Definition: execUtils.c:411
PartitionDirectory es_partition_directory
Definition: execnodes.h:582
void jit_release_context(JitContext *context)
Definition: jit.c:138
List * es_exprcontexts
Definition: execnodes.h:610

◆ FreeExprContext()

void FreeExprContext ( ExprContext econtext,
bool  isCommit 
)

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

412 {
413  EState *estate;
414 
415  /* Call any registered callbacks */
416  ShutdownExprContext(econtext, isCommit);
417  /* And clean up the memory used */
419  /* Unlink self from owning EState, if any */
420  estate = econtext->ecxt_estate;
421  if (estate)
423  econtext);
424  /* And delete the ExprContext node */
425  pfree(econtext);
426 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:218
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:234
List * list_delete_ptr(List *list, void *datum)
Definition: list.c:811
void pfree(void *pointer)
Definition: mcxt.c:1169
struct EState * ecxt_estate
Definition: execnodes.h:262
static void ShutdownExprContext(ExprContext *econtext, bool isCommit)
Definition: execUtils.c:982
List * es_exprcontexts
Definition: execnodes.h:610

◆ GetAttributeByName()

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

Definition at line 1023 of file execUtils.c.

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

Referenced by c_overpaid(), exec_rt_fetch(), and overpaid().

1024 {
1025  AttrNumber attrno;
1026  Datum result;
1027  Oid tupType;
1028  int32 tupTypmod;
1029  TupleDesc tupDesc;
1030  HeapTupleData tmptup;
1031  int i;
1032 
1033  if (attname == NULL)
1034  elog(ERROR, "invalid attribute name");
1035 
1036  if (isNull == NULL)
1037  elog(ERROR, "a NULL isNull pointer was passed");
1038 
1039  if (tuple == NULL)
1040  {
1041  /* Kinda bogus but compatible with old behavior... */
1042  *isNull = true;
1043  return (Datum) 0;
1044  }
1045 
1046  tupType = HeapTupleHeaderGetTypeId(tuple);
1047  tupTypmod = HeapTupleHeaderGetTypMod(tuple);
1048  tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
1049 
1050  attrno = InvalidAttrNumber;
1051  for (i = 0; i < tupDesc->natts; i++)
1052  {
1053  Form_pg_attribute att = TupleDescAttr(tupDesc, i);
1054 
1055  if (namestrcmp(&(att->attname), attname) == 0)
1056  {
1057  attrno = att->attnum;
1058  break;
1059  }
1060  }
1061 
1062  if (attrno == InvalidAttrNumber)
1063  elog(ERROR, "attribute \"%s\" does not exist", attname);
1064 
1065  /*
1066  * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
1067  * the fields in the struct just in case user tries to inspect system
1068  * columns.
1069  */
1070  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
1071  ItemPointerSetInvalid(&(tmptup.t_self));
1072  tmptup.t_tableOid = InvalidOid;
1073  tmptup.t_data = tuple;
1074 
1075  result = heap_getattr(&tmptup,
1076  attrno,
1077  tupDesc,
1078  isNull);
1079 
1080  ReleaseTupleDesc(tupDesc);
1081 
1082  return result;
1083 }
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition: typcache.c:1824
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
int namestrcmp(Name name, const char *str)
Definition: name.c:247
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:429
HeapTupleHeader t_data
Definition: htup.h:68
#define HeapTupleHeaderGetTypMod(tup)
Definition: htup_details.h:467
#define ERROR
Definition: elog.h:46
NameData attname
Definition: pg_attribute.h:41
ItemPointerData t_self
Definition: htup.h:65
uint32 t_len
Definition: htup.h:64
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:207
Oid t_tableOid
Definition: htup.h:66
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:761
uintptr_t Datum
Definition: postgres.h:411
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:457
#define InvalidOid
Definition: postgres_ext.h:36
#define InvalidAttrNumber
Definition: attnum.h:23
#define ItemPointerSetInvalid(pointer)
Definition: itemptr.h:172
#define elog(elevel,...)
Definition: elog.h:232
int i
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:122
int16 AttrNumber
Definition: attnum.h:21
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:451

◆ GetAttributeByNum()

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

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

Referenced by exec_rt_fetch().

1089 {
1090  Datum result;
1091  Oid tupType;
1092  int32 tupTypmod;
1093  TupleDesc tupDesc;
1094  HeapTupleData tmptup;
1095 
1096  if (!AttributeNumberIsValid(attrno))
1097  elog(ERROR, "invalid attribute number %d", attrno);
1098 
1099  if (isNull == NULL)
1100  elog(ERROR, "a NULL isNull pointer was passed");
1101 
1102  if (tuple == NULL)
1103  {
1104  /* Kinda bogus but compatible with old behavior... */
1105  *isNull = true;
1106  return (Datum) 0;
1107  }
1108 
1109  tupType = HeapTupleHeaderGetTypeId(tuple);
1110  tupTypmod = HeapTupleHeaderGetTypMod(tuple);
1111  tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
1112 
1113  /*
1114  * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
1115  * the fields in the struct just in case user tries to inspect system
1116  * columns.
1117  */
1118  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
1119  ItemPointerSetInvalid(&(tmptup.t_self));
1120  tmptup.t_tableOid = InvalidOid;
1121  tmptup.t_data = tuple;
1122 
1123  result = heap_getattr(&tmptup,
1124  attrno,
1125  tupDesc,
1126  isNull);
1127 
1128  ReleaseTupleDesc(tupDesc);
1129 
1130  return result;
1131 }
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition: typcache.c:1824
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:429
HeapTupleHeader t_data
Definition: htup.h:68
#define HeapTupleHeaderGetTypMod(tup)
Definition: htup_details.h:467
#define ERROR
Definition: elog.h:46
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:761
#define AttributeNumberIsValid(attributeNumber)
Definition: attnum.h:34
uintptr_t Datum
Definition: postgres.h:411
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:457
#define InvalidOid
Definition: postgres_ext.h:36
#define ItemPointerSetInvalid(pointer)
Definition: itemptr.h:172
#define elog(elevel,...)
Definition: elog.h:232
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:122
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:451

◆ MakePerTupleExprContext()

ExprContext* MakePerTupleExprContext ( EState estate)

Definition at line 453 of file execUtils.c.

References CreateExprContext(), and EState::es_per_tuple_exprcontext.

454 {
455  if (estate->es_per_tuple_exprcontext == NULL)
457 
458  return estate->es_per_tuple_exprcontext;
459 }
ExprContext * es_per_tuple_exprcontext
Definition: execnodes.h:621
ExprContext * CreateExprContext(EState *estate)
Definition: execUtils.c:301

◆ RegisterExprContextCallback()

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

Definition at line 925 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(), exec_rt_fetch(), ExecMakeFunctionResultSet(), ExecPrepareTuplestoreResult(), fmgr_sql(), and init_MultiFuncCall().

928 {
929  ExprContext_CB *ecxt_callback;
930 
931  /* Save the info in appropriate memory context */
932  ecxt_callback = (ExprContext_CB *)
934  sizeof(ExprContext_CB));
935 
936  ecxt_callback->function = function;
937  ecxt_callback->arg = arg;
938 
939  /* link to front of list for appropriate execution order */
940  ecxt_callback->next = econtext->ecxt_callbacks;
941  econtext->ecxt_callbacks = ecxt_callback;
942 }
ExprContextCallbackFunction function
Definition: execnodes.h:193
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:265
struct ExprContext_CB * next
Definition: execnodes.h:192
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:233
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:863
void * arg

◆ ReScanExprContext()

void ReScanExprContext ( ExprContext econtext)

Definition at line 438 of file execUtils.c.

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

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

439 {
440  /* Call any registered callbacks */
441  ShutdownExprContext(econtext, true);
442  /* And clean up the memory used */
444 }
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:234
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:143
static void ShutdownExprContext(ExprContext *econtext, bool isCommit)
Definition: execUtils.c:982

◆ ShutdownExprContext()

static void ShutdownExprContext ( ExprContext econtext,
bool  isCommit 
)
static

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

983 {
984  ExprContext_CB *ecxt_callback;
985  MemoryContext oldcontext;
986 
987  /* Fast path in normal case where there's nothing to do. */
988  if (econtext->ecxt_callbacks == NULL)
989  return;
990 
991  /*
992  * Call the callbacks in econtext's per-tuple context. This ensures that
993  * any memory they might leak will get cleaned up.
994  */
995  oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
996 
997  /*
998  * Call each callback function in reverse registration order.
999  */
1000  while ((ecxt_callback = econtext->ecxt_callbacks) != NULL)
1001  {
1002  econtext->ecxt_callbacks = ecxt_callback->next;
1003  if (isCommit)
1004  ecxt_callback->function(ecxt_callback->arg);
1005  pfree(ecxt_callback);
1006  }
1007 
1008  MemoryContextSwitchTo(oldcontext);
1009 }
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:234
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void pfree(void *pointer)
Definition: mcxt.c:1169
ExprContextCallbackFunction function
Definition: execnodes.h:193
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:265
struct ExprContext_CB * next
Definition: execnodes.h:192

◆ tlist_matches_tupdesc()

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

Definition at line 582 of file execUtils.c.

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

Referenced by ExecConditionalAssignProjectionInfo().

583 {
584  int numattrs = tupdesc->natts;
585  int attrno;
586  ListCell *tlist_item = list_head(tlist);
587 
588  /* Check the tlist attributes */
589  for (attrno = 1; attrno <= numattrs; attrno++)
590  {
591  Form_pg_attribute att_tup = TupleDescAttr(tupdesc, attrno - 1);
592  Var *var;
593 
594  if (tlist_item == NULL)
595  return false; /* tlist too short */
596  var = (Var *) ((TargetEntry *) lfirst(tlist_item))->expr;
597  if (!var || !IsA(var, Var))
598  return false; /* tlist item not a Var */
599  /* if these Asserts fail, planner messed up */
600  Assert(var->varno == varno);
601  Assert(var->varlevelsup == 0);
602  if (var->varattno != attrno)
603  return false; /* out of order */
604  if (att_tup->attisdropped)
605  return false; /* table contains dropped columns */
606  if (att_tup->atthasmissing)
607  return false; /* table contains cols with missing values */
608 
609  /*
610  * Note: usually the Var's type should match the tupdesc exactly, but
611  * in situations involving unions of columns that have different
612  * typmods, the Var may have come from above the union and hence have
613  * typmod -1. This is a legitimate situation since the Var still
614  * describes the column, just not as exactly as the tupdesc does. We
615  * could change the planner to prevent it, but it'd then insert
616  * projection steps just to convert from specific typmod to typmod -1,
617  * which is pretty silly.
618  */
619  if (var->vartype != att_tup->atttypid ||
620  (var->vartypmod != att_tup->atttypmod &&
621  var->vartypmod != -1))
622  return false; /* type mismatch */
623 
624  tlist_item = lnext(tlist, tlist_item);
625  }
626 
627  if (tlist_item)
628  return false; /* tlist too long */
629 
630  return true;
631 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:590
Index varlevelsup
Definition: primnodes.h:196
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:322
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
AttrNumber varattno
Definition: primnodes.h:191
Definition: primnodes.h:186
Oid vartype
Definition: primnodes.h:193
static ListCell * list_head(const List *l)
Definition: pg_list.h:125
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:207
Index varno
Definition: primnodes.h:189
#define Assert(condition)
Definition: c.h:804
#define lfirst(lc)
Definition: pg_list.h:169
int32 vartypmod
Definition: primnodes.h:194

◆ UnregisterExprContextCallback()

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

Definition at line 951 of file execUtils.c.

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

Referenced by end_MultiFuncCall(), exec_rt_fetch(), and fmgr_sql().

954 {
955  ExprContext_CB **prev_callback;
956  ExprContext_CB *ecxt_callback;
957 
958  prev_callback = &econtext->ecxt_callbacks;
959 
960  while ((ecxt_callback = *prev_callback) != NULL)
961  {
962  if (ecxt_callback->function == function && ecxt_callback->arg == arg)
963  {
964  *prev_callback = ecxt_callback->next;
965  pfree(ecxt_callback);
966  }
967  else
968  prev_callback = &ecxt_callback->next;
969  }
970 }
void pfree(void *pointer)
Definition: mcxt.c:1169
ExprContextCallbackFunction function
Definition: execnodes.h:193
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:265
struct ExprContext_CB * next
Definition: execnodes.h:192
void * arg

◆ UpdateChangedParamSet()

void UpdateChangedParamSet ( PlanState node,
Bitmapset newchg 
)

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

865 {
866  Bitmapset *parmset;
867 
868  /*
869  * The plan node only depends on params listed in its allParam set. Don't
870  * include anything else into its chgParam set.
871  */
872  parmset = bms_intersect(node->plan->allParam, newchg);
873 
874  /*
875  * Keep node->chgParam == NULL if there's not actually any members; this
876  * allows the simplest possible tests in executor node files.
877  */
878  if (!bms_is_empty(parmset))
879  node->chgParam = bms_join(node->chgParam, parmset);
880  else
881  bms_free(parmset);
882 }
Bitmapset * bms_join(Bitmapset *a, Bitmapset *b)
Definition: bitmapset.c:949
Bitmapset * allParam
Definition: plannodes.h:160
Bitmapset * chgParam
Definition: execnodes.h:998
bool bms_is_empty(const Bitmapset *a)
Definition: bitmapset.c:701
Bitmapset * bms_intersect(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:259
Plan * plan
Definition: execnodes.h:966
void bms_free(Bitmapset *a)
Definition: bitmapset.c:208