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 "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 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)
 

Function Documentation

◆ CreateExecutorState()

EState* CreateExecutorState ( void  )

Definition at line 89 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_num_result_relations, EState::es_num_root_result_relations, EState::es_output_cid, EState::es_param_exec_vals, EState::es_param_list_info, EState::es_per_tuple_exprcontext, EState::es_plannedstmt, EState::es_processed, EState::es_query_cxt, EState::es_queryEnv, EState::es_range_table, EState::es_range_table_size, EState::es_relations, EState::es_result_relation_info, EState::es_result_relations, EState::es_root_result_relations, EState::es_rowmarks, EState::es_snapshot, EState::es_sourceText, EState::es_subplanstates, EState::es_top_eflags, EState::es_trig_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_index_stats(), CopyFrom(), create_estate_for_relation(), EvalPlanQualStart(), evaluate_expr(), ExecuteCallStmt(), ExecuteQuery(), ExecuteTruncateGuts(), ExplainExecuteQuery(), get_qual_for_range(), heapam_index_build_range_scan(), heapam_index_validate_scan(), IndexCheckExclusion(), operator_predicate_proof(), plpgsql_create_econtext(), plpgsql_inline_handler(), standard_ExecutorStart(), StoreAttrDefault(), tuplesort_begin_cluster(), unique_key_recheck(), validateCheckConstraint(), and validateDomainConstraint().

90 {
91  EState *estate;
92  MemoryContext qcontext;
93  MemoryContext oldcontext;
94 
95  /*
96  * Create the per-query context for this Executor run.
97  */
99  "ExecutorState",
101 
102  /*
103  * Make the EState node within the per-query context. This way, we don't
104  * need a separate pfree() operation for it at shutdown.
105  */
106  oldcontext = MemoryContextSwitchTo(qcontext);
107 
108  estate = makeNode(EState);
109 
110  /*
111  * Initialize all fields of the Executor State structure
112  */
114  estate->es_snapshot = InvalidSnapshot; /* caller must initialize this */
115  estate->es_crosscheck_snapshot = InvalidSnapshot; /* no crosscheck */
116  estate->es_range_table = NIL;
117  estate->es_range_table_size = 0;
118  estate->es_relations = NULL;
119  estate->es_rowmarks = NULL;
120  estate->es_plannedstmt = NULL;
121 
122  estate->es_junkFilter = NULL;
123 
124  estate->es_output_cid = (CommandId) 0;
125 
126  estate->es_result_relations = NULL;
127  estate->es_num_result_relations = 0;
128  estate->es_result_relation_info = NULL;
129 
130  estate->es_root_result_relations = NULL;
131  estate->es_num_root_result_relations = 0;
132 
134 
135  estate->es_trig_target_relations = NIL;
136 
137  estate->es_param_list_info = NULL;
138  estate->es_param_exec_vals = NULL;
139 
140  estate->es_queryEnv = NULL;
141 
142  estate->es_query_cxt = qcontext;
143 
144  estate->es_tupleTable = NIL;
145 
146  estate->es_processed = 0;
147 
148  estate->es_top_eflags = 0;
149  estate->es_instrument = 0;
150  estate->es_finished = false;
151 
152  estate->es_exprcontexts = NIL;
153 
154  estate->es_subplanstates = NIL;
155 
156  estate->es_auxmodifytables = NIL;
157 
158  estate->es_per_tuple_exprcontext = NULL;
159 
160  estate->es_sourceText = NULL;
161 
162  estate->es_use_parallel_mode = false;
163 
164  estate->es_jit_flags = 0;
165  estate->es_jit = NULL;
166 
167  /*
168  * Return the executor state structure
169  */
170  MemoryContextSwitchTo(oldcontext);
171 
172  return estate;
173 }
#define NIL
Definition: pg_list.h:65
uint32 CommandId
Definition: c.h:527
JunkFilter * es_junkFilter
Definition: execnodes.h:519
#define AllocSetContextCreate
Definition: memutils.h:170
CommandId es_output_cid
Definition: execnodes.h:522
struct JitContext * es_jit
Definition: execnodes.h:601
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
PlannedStmt * es_plannedstmt
Definition: execnodes.h:516
Snapshot es_crosscheck_snapshot
Definition: execnodes.h:509
ExprContext * es_per_tuple_exprcontext
Definition: execnodes.h:576
Snapshot es_snapshot
Definition: execnodes.h:508
List * es_range_table
Definition: execnodes.h:510
ScanDirection es_direction
Definition: execnodes.h:507
bool es_use_parallel_mode
Definition: execnodes.h:586
struct ExecRowMark ** es_rowmarks
Definition: execnodes.h:514
const char * es_sourceText
Definition: execnodes.h:517
ParamExecData * es_param_exec_vals
Definition: execnodes.h:550
MemoryContext es_query_cxt
Definition: execnodes.h:555
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:192
int es_jit_flags
Definition: execnodes.h:600
ResultRelInfo * es_result_relations
Definition: execnodes.h:525
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
int es_instrument
Definition: execnodes.h:562
QueryEnvironment * es_queryEnv
Definition: execnodes.h:552
int es_num_root_result_relations
Definition: execnodes.h:536
#define InvalidSnapshot
Definition: snapshot.h:123
List * es_trig_target_relations
Definition: execnodes.h:546
List * es_tupleTable
Definition: execnodes.h:557
List * es_auxmodifytables
Definition: execnodes.h:569
int es_num_result_relations
Definition: execnodes.h:526
List * es_tuple_routing_result_relations
Definition: execnodes.h:543
bool es_finished
Definition: execnodes.h:563
#define makeNode(_type_)
Definition: nodes.h:577
Relation * es_relations
Definition: execnodes.h:512
uint64 es_processed
Definition: execnodes.h:559
Index es_range_table_size
Definition: execnodes.h:511
List * es_subplanstates
Definition: execnodes.h:567
int es_top_eflags
Definition: execnodes.h:561
ResultRelInfo * es_root_result_relations
Definition: execnodes.h:535
ParamListInfo es_param_list_info
Definition: execnodes.h:549
List * es_exprcontexts
Definition: execnodes.h:565
ResultRelInfo * es_result_relation_info
Definition: execnodes.h:527

◆ CreateExprContext()

ExprContext* CreateExprContext ( EState estate)

Definition at line 306 of file execUtils.c.

References ALLOCSET_DEFAULT_SIZES, and CreateExprContextInternal().

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

307 {
309 }
static ExprContext * CreateExprContextInternal(EState *estate, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: execUtils.c:236
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:192

◆ CreateExprContextInternal()

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

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

238 {
239  ExprContext *econtext;
240  MemoryContext oldcontext;
241 
242  /* Create the ExprContext node within the per-query memory context */
243  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
244 
245  econtext = makeNode(ExprContext);
246 
247  /* Initialize fields of ExprContext */
248  econtext->ecxt_scantuple = NULL;
249  econtext->ecxt_innertuple = NULL;
250  econtext->ecxt_outertuple = NULL;
251 
252  econtext->ecxt_per_query_memory = estate->es_query_cxt;
253 
254  /*
255  * Create working memory for expression evaluation in this context.
256  */
257  econtext->ecxt_per_tuple_memory =
259  "ExprContext",
260  minContextSize,
261  initBlockSize,
262  maxBlockSize);
263 
264  econtext->ecxt_param_exec_vals = estate->es_param_exec_vals;
265  econtext->ecxt_param_list_info = estate->es_param_list_info;
266 
267  econtext->ecxt_aggvalues = NULL;
268  econtext->ecxt_aggnulls = NULL;
269 
270  econtext->caseValue_datum = (Datum) 0;
271  econtext->caseValue_isNull = true;
272 
273  econtext->domainValue_datum = (Datum) 0;
274  econtext->domainValue_isNull = true;
275 
276  econtext->ecxt_estate = estate;
277 
278  econtext->ecxt_callbacks = NULL;
279 
280  /*
281  * Link the ExprContext into the EState to ensure it is shut down when the
282  * EState is freed. Because we use lcons(), shutdowns will occur in
283  * reverse order of creation, which may not be essential but can't hurt.
284  */
285  estate->es_exprcontexts = lcons(econtext, estate->es_exprcontexts);
286 
287  MemoryContextSwitchTo(oldcontext);
288 
289  return econtext;
290 }
#define AllocSetContextCreate
Definition: memutils.h:170
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:550
MemoryContext es_query_cxt
Definition: execnodes.h:555
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:367
List * lcons(void *datum, List *list)
Definition: list.c:453
#define makeNode(_type_)
Definition: nodes.h:577
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:549
List * es_exprcontexts
Definition: execnodes.h:565
ParamListInfo ecxt_param_list_info
Definition: execnodes.h:238

◆ CreateStandaloneExprContext()

ExprContext* CreateStandaloneExprContext ( void  )

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

358 {
359  ExprContext *econtext;
360 
361  /* Create the ExprContext node within the caller's memory context */
362  econtext = makeNode(ExprContext);
363 
364  /* Initialize fields of ExprContext */
365  econtext->ecxt_scantuple = NULL;
366  econtext->ecxt_innertuple = NULL;
367  econtext->ecxt_outertuple = NULL;
368 
370 
371  /*
372  * Create working memory for expression evaluation in this context.
373  */
374  econtext->ecxt_per_tuple_memory =
376  "ExprContext",
378 
379  econtext->ecxt_param_exec_vals = NULL;
380  econtext->ecxt_param_list_info = NULL;
381 
382  econtext->ecxt_aggvalues = NULL;
383  econtext->ecxt_aggnulls = NULL;
384 
385  econtext->caseValue_datum = (Datum) 0;
386  econtext->caseValue_isNull = true;
387 
388  econtext->domainValue_datum = (Datum) 0;
389  econtext->domainValue_isNull = true;
390 
391  econtext->ecxt_estate = NULL;
392 
393  econtext->ecxt_callbacks = NULL;
394 
395  return econtext;
396 }
#define AllocSetContextCreate
Definition: memutils.h:170
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:192
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:38
bool domainValue_isNull
Definition: execnodes.h:259
bool * ecxt_aggnulls
Definition: execnodes.h:247
uintptr_t Datum
Definition: postgres.h:367
#define makeNode(_type_)
Definition: nodes.h:577
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 321 of file execUtils.c.

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

Referenced by ExecInitAgg().

322 {
323  Size minContextSize = ALLOCSET_DEFAULT_MINSIZE;
324  Size initBlockSize = ALLOCSET_DEFAULT_INITSIZE;
325  Size maxBlockSize = ALLOCSET_DEFAULT_MAXSIZE;
326 
327  /* choose the maxBlockSize to be no larger than 1/16 of work_mem */
328  while (16 * maxBlockSize > work_mem * 1024L)
329  maxBlockSize >>= 1;
330 
331  if (maxBlockSize < ALLOCSET_DEFAULT_INITSIZE)
332  maxBlockSize = ALLOCSET_DEFAULT_INITSIZE;
333 
334  return CreateExprContextInternal(estate, minContextSize,
335  initBlockSize, maxBlockSize);
336 }
static ExprContext * CreateExprContextInternal(EState *estate, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: execUtils.c:236
#define ALLOCSET_DEFAULT_MINSIZE
Definition: memutils.h:189
int work_mem
Definition: globals.c:121
size_t Size
Definition: c.h:466
#define ALLOCSET_DEFAULT_INITSIZE
Definition: memutils.h:190
#define ALLOCSET_DEFAULT_MAXSIZE
Definition: memutils.h:191

◆ ExecAssignExprContext()

◆ ExecAssignProjectionInfo()

void ExecAssignProjectionInfo ( PlanState planstate,
TupleDesc  inputDesc 
)

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

542 {
543  planstate->ps_ProjInfo =
545  planstate->ps_ExprContext,
546  planstate->ps_ResultTupleSlot,
547  planstate,
548  inputDesc);
549 }
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:985
ExprContext * ps_ExprContext
Definition: execnodes.h:984
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:983
Plan * plan
Definition: execnodes.h:945
List * targetlist
Definition: plannodes.h:142
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 675 of file execUtils.c.

References ExecSetSlotDescriptor(), and ScanState::ss_ScanTupleSlot.

Referenced by ExecWorkTableScan().

676 {
677  TupleTableSlot *slot = scanstate->ss_ScanTupleSlot;
678 
679  ExecSetSlotDescriptor(slot, tupDesc);
680 }
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1335
void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc)
Definition: execTuples.c:1259

◆ ExecCleanTargetListLength()

int ExecCleanTargetListLength ( List targetlist)

Definition at line 1126 of file execUtils.c.

References lfirst_node, and TargetEntry::resjunk.

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

1127 {
1128  int len = 0;
1129  ListCell *tl;
1130 
1131  foreach(tl, targetlist)
1132  {
1133  TargetEntry *curTle = lfirst_node(TargetEntry, tl);
1134 
1135  if (!curTle->resjunk)
1136  len++;
1137  }
1138  return len;
1139 }
bool resjunk
Definition: primnodes.h:1414
#define lfirst_node(type, lc)
Definition: pg_list.h:193

◆ ExecConditionalAssignProjectionInfo()

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

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

562 {
563  if (tlist_matches_tupdesc(planstate,
564  planstate->plan->targetlist,
565  varno,
566  inputDesc))
567  {
568  planstate->ps_ProjInfo = NULL;
569  planstate->resultopsset = planstate->scanopsset;
570  planstate->resultopsfixed = planstate->scanopsfixed;
571  planstate->resultops = planstate->scanops;
572  }
573  else
574  {
575  if (!planstate->ps_ResultTupleSlot)
576  {
577  ExecInitResultSlot(planstate, &TTSOpsVirtual);
578  planstate->resultops = &TTSOpsVirtual;
579  planstate->resultopsfixed = true;
580  planstate->resultopsset = true;
581  }
582  ExecAssignProjectionInfo(planstate, inputDesc);
583  }
584 }
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:985
const TupleTableSlotOps TTSOpsVirtual
Definition: execTuples.c:83
const TupleTableSlotOps * resultops
Definition: execnodes.h:1020
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:983
const TupleTableSlotOps * scanops
Definition: execnodes.h:1017
void ExecAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc)
Definition: execUtils.c:540
bool resultopsset
Definition: execnodes.h:1028
Plan * plan
Definition: execnodes.h:945
bool scanopsfixed
Definition: execnodes.h:1021
void ExecInitResultSlot(PlanState *planstate, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1749
static bool tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc)
Definition: execUtils.c:587
bool scanopsset
Definition: execnodes.h:1025
List * targetlist
Definition: plannodes.h:142
bool resultopsfixed
Definition: execnodes.h:1024

◆ ExecCreateScanSlotFromOuterPlan()

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

Definition at line 687 of file execUtils.c.

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

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

690 {
692  TupleDesc tupDesc;
693 
694  outerPlan = outerPlanState(scanstate);
695  tupDesc = ExecGetResultType(outerPlan);
696 
697  ExecInitScanTupleSlot(estate, scanstate, tupDesc, tts_ops);
698 }
#define outerPlanState(node)
Definition: execnodes.h:1039
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1781
#define outerPlan(node)
Definition: plannodes.h:172
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:495

◆ ExecFreeExprContext()

◆ ExecGetRangeTableRelation()

Relation ExecGetRangeTableRelation ( EState estate,
Index  rti 
)

Definition at line 795 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(), ExecOpenScanRelation(), and InitPlan().

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

◆ ExecGetResultSlotOps()

const TupleTableSlotOps* ExecGetResultSlotOps ( PlanState planstate,
bool isfixed 
)

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

505 {
506  if (planstate->resultopsset && planstate->resultops)
507  {
508  if (isfixed)
509  *isfixed = planstate->resultopsfixed;
510  return planstate->resultops;
511  }
512 
513  if (isfixed)
514  {
515  if (planstate->resultopsset)
516  *isfixed = planstate->resultopsfixed;
517  else if (planstate->ps_ResultTupleSlot)
518  *isfixed = TTS_FIXED(planstate->ps_ResultTupleSlot);
519  else
520  *isfixed = false;
521  }
522 
523  if (!planstate->ps_ResultTupleSlot)
524  return &TTSOpsVirtual;
525 
526  return planstate->ps_ResultTupleSlot->tts_ops;
527 }
#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:1020
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:983
bool resultopsset
Definition: execnodes.h:1028
bool resultopsfixed
Definition: execnodes.h:1024

◆ ExecGetResultType()

◆ ExecGetReturningSlot()

TupleTableSlot* ExecGetReturningSlot ( EState estate,
ResultRelInfo relInfo 
)

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

1190 {
1191  if (relInfo->ri_ReturningSlot == NULL)
1192  {
1193  Relation rel = relInfo->ri_RelationDesc;
1194  MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1195 
1196  relInfo->ri_ReturningSlot =
1197  ExecInitExtraTupleSlot(estate,
1198  RelationGetDescr(rel),
1199  table_slot_callbacks(rel));
1200 
1201  MemoryContextSwitchTo(oldcontext);
1202  }
1203 
1204  return relInfo->ri_ReturningSlot;
1205 }
Relation ri_RelationDesc
Definition: execnodes.h:413
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1801
#define RelationGetDescr(relation)
Definition: rel.h:482
const TupleTableSlotOps * table_slot_callbacks(Relation relation)
Definition: tableam.c:44
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext es_query_cxt
Definition: execnodes.h:555
TupleTableSlot * ri_ReturningSlot
Definition: execnodes.h:437

◆ ExecGetTriggerNewSlot()

TupleTableSlot* ExecGetTriggerNewSlot ( EState estate,
ResultRelInfo relInfo 
)

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

1168 {
1169  if (relInfo->ri_TrigNewSlot == NULL)
1170  {
1171  Relation rel = relInfo->ri_RelationDesc;
1172  MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1173 
1174  relInfo->ri_TrigNewSlot =
1175  ExecInitExtraTupleSlot(estate,
1176  RelationGetDescr(rel),
1177  table_slot_callbacks(rel));
1178 
1179  MemoryContextSwitchTo(oldcontext);
1180  }
1181 
1182  return relInfo->ri_TrigNewSlot;
1183 }
Relation ri_RelationDesc
Definition: execnodes.h:413
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1801
#define RelationGetDescr(relation)
Definition: rel.h:482
const TupleTableSlotOps * table_slot_callbacks(Relation relation)
Definition: tableam.c:44
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
TupleTableSlot * ri_TrigNewSlot
Definition: execnodes.h:439
MemoryContext es_query_cxt
Definition: execnodes.h:555

◆ ExecGetTriggerOldSlot()

TupleTableSlot* ExecGetTriggerOldSlot ( EState estate,
ResultRelInfo relInfo 
)

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

1146 {
1147  if (relInfo->ri_TrigOldSlot == NULL)
1148  {
1149  Relation rel = relInfo->ri_RelationDesc;
1150  MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1151 
1152  relInfo->ri_TrigOldSlot =
1153  ExecInitExtraTupleSlot(estate,
1154  RelationGetDescr(rel),
1155  table_slot_callbacks(rel));
1156 
1157  MemoryContextSwitchTo(oldcontext);
1158  }
1159 
1160  return relInfo->ri_TrigOldSlot;
1161 }
Relation ri_RelationDesc
Definition: execnodes.h:413
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1801
#define RelationGetDescr(relation)
Definition: rel.h:482
const TupleTableSlotOps * table_slot_callbacks(Relation relation)
Definition: tableam.c:44
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext es_query_cxt
Definition: execnodes.h:555
TupleTableSlot * ri_TrigOldSlot
Definition: execnodes.h:438

◆ ExecInitRangeTable()

void ExecInitRangeTable ( EState estate,
List rangeTable 
)

Definition at line 765 of file execUtils.c.

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

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

766 {
767  /* Remember the range table List as-is */
768  estate->es_range_table = rangeTable;
769 
770  /* Set size of associated arrays */
771  estate->es_range_table_size = list_length(rangeTable);
772 
773  /*
774  * Allocate an array to store an open Relation corresponding to each
775  * rangetable entry, and initialize entries to NULL. Relations are opened
776  * and stored here as needed.
777  */
778  estate->es_relations = (Relation *)
779  palloc0(estate->es_range_table_size * sizeof(Relation));
780 
781  /*
782  * es_rowmarks is also parallel to the es_range_table, but it's allocated
783  * only if needed.
784  */
785  estate->es_rowmarks = NULL;
786 }
List * es_range_table
Definition: execnodes.h:510
struct ExecRowMark ** es_rowmarks
Definition: execnodes.h:514
void * palloc0(Size size)
Definition: mcxt.c:980
Relation * es_relations
Definition: execnodes.h:512
static int list_length(const List *l)
Definition: pg_list.h:169
Index es_range_table_size
Definition: execnodes.h:511

◆ ExecOpenScanRelation()

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

Definition at line 734 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(), ExecInitTidScan(), and postgresBeginDirectModify().

735 {
736  Relation rel;
737 
738  /* Open the relation. */
739  rel = ExecGetRangeTableRelation(estate, scanrelid);
740 
741  /*
742  * Complain if we're attempting a scan of an unscannable relation, except
743  * when the query won't actually be run. This is a slightly klugy place
744  * to do this, perhaps, but there is no better place.
745  */
746  if ((eflags & (EXEC_FLAG_EXPLAIN_ONLY | EXEC_FLAG_WITH_NO_DATA)) == 0 &&
747  !RelationIsScannable(rel))
748  ereport(ERROR,
749  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
750  errmsg("materialized view \"%s\" has not been populated",
752  errhint("Use the REFRESH MATERIALIZED VIEW command.")));
753 
754  return rel;
755 }
int errhint(const char *fmt,...)
Definition: elog.c:1071
#define RelationIsScannable(relation)
Definition: rel.h:604
int errcode(int sqlerrcode)
Definition: elog.c:610
#define EXEC_FLAG_WITH_NO_DATA
Definition: executor.h:61
#define ERROR
Definition: elog.h:43
#define RelationGetRelationName(relation)
Definition: rel.h:490
#define ereport(elevel,...)
Definition: elog.h:144
Relation ExecGetRangeTableRelation(EState *estate, Index rti)
Definition: execUtils.c:795
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define EXEC_FLAG_EXPLAIN_ONLY
Definition: executor.h:56

◆ ExecRelationIsTargetRelation()

bool ExecRelationIsTargetRelation ( EState estate,
Index  scanrelid 
)

Definition at line 712 of file execUtils.c.

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

713 {
714  ResultRelInfo *resultRelInfos;
715  int i;
716 
717  resultRelInfos = estate->es_result_relations;
718  for (i = 0; i < estate->es_num_result_relations; i++)
719  {
720  if (resultRelInfos[i].ri_RangeTableIndex == scanrelid)
721  return true;
722  }
723  return false;
724 }
ResultRelInfo * es_result_relations
Definition: execnodes.h:525
int es_num_result_relations
Definition: execnodes.h:526
int i

◆ ExecTargetListLength()

int ExecTargetListLength ( List targetlist)

Definition at line 1116 of file execUtils.c.

References list_length().

Referenced by exec_rt_fetch(), and ExecTypeFromTLInternal().

1117 {
1118  /* This used to be more complex, but fjoins are dead */
1119  return list_length(targetlist);
1120 }
static int list_length(const List *l)
Definition: pg_list.h:169

◆ executor_errposition()

int executor_errposition ( EState estate,
int  location 
)

Definition at line 877 of file execUtils.c.

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

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

878 {
879  int pos;
880 
881  /* No-op if location was not provided */
882  if (location < 0)
883  return 0;
884  /* Can't do anything if source text is not available */
885  if (estate == NULL || estate->es_sourceText == NULL)
886  return 0;
887  /* Convert offset to character number */
888  pos = pg_mbstrlen_with_len(estate->es_sourceText, location) + 1;
889  /* And pass it to the ereport mechanism */
890  return errposition(pos);
891 }
int pg_mbstrlen_with_len(const char *mbstr, int limit)
Definition: mbutils.c:941
const char * es_sourceText
Definition: execnodes.h:517
int errposition(int cursorpos)
Definition: elog.c:1199

◆ FreeExecutorState()

void FreeExecutorState ( EState estate)

Definition at line 191 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(), apply_handle_delete(), apply_handle_insert(), apply_handle_update(), ATRewriteTable(), check_default_partition_contents(), compute_index_stats(), CopyFrom(), EvalPlanQualEnd(), evaluate_expr(), ExecuteCallStmt(), ExecuteQuery(), ExecuteTruncateGuts(), ExplainExecuteQuery(), get_qual_for_range(), heapam_index_build_range_scan(), heapam_index_validate_scan(), IndexCheckExclusion(), operator_predicate_proof(), plpgsql_inline_handler(), plpgsql_xact_cb(), standard_ExecutorEnd(), StoreAttrDefault(), tuplesort_free(), unique_key_recheck(), validateCheckConstraint(), and validateDomainConstraint().

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

◆ FreeExprContext()

void FreeExprContext ( ExprContext econtext,
bool  isCommit 
)

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

417 {
418  EState *estate;
419 
420  /* Call any registered callbacks */
421  ShutdownExprContext(econtext, isCommit);
422  /* And clean up the memory used */
424  /* Unlink self from owning EState, if any */
425  estate = econtext->ecxt_estate;
426  if (estate)
428  econtext);
429  /* And delete the ExprContext node */
430  pfree(econtext);
431 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:211
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:234
List * list_delete_ptr(List *list, void *datum)
Definition: list.c:796
void pfree(void *pointer)
Definition: mcxt.c:1056
struct EState * ecxt_estate
Definition: execnodes.h:262
static void ShutdownExprContext(ExprContext *econtext, bool isCommit)
Definition: execUtils.c:961
List * es_exprcontexts
Definition: execnodes.h:565

◆ GetAttributeByName()

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

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

1003 {
1004  AttrNumber attrno;
1005  Datum result;
1006  Oid tupType;
1007  int32 tupTypmod;
1008  TupleDesc tupDesc;
1009  HeapTupleData tmptup;
1010  int i;
1011 
1012  if (attname == NULL)
1013  elog(ERROR, "invalid attribute name");
1014 
1015  if (isNull == NULL)
1016  elog(ERROR, "a NULL isNull pointer was passed");
1017 
1018  if (tuple == NULL)
1019  {
1020  /* Kinda bogus but compatible with old behavior... */
1021  *isNull = true;
1022  return (Datum) 0;
1023  }
1024 
1025  tupType = HeapTupleHeaderGetTypeId(tuple);
1026  tupTypmod = HeapTupleHeaderGetTypMod(tuple);
1027  tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
1028 
1029  attrno = InvalidAttrNumber;
1030  for (i = 0; i < tupDesc->natts; i++)
1031  {
1032  Form_pg_attribute att = TupleDescAttr(tupDesc, i);
1033 
1034  if (namestrcmp(&(att->attname), attname) == 0)
1035  {
1036  attrno = att->attnum;
1037  break;
1038  }
1039  }
1040 
1041  if (attrno == InvalidAttrNumber)
1042  elog(ERROR, "attribute \"%s\" does not exist", attname);
1043 
1044  /*
1045  * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
1046  * the fields in the struct just in case user tries to inspect system
1047  * columns.
1048  */
1049  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
1050  ItemPointerSetInvalid(&(tmptup.t_self));
1051  tmptup.t_tableOid = InvalidOid;
1052  tmptup.t_data = tuple;
1053 
1054  result = heap_getattr(&tmptup,
1055  attrno,
1056  tupDesc,
1057  isNull);
1058 
1059  ReleaseTupleDesc(tupDesc);
1060 
1061  return result;
1062 }
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition: typcache.c:1710
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
int namestrcmp(Name name, const char *str)
Definition: name.c:287
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:355
HeapTupleHeader t_data
Definition: htup.h:68
#define HeapTupleHeaderGetTypMod(tup)
Definition: htup_details.h:468
#define ERROR
Definition: elog.h:43
NameData attname
Definition: pg_attribute.h:40
ItemPointerData t_self
Definition: htup.h:65
uint32 t_len
Definition: htup.h:64
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:193
Oid t_tableOid
Definition: htup.h:66
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:762
uintptr_t Datum
Definition: postgres.h:367
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:458
#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:214
int i
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:122
int16 AttrNumber
Definition: attnum.h:21
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:452

◆ GetAttributeByNum()

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

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

1068 {
1069  Datum result;
1070  Oid tupType;
1071  int32 tupTypmod;
1072  TupleDesc tupDesc;
1073  HeapTupleData tmptup;
1074 
1075  if (!AttributeNumberIsValid(attrno))
1076  elog(ERROR, "invalid attribute number %d", attrno);
1077 
1078  if (isNull == NULL)
1079  elog(ERROR, "a NULL isNull pointer was passed");
1080 
1081  if (tuple == NULL)
1082  {
1083  /* Kinda bogus but compatible with old behavior... */
1084  *isNull = true;
1085  return (Datum) 0;
1086  }
1087 
1088  tupType = HeapTupleHeaderGetTypeId(tuple);
1089  tupTypmod = HeapTupleHeaderGetTypMod(tuple);
1090  tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
1091 
1092  /*
1093  * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
1094  * the fields in the struct just in case user tries to inspect system
1095  * columns.
1096  */
1097  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
1098  ItemPointerSetInvalid(&(tmptup.t_self));
1099  tmptup.t_tableOid = InvalidOid;
1100  tmptup.t_data = tuple;
1101 
1102  result = heap_getattr(&tmptup,
1103  attrno,
1104  tupDesc,
1105  isNull);
1106 
1107  ReleaseTupleDesc(tupDesc);
1108 
1109  return result;
1110 }
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition: typcache.c:1710
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:355
HeapTupleHeader t_data
Definition: htup.h:68
#define HeapTupleHeaderGetTypMod(tup)
Definition: htup_details.h:468
#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:762
#define AttributeNumberIsValid(attributeNumber)
Definition: attnum.h:34
uintptr_t Datum
Definition: postgres.h:367
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:458
#define InvalidOid
Definition: postgres_ext.h:36
#define ItemPointerSetInvalid(pointer)
Definition: itemptr.h:172
#define elog(elevel,...)
Definition: elog.h:214
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:122
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:452

◆ MakePerTupleExprContext()

ExprContext* MakePerTupleExprContext ( EState estate)

Definition at line 458 of file execUtils.c.

References CreateExprContext(), and EState::es_per_tuple_exprcontext.

459 {
460  if (estate->es_per_tuple_exprcontext == NULL)
462 
463  return estate->es_per_tuple_exprcontext;
464 }
ExprContext * es_per_tuple_exprcontext
Definition: execnodes.h:576
ExprContext * CreateExprContext(EState *estate)
Definition: execUtils.c:306

◆ RegisterExprContextCallback()

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

Definition at line 904 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(), get_cached_rowtype(), and init_MultiFuncCall().

907 {
908  ExprContext_CB *ecxt_callback;
909 
910  /* Save the info in appropriate memory context */
911  ecxt_callback = (ExprContext_CB *)
913  sizeof(ExprContext_CB));
914 
915  ecxt_callback->function = function;
916  ecxt_callback->arg = arg;
917 
918  /* link to front of list for appropriate execution order */
919  ecxt_callback->next = econtext->ecxt_callbacks;
920  econtext->ecxt_callbacks = ecxt_callback;
921 }
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:796
void * arg

◆ ReScanExprContext()

void ReScanExprContext ( ExprContext econtext)

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

444 {
445  /* Call any registered callbacks */
446  ShutdownExprContext(econtext, true);
447  /* And clean up the memory used */
449 }
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:234
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:136
static void ShutdownExprContext(ExprContext *econtext, bool isCommit)
Definition: execUtils.c:961

◆ ShutdownExprContext()

static void ShutdownExprContext ( ExprContext econtext,
bool  isCommit 
)
static

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

962 {
963  ExprContext_CB *ecxt_callback;
964  MemoryContext oldcontext;
965 
966  /* Fast path in normal case where there's nothing to do. */
967  if (econtext->ecxt_callbacks == NULL)
968  return;
969 
970  /*
971  * Call the callbacks in econtext's per-tuple context. This ensures that
972  * any memory they might leak will get cleaned up.
973  */
974  oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
975 
976  /*
977  * Call each callback function in reverse registration order.
978  */
979  while ((ecxt_callback = econtext->ecxt_callbacks) != NULL)
980  {
981  econtext->ecxt_callbacks = ecxt_callback->next;
982  if (isCommit)
983  ecxt_callback->function(ecxt_callback->arg);
984  pfree(ecxt_callback);
985  }
986 
987  MemoryContextSwitchTo(oldcontext);
988 }
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:1056
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 587 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().

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

◆ UnregisterExprContextCallback()

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

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

933 {
934  ExprContext_CB **prev_callback;
935  ExprContext_CB *ecxt_callback;
936 
937  prev_callback = &econtext->ecxt_callbacks;
938 
939  while ((ecxt_callback = *prev_callback) != NULL)
940  {
941  if (ecxt_callback->function == function && ecxt_callback->arg == arg)
942  {
943  *prev_callback = ecxt_callback->next;
944  pfree(ecxt_callback);
945  }
946  else
947  prev_callback = &ecxt_callback->next;
948  }
949 }
void pfree(void *pointer)
Definition: mcxt.c:1056
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 843 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().

844 {
845  Bitmapset *parmset;
846 
847  /*
848  * The plan node only depends on params listed in its allParam set. Don't
849  * include anything else into its chgParam set.
850  */
851  parmset = bms_intersect(node->plan->allParam, newchg);
852 
853  /*
854  * Keep node->chgParam == NULL if there's not actually any members; this
855  * allows the simplest possible tests in executor node files.
856  */
857  if (!bms_is_empty(parmset))
858  node->chgParam = bms_join(node->chgParam, parmset);
859  else
860  bms_free(parmset);
861 }
Bitmapset * bms_join(Bitmapset *a, Bitmapset *b)
Definition: bitmapset.c:949
Bitmapset * allParam
Definition: plannodes.h:161
Bitmapset * chgParam
Definition: execnodes.h:977
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:945
void bms_free(Bitmapset *a)
Definition: bitmapset.c:208