PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
execUtils.c File Reference
#include "postgres.h"
#include "access/relscan.h"
#include "access/transam.h"
#include "executor/executor.h"
#include "nodes/nodeFuncs.h"
#include "parser/parsetree.h"
#include "utils/memutils.h"
#include "utils/rel.h"
Include dependency graph for execUtils.c:

Go to the source code of this file.

Functions

static bool get_last_attnums (Node *node, ProjectionInfo *projInfo)
 
static void ShutdownExprContext (ExprContext *econtext, bool isCommit)
 
EStateCreateExecutorState (void)
 
void FreeExecutorState (EState *estate)
 
ExprContextCreateExprContext (EState *estate)
 
ExprContextCreateStandaloneExprContext (void)
 
void FreeExprContext (ExprContext *econtext, bool isCommit)
 
void ReScanExprContext (ExprContext *econtext)
 
ExprContextMakePerTupleExprContext (EState *estate)
 
void ExecAssignExprContext (EState *estate, PlanState *planstate)
 
void ExecAssignResultType (PlanState *planstate, TupleDesc tupDesc)
 
void ExecAssignResultTypeFromTL (PlanState *planstate)
 
TupleDesc ExecGetResultType (PlanState *planstate)
 
ProjectionInfoExecBuildProjectionInfo (List *targetList, ExprContext *econtext, TupleTableSlot *slot, TupleDesc inputDesc)
 
void ExecAssignProjectionInfo (PlanState *planstate, TupleDesc inputDesc)
 
void ExecFreeExprContext (PlanState *planstate)
 
void ExecAssignScanType (ScanState *scanstate, TupleDesc tupDesc)
 
void ExecAssignScanTypeFromOuterPlan (ScanState *scanstate)
 
bool ExecRelationIsTargetRelation (EState *estate, Index scanrelid)
 
Relation ExecOpenScanRelation (EState *estate, Index scanrelid, int eflags)
 
void ExecCloseScanRelation (Relation scanrel)
 
void UpdateChangedParamSet (PlanState *node, Bitmapset *newchg)
 
void RegisterExprContextCallback (ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
 
void UnregisterExprContextCallback (ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
 

Function Documentation

EState* CreateExecutorState ( void  )

Definition at line 72 of file execUtils.c.

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate(), CurrentMemoryContext, EState::es_auxmodifytables, EState::es_crosscheck_snapshot, EState::es_direction, EState::es_epqScanDone, EState::es_epqTuple, EState::es_epqTupleSet, EState::es_exprcontexts, EState::es_finished, EState::es_instrument, EState::es_junkFilter, EState::es_lastoid, EState::es_num_result_relations, EState::es_output_cid, EState::es_param_exec_vals, EState::es_param_list_info, EState::es_per_tuple_exprcontext, EState::es_plannedstmt, EState::es_processed, EState::es_query_cxt, EState::es_range_table, EState::es_result_relation_info, EState::es_result_relations, EState::es_rowMarks, EState::es_snapshot, EState::es_sourceText, EState::es_subplanstates, EState::es_top_eflags, EState::es_trig_newtup_slot, EState::es_trig_oldtup_slot, EState::es_trig_target_relations, EState::es_trig_tuple_slot, EState::es_tupleTable, ForwardScanDirection, InvalidOid, InvalidSnapshot, makeNode, MemoryContextSwitchTo(), NIL, and NULL.

Referenced by afterTriggerInvokeEvents(), ATRewriteTable(), compute_index_stats(), CopyFrom(), create_estate_for_relation(), EvalPlanQualStart(), evaluate_expr(), ExecuteQuery(), ExecuteTruncate(), ExplainExecuteQuery(), get_actual_variable_range(), get_qual_for_range(), IndexBuildHeapRangeScan(), IndexCheckExclusion(), operator_predicate_proof(), plpgsql_create_econtext(), plpgsql_inline_handler(), standard_ExecutorStart(), tuplesort_begin_cluster(), unique_key_recheck(), validate_index_heapscan(), validateCheckConstraint(), and validateDomainConstraint().

73 {
74  EState *estate;
75  MemoryContext qcontext;
76  MemoryContext oldcontext;
77 
78  /*
79  * Create the per-query context for this Executor run.
80  */
82  "ExecutorState",
84 
85  /*
86  * Make the EState node within the per-query context. This way, we don't
87  * need a separate pfree() operation for it at shutdown.
88  */
89  oldcontext = MemoryContextSwitchTo(qcontext);
90 
91  estate = makeNode(EState);
92 
93  /*
94  * Initialize all fields of the Executor State structure
95  */
97  estate->es_snapshot = InvalidSnapshot; /* caller must initialize this */
98  estate->es_crosscheck_snapshot = InvalidSnapshot; /* no crosscheck */
99  estate->es_range_table = NIL;
100  estate->es_plannedstmt = NULL;
101 
102  estate->es_junkFilter = NULL;
103 
104  estate->es_output_cid = (CommandId) 0;
105 
106  estate->es_result_relations = NULL;
107  estate->es_num_result_relations = 0;
108  estate->es_result_relation_info = NULL;
109 
110  estate->es_trig_target_relations = NIL;
111  estate->es_trig_tuple_slot = NULL;
112  estate->es_trig_oldtup_slot = NULL;
113  estate->es_trig_newtup_slot = NULL;
114 
115  estate->es_param_list_info = NULL;
116  estate->es_param_exec_vals = NULL;
117 
118  estate->es_query_cxt = qcontext;
119 
120  estate->es_tupleTable = NIL;
121 
122  estate->es_rowMarks = NIL;
123 
124  estate->es_processed = 0;
125  estate->es_lastoid = InvalidOid;
126 
127  estate->es_top_eflags = 0;
128  estate->es_instrument = 0;
129  estate->es_finished = false;
130 
131  estate->es_exprcontexts = NIL;
132 
133  estate->es_subplanstates = NIL;
134 
135  estate->es_auxmodifytables = NIL;
136 
137  estate->es_per_tuple_exprcontext = NULL;
138 
139  estate->es_epqTuple = NULL;
140  estate->es_epqTupleSet = NULL;
141  estate->es_epqScanDone = NULL;
142  estate->es_sourceText = NULL;
143 
144  /*
145  * Return the executor state structure
146  */
147  MemoryContextSwitchTo(oldcontext);
148 
149  return estate;
150 }
#define NIL
Definition: pg_list.h:69
uint32 CommandId
Definition: c.h:407
HeapTuple * es_epqTuple
Definition: execnodes.h:432
JunkFilter * es_junkFilter
Definition: execnodes.h:376
CommandId es_output_cid
Definition: execnodes.h:379
TupleTableSlot * es_trig_newtup_slot
Definition: execnodes.h:390
Oid es_lastoid
Definition: execnodes.h:404
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
PlannedStmt * es_plannedstmt
Definition: execnodes.h:373
Snapshot es_crosscheck_snapshot
Definition: execnodes.h:371
ExprContext * es_per_tuple_exprcontext
Definition: execnodes.h:421
Snapshot es_snapshot
Definition: execnodes.h:370
List * es_range_table
Definition: execnodes.h:372
ScanDirection es_direction
Definition: execnodes.h:369
const char * es_sourceText
Definition: execnodes.h:374
ParamExecData * es_param_exec_vals
Definition: execnodes.h:394
MemoryContext es_query_cxt
Definition: execnodes.h:397
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:145
ResultRelInfo * es_result_relations
Definition: execnodes.h:382
TupleTableSlot * es_trig_oldtup_slot
Definition: execnodes.h:389
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
int es_instrument
Definition: execnodes.h:407
TupleTableSlot * es_trig_tuple_slot
Definition: execnodes.h:388
#define InvalidSnapshot
Definition: snapshot.h:24
List * es_trig_target_relations
Definition: execnodes.h:387
List * es_tupleTable
Definition: execnodes.h:399
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:440
List * es_auxmodifytables
Definition: execnodes.h:414
int es_num_result_relations
Definition: execnodes.h:383
#define InvalidOid
Definition: postgres_ext.h:36
bool es_finished
Definition: execnodes.h:408
#define makeNode(_type_)
Definition: nodes.h:556
#define NULL
Definition: c.h:226
uint64 es_processed
Definition: execnodes.h:403
bool * es_epqTupleSet
Definition: execnodes.h:433
List * es_subplanstates
Definition: execnodes.h:412
List * es_rowMarks
Definition: execnodes.h:401
int es_top_eflags
Definition: execnodes.h:406
bool * es_epqScanDone
Definition: execnodes.h:434
ParamListInfo es_param_list_info
Definition: execnodes.h:393
List * es_exprcontexts
Definition: execnodes.h:410
ResultRelInfo * es_result_relation_info
Definition: execnodes.h:384
ExprContext* CreateExprContext ( EState estate)

Definition at line 208 of file execUtils.c.

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate(), ExprContext::caseValue_datum, ExprContext::caseValue_isNull, ExprContext::domainValue_datum, ExprContext::domainValue_isNull, ExprContext::ecxt_aggnulls, ExprContext::ecxt_aggvalues, ExprContext::ecxt_callbacks, ExprContext::ecxt_estate, ExprContext::ecxt_innertuple, ExprContext::ecxt_outertuple, ExprContext::ecxt_param_exec_vals, ExprContext::ecxt_param_list_info, ExprContext::ecxt_per_query_memory, ExprContext::ecxt_per_tuple_memory, ExprContext::ecxt_scantuple, EState::es_exprcontexts, EState::es_param_exec_vals, EState::es_param_list_info, EState::es_query_cxt, lcons(), makeNode, MemoryContextSwitchTo(), and NULL.

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

209 {
210  ExprContext *econtext;
211  MemoryContext oldcontext;
212 
213  /* Create the ExprContext node within the per-query memory context */
214  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
215 
216  econtext = makeNode(ExprContext);
217 
218  /* Initialize fields of ExprContext */
219  econtext->ecxt_scantuple = NULL;
220  econtext->ecxt_innertuple = NULL;
221  econtext->ecxt_outertuple = NULL;
222 
223  econtext->ecxt_per_query_memory = estate->es_query_cxt;
224 
225  /*
226  * Create working memory for expression evaluation in this context.
227  */
228  econtext->ecxt_per_tuple_memory =
230  "ExprContext",
232 
233  econtext->ecxt_param_exec_vals = estate->es_param_exec_vals;
234  econtext->ecxt_param_list_info = estate->es_param_list_info;
235 
236  econtext->ecxt_aggvalues = NULL;
237  econtext->ecxt_aggnulls = NULL;
238 
239  econtext->caseValue_datum = (Datum) 0;
240  econtext->caseValue_isNull = true;
241 
242  econtext->domainValue_datum = (Datum) 0;
243  econtext->domainValue_isNull = true;
244 
245  econtext->ecxt_estate = estate;
246 
247  econtext->ecxt_callbacks = NULL;
248 
249  /*
250  * Link the ExprContext into the EState to ensure it is shut down when the
251  * EState is freed. Because we use lcons(), shutdowns will occur in
252  * reverse order of creation, which may not be essential but can't hurt.
253  */
254  estate->es_exprcontexts = lcons(econtext, estate->es_exprcontexts);
255 
256  MemoryContextSwitchTo(oldcontext);
257 
258  return econtext;
259 }
Datum * ecxt_aggvalues
Definition: execnodes.h:144
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:134
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Datum domainValue_datum
Definition: execnodes.h:152
ParamExecData * es_param_exec_vals
Definition: execnodes.h:394
MemoryContext es_query_cxt
Definition: execnodes.h:397
Datum caseValue_datum
Definition: execnodes.h:148
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:159
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:145
TupleTableSlot * ecxt_innertuple
Definition: execnodes.h:129
ParamExecData * ecxt_param_exec_vals
Definition: execnodes.h:137
struct EState * ecxt_estate
Definition: execnodes.h:156
bool domainValue_isNull
Definition: execnodes.h:153
bool * ecxt_aggnulls
Definition: execnodes.h:145
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:440
uintptr_t Datum
Definition: postgres.h:374
List * lcons(void *datum, List *list)
Definition: list.c:259
#define makeNode(_type_)
Definition: nodes.h:556
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:130
#define NULL
Definition: c.h:226
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:128
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:133
bool caseValue_isNull
Definition: execnodes.h:149
ParamListInfo es_param_list_info
Definition: execnodes.h:393
List * es_exprcontexts
Definition: execnodes.h:410
ParamListInfo ecxt_param_list_info
Definition: execnodes.h:138
ExprContext* CreateStandaloneExprContext ( void  )

Definition at line 280 of file execUtils.c.

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate(), ExprContext::caseValue_datum, ExprContext::caseValue_isNull, CurrentMemoryContext, ExprContext::domainValue_datum, ExprContext::domainValue_isNull, ExprContext::ecxt_aggnulls, ExprContext::ecxt_aggvalues, ExprContext::ecxt_callbacks, ExprContext::ecxt_estate, ExprContext::ecxt_innertuple, ExprContext::ecxt_outertuple, ExprContext::ecxt_param_exec_vals, ExprContext::ecxt_param_list_info, ExprContext::ecxt_per_query_memory, ExprContext::ecxt_per_tuple_memory, ExprContext::ecxt_scantuple, makeNode, and NULL.

Referenced by domain_check_input().

281 {
282  ExprContext *econtext;
283 
284  /* Create the ExprContext node within the caller's memory context */
285  econtext = makeNode(ExprContext);
286 
287  /* Initialize fields of ExprContext */
288  econtext->ecxt_scantuple = NULL;
289  econtext->ecxt_innertuple = NULL;
290  econtext->ecxt_outertuple = NULL;
291 
293 
294  /*
295  * Create working memory for expression evaluation in this context.
296  */
297  econtext->ecxt_per_tuple_memory =
299  "ExprContext",
301 
302  econtext->ecxt_param_exec_vals = NULL;
303  econtext->ecxt_param_list_info = NULL;
304 
305  econtext->ecxt_aggvalues = NULL;
306  econtext->ecxt_aggnulls = NULL;
307 
308  econtext->caseValue_datum = (Datum) 0;
309  econtext->caseValue_isNull = true;
310 
311  econtext->domainValue_datum = (Datum) 0;
312  econtext->domainValue_isNull = true;
313 
314  econtext->ecxt_estate = NULL;
315 
316  econtext->ecxt_callbacks = NULL;
317 
318  return econtext;
319 }
Datum * ecxt_aggvalues
Definition: execnodes.h:144
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:134
Datum domainValue_datum
Definition: execnodes.h:152
Datum caseValue_datum
Definition: execnodes.h:148
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:159
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:145
TupleTableSlot * ecxt_innertuple
Definition: execnodes.h:129
ParamExecData * ecxt_param_exec_vals
Definition: execnodes.h:137
struct EState * ecxt_estate
Definition: execnodes.h:156
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
bool domainValue_isNull
Definition: execnodes.h:153
bool * ecxt_aggnulls
Definition: execnodes.h:145
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:440
uintptr_t Datum
Definition: postgres.h:374
#define makeNode(_type_)
Definition: nodes.h:556
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:130
#define NULL
Definition: c.h:226
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:128
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:133
bool caseValue_isNull
Definition: execnodes.h:149
ParamListInfo ecxt_param_list_info
Definition: execnodes.h:138
void ExecAssignProjectionInfo ( PlanState planstate,
TupleDesc  inputDesc 
)

Definition at line 657 of file execUtils.c.

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

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

659 {
660  planstate->ps_ProjInfo =
662  planstate->ps_ExprContext,
663  planstate->ps_ResultTupleSlot,
664  inputDesc);
665 }
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:1079
ExprContext * ps_ExprContext
Definition: execnodes.h:1078
List * targetlist
Definition: execnodes.h:1061
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:1077
ProjectionInfo * ExecBuildProjectionInfo(List *targetList, ExprContext *econtext, TupleTableSlot *slot, TupleDesc inputDesc)
Definition: execUtils.c:482
void ExecAssignResultType ( PlanState planstate,
TupleDesc  tupDesc 
)

Definition at line 418 of file execUtils.c.

References ExecSetSlotDescriptor(), and PlanState::ps_ResultTupleSlot.

Referenced by ExecAssignResultTypeFromTL(), and ExecInitModifyTable().

419 {
420  TupleTableSlot *slot = planstate->ps_ResultTupleSlot;
421 
422  ExecSetSlotDescriptor(slot, tupDesc);
423 }
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:1077
void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc)
Definition: execTuples.c:247
void ExecAssignResultTypeFromTL ( PlanState planstate)

Definition at line 430 of file execUtils.c.

References ExecAssignResultType(), ExecContextForcesOids(), ExecTypeFromTL(), PlanState::plan, and Plan::targetlist.

Referenced by ExecInitAgg(), ExecInitAppend(), ExecInitBitmapHeapScan(), ExecInitCteScan(), ExecInitCustomScan(), ExecInitForeignScan(), ExecInitFunctionScan(), ExecInitGather(), ExecInitGroup(), ExecInitHash(), ExecInitHashJoin(), ExecInitIndexOnlyScan(), ExecInitIndexScan(), ExecInitLimit(), ExecInitLockRows(), ExecInitMaterial(), ExecInitMergeAppend(), ExecInitMergeJoin(), ExecInitNestLoop(), ExecInitProjectSet(), ExecInitRecursiveUnion(), ExecInitResult(), ExecInitSampleScan(), ExecInitSeqScan(), ExecInitSetOp(), ExecInitSort(), ExecInitSubqueryScan(), ExecInitTidScan(), ExecInitUnique(), ExecInitValuesScan(), ExecInitWindowAgg(), and ExecInitWorkTableScan().

431 {
432  bool hasoid;
433  TupleDesc tupDesc;
434 
435  if (ExecContextForcesOids(planstate, &hasoid))
436  {
437  /* context forces OID choice; hasoid is now set correctly */
438  }
439  else
440  {
441  /* given free choice, don't leave space for OIDs in result tuples */
442  hasoid = false;
443  }
444 
445  /*
446  * ExecTypeFromTL needs the parse-time representation of the tlist, not a
447  * list of ExprStates. This is good because some plan nodes don't bother
448  * to set up planstate->targetlist ...
449  */
450  tupDesc = ExecTypeFromTL(planstate->plan->targetlist, hasoid);
451  ExecAssignResultType(planstate, tupDesc);
452 }
void ExecAssignResultType(PlanState *planstate, TupleDesc tupDesc)
Definition: execUtils.c:418
TupleDesc ExecTypeFromTL(List *targetList, bool hasoid)
Definition: execTuples.c:888
Plan * plan
Definition: execnodes.h:1047
List * targetlist
Definition: plannodes.h:129
bool ExecContextForcesOids(PlanState *planstate, bool *hasoids)
Definition: execMain.c:1406
void ExecAssignScanType ( ScanState scanstate,
TupleDesc  tupDesc 
)
void ExecAssignScanTypeFromOuterPlan ( ScanState scanstate)

Definition at line 721 of file execUtils.c.

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

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

722 {
724  TupleDesc tupDesc;
725 
726  outerPlan = outerPlanState(scanstate);
727  tupDesc = ExecGetResultType(outerPlan);
728 
729  ExecAssignScanType(scanstate, tupDesc);
730 }
#define outerPlanState(node)
Definition: execnodes.h:1090
#define outerPlan(node)
Definition: plannodes.h:159
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:459
void ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc)
Definition: execUtils.c:709
ProjectionInfo* ExecBuildProjectionInfo ( List targetList,
ExprContext econtext,
TupleTableSlot slot,
TupleDesc  inputDesc 
)

Definition at line 482 of file execUtils.c.

References GenericExprState::arg, tupleDesc::attrs, ExecTargetListLength(), ExprState::expr, get_last_attnums(), INNER_VAR, IsA, lappend(), lfirst, makeNode, tupleDesc::natts, NIL, NULL, offsetof, OUTER_VAR, palloc(), ProjectionInfo::pi_directMap, ProjectionInfo::pi_exprContext, ProjectionInfo::pi_lastInnerVar, ProjectionInfo::pi_lastOuterVar, ProjectionInfo::pi_lastScanVar, ProjectionInfo::pi_numSimpleVars, ProjectionInfo::pi_slot, ProjectionInfo::pi_targetlist, ProjectionInfo::pi_varNumbers, ProjectionInfo::pi_varOutputCols, ProjectionInfo::pi_varSlotOffsets, TargetEntry::resno, Var::varattno, Var::varno, Var::vartype, and GenericExprState::xprstate.

Referenced by ExecAssignProjectionInfo(), ExecInitAgg(), ExecInitModifyTable(), and ExecInitSubPlan().

486 {
488  int len = ExecTargetListLength(targetList);
489  int *workspace;
490  int *varSlotOffsets;
491  int *varNumbers;
492  int *varOutputCols;
493  List *exprlist;
494  int numSimpleVars;
495  bool directMap;
496  ListCell *tl;
497 
498  projInfo->pi_exprContext = econtext;
499  projInfo->pi_slot = slot;
500  /* since these are all int arrays, we need do just one palloc */
501  workspace = (int *) palloc(len * 3 * sizeof(int));
502  projInfo->pi_varSlotOffsets = varSlotOffsets = workspace;
503  projInfo->pi_varNumbers = varNumbers = workspace + len;
504  projInfo->pi_varOutputCols = varOutputCols = workspace + len * 2;
505  projInfo->pi_lastInnerVar = 0;
506  projInfo->pi_lastOuterVar = 0;
507  projInfo->pi_lastScanVar = 0;
508 
509  /*
510  * We separate the target list elements into simple Var references and
511  * expressions which require the full ExecTargetList machinery. To be a
512  * simple Var, a Var has to be a user attribute and not mismatch the
513  * inputDesc. (Note: if there is a type mismatch then ExecEvalScalarVar
514  * will probably throw an error at runtime, but we leave that to it.)
515  */
516  exprlist = NIL;
517  numSimpleVars = 0;
518  directMap = true;
519  foreach(tl, targetList)
520  {
521  GenericExprState *gstate = (GenericExprState *) lfirst(tl);
522  Var *variable = (Var *) gstate->arg->expr;
523  bool isSimpleVar = false;
524 
525  if (variable != NULL &&
526  IsA(variable, Var) &&
527  variable->varattno > 0)
528  {
529  if (!inputDesc)
530  isSimpleVar = true; /* can't check type, assume OK */
531  else if (variable->varattno <= inputDesc->natts)
532  {
533  Form_pg_attribute attr;
534 
535  attr = inputDesc->attrs[variable->varattno - 1];
536  if (!attr->attisdropped && variable->vartype == attr->atttypid)
537  isSimpleVar = true;
538  }
539  }
540 
541  if (isSimpleVar)
542  {
543  TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
544  AttrNumber attnum = variable->varattno;
545 
546  varNumbers[numSimpleVars] = attnum;
547  varOutputCols[numSimpleVars] = tle->resno;
548  if (tle->resno != numSimpleVars + 1)
549  directMap = false;
550 
551  switch (variable->varno)
552  {
553  case INNER_VAR:
554  varSlotOffsets[numSimpleVars] = offsetof(ExprContext,
555  ecxt_innertuple);
556  if (projInfo->pi_lastInnerVar < attnum)
557  projInfo->pi_lastInnerVar = attnum;
558  break;
559 
560  case OUTER_VAR:
561  varSlotOffsets[numSimpleVars] = offsetof(ExprContext,
562  ecxt_outertuple);
563  if (projInfo->pi_lastOuterVar < attnum)
564  projInfo->pi_lastOuterVar = attnum;
565  break;
566 
567  /* INDEX_VAR is handled by default case */
568 
569  default:
570  varSlotOffsets[numSimpleVars] = offsetof(ExprContext,
571  ecxt_scantuple);
572  if (projInfo->pi_lastScanVar < attnum)
573  projInfo->pi_lastScanVar = attnum;
574  break;
575  }
576  numSimpleVars++;
577  }
578  else
579  {
580  /* Not a simple variable, add it to generic targetlist */
581  exprlist = lappend(exprlist, gstate);
582  /* Examine expr to include contained Vars in lastXXXVar counts */
583  get_last_attnums((Node *) variable, projInfo);
584  }
585  }
586  projInfo->pi_targetlist = exprlist;
587  projInfo->pi_numSimpleVars = numSimpleVars;
588  projInfo->pi_directMap = directMap;
589 
590  return projInfo;
591 }
#define NIL
Definition: pg_list.h:69
#define IsA(nodeptr, _type_)
Definition: nodes.h:559
ExprState xprstate
Definition: execnodes.h:611
int ExecTargetListLength(List *targetlist)
Definition: execQual.c:5122
Form_pg_attribute * attrs
Definition: tupdesc.h:74
Definition: nodes.h:508
AttrNumber varattno
Definition: primnodes.h:146
int * pi_varSlotOffsets
Definition: execnodes.h:254
Definition: primnodes.h:141
int natts
Definition: tupdesc.h:73
int pi_lastScanVar
Definition: execnodes.h:259
List * pi_targetlist
Definition: execnodes.h:249
Expr * expr
Definition: execnodes.h:598
Oid vartype
Definition: primnodes.h:148
TupleTableSlot * pi_slot
Definition: execnodes.h:251
AttrNumber resno
Definition: primnodes.h:1331
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:184
int * pi_varNumbers
Definition: execnodes.h:255
List * lappend(List *list, void *datum)
Definition: list.c:128
Index varno
Definition: primnodes.h:144
ExprState * arg
Definition: execnodes.h:612
int * pi_varOutputCols
Definition: execnodes.h:256
static bool get_last_attnums(Node *node, ProjectionInfo *projInfo)
Definition: execUtils.c:600
#define INNER_VAR
Definition: primnodes.h:131
#define makeNode(_type_)
Definition: nodes.h:556
#define NULL
Definition: c.h:226
#define lfirst(lc)
Definition: pg_list.h:106
bool pi_directMap
Definition: execnodes.h:252
void * palloc(Size size)
Definition: mcxt.c:891
int pi_lastInnerVar
Definition: execnodes.h:257
int pi_lastOuterVar
Definition: execnodes.h:258
ExprContext * pi_exprContext
Definition: execnodes.h:250
Definition: pg_list.h:45
int16 AttrNumber
Definition: attnum.h:21
#define OUTER_VAR
Definition: primnodes.h:132
int pi_numSimpleVars
Definition: execnodes.h:253
#define offsetof(type, field)
Definition: c.h:550
void ExecCloseScanRelation ( Relation  scanrel)

Definition at line 830 of file execUtils.c.

References heap_close, and NoLock.

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

831 {
832  heap_close(scanrel, NoLock);
833 }
#define heap_close(r, l)
Definition: heapam.h:97
#define NoLock
Definition: lockdefs.h:34
void ExecFreeExprContext ( PlanState planstate)
Relation ExecOpenScanRelation ( EState estate,
Index  scanrelid,
int  eflags 
)

Definition at line 772 of file execUtils.c.

References AccessShareLock, ereport, errcode(), errhint(), errmsg(), ERROR, EState::es_range_table, EXEC_FLAG_EXPLAIN_ONLY, EXEC_FLAG_WITH_NO_DATA, ExecFindRowMark(), ExecRelationIsTargetRelation(), getrelid, heap_open(), NoLock, NULL, ExecRowMark::relation, RelationGetRelationName, and RelationIsScannable.

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

773 {
774  Relation rel;
775  Oid reloid;
776  LOCKMODE lockmode;
777 
778  /*
779  * Determine the lock type we need. First, scan to see if target relation
780  * is a result relation. If not, check if it's a FOR UPDATE/FOR SHARE
781  * relation. In either of those cases, we got the lock already.
782  */
783  lockmode = AccessShareLock;
784  if (ExecRelationIsTargetRelation(estate, scanrelid))
785  lockmode = NoLock;
786  else
787  {
788  /* Keep this check in sync with InitPlan! */
789  ExecRowMark *erm = ExecFindRowMark(estate, scanrelid, true);
790 
791  if (erm != NULL && erm->relation != NULL)
792  lockmode = NoLock;
793  }
794 
795  /* Open the relation and acquire lock as needed */
796  reloid = getrelid(scanrelid, estate->es_range_table);
797  rel = heap_open(reloid, lockmode);
798 
799  /*
800  * Complain if we're attempting a scan of an unscannable relation, except
801  * when the query won't actually be run. This is a slightly klugy place
802  * to do this, perhaps, but there is no better place.
803  */
804  if ((eflags & (EXEC_FLAG_EXPLAIN_ONLY | EXEC_FLAG_WITH_NO_DATA)) == 0 &&
805  !RelationIsScannable(rel))
806  ereport(ERROR,
807  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
808  errmsg("materialized view \"%s\" has not been populated",
810  errhint("Use the REFRESH MATERIALIZED VIEW command.")));
811 
812  return rel;
813 }
int errhint(const char *fmt,...)
Definition: elog.c:987
int LOCKMODE
Definition: lockdefs.h:26
#define RelationIsScannable(relation)
Definition: rel.h:541
Relation relation
Definition: execnodes.h:460
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:575
#define EXEC_FLAG_WITH_NO_DATA
Definition: executor.h:65
List * es_range_table
Definition: execnodes.h:372
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:43
#define NoLock
Definition: lockdefs.h:34
#define RelationGetRelationName(relation)
Definition: rel.h:433
#define ereport(elevel, rest)
Definition: elog.h:122
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define NULL
Definition: c.h:226
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define getrelid(rangeindex, rangetable)
Definition: parsetree.h:41
#define EXEC_FLAG_EXPLAIN_ONLY
Definition: executor.h:58
bool ExecRelationIsTargetRelation(EState *estate, Index scanrelid)
Definition: execUtils.c:746
ExecRowMark * ExecFindRowMark(EState *estate, Index rti, bool missing_ok)
Definition: execMain.c:2208
bool ExecRelationIsTargetRelation ( EState estate,
Index  scanrelid 
)

Definition at line 746 of file execUtils.c.

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

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

747 {
748  ResultRelInfo *resultRelInfos;
749  int i;
750 
751  resultRelInfos = estate->es_result_relations;
752  for (i = 0; i < estate->es_num_result_relations; i++)
753  {
754  if (resultRelInfos[i].ri_RangeTableIndex == scanrelid)
755  return true;
756  }
757  return false;
758 }
ResultRelInfo * es_result_relations
Definition: execnodes.h:382
int es_num_result_relations
Definition: execnodes.h:383
int i
void FreeExecutorState ( EState estate)

Definition at line 168 of file execUtils.c.

References EState::es_exprcontexts, EState::es_query_cxt, FreeExprContext(), linitial, and MemoryContextDelete().

Referenced by afterTriggerInvokeEvents(), apply_handle_delete(), apply_handle_insert(), apply_handle_update(), ATRewriteTable(), compute_index_stats(), CopyFrom(), EvalPlanQualEnd(), evaluate_expr(), ExecuteQuery(), ExecuteTruncate(), ExplainExecuteQuery(), get_actual_variable_range(), get_qual_for_range(), IndexBuildHeapRangeScan(), IndexCheckExclusion(), operator_predicate_proof(), plpgsql_inline_handler(), plpgsql_xact_cb(), standard_ExecutorEnd(), tuplesort_end(), unique_key_recheck(), validate_index_heapscan(), validateCheckConstraint(), and validateDomainConstraint().

169 {
170  /*
171  * Shut down and free any remaining ExprContexts. We do this explicitly
172  * to ensure that any remaining shutdown callbacks get called (since they
173  * might need to release resources that aren't simply memory within the
174  * per-query memory context).
175  */
176  while (estate->es_exprcontexts)
177  {
178  /*
179  * XXX: seems there ought to be a faster way to implement this than
180  * repeated list_delete(), no?
181  */
183  true);
184  /* FreeExprContext removed the list link for us */
185  }
186 
187  /*
188  * Free the per-query memory context, thereby releasing all working
189  * memory, including the EState node itself.
190  */
192 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:200
MemoryContext es_query_cxt
Definition: execnodes.h:397
#define linitial(l)
Definition: pg_list.h:110
void FreeExprContext(ExprContext *econtext, bool isCommit)
Definition: execUtils.c:339
List * es_exprcontexts
Definition: execnodes.h:410
void FreeExprContext ( ExprContext econtext,
bool  isCommit 
)

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

340 {
341  EState *estate;
342 
343  /* Call any registered callbacks */
344  ShutdownExprContext(econtext, isCommit);
345  /* And clean up the memory used */
347  /* Unlink self from owning EState, if any */
348  estate = econtext->ecxt_estate;
349  if (estate)
351  econtext);
352  /* And delete the ExprContext node */
353  pfree(econtext);
354 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:200
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:134
List * list_delete_ptr(List *list, void *datum)
Definition: list.c:590
void pfree(void *pointer)
Definition: mcxt.c:992
struct EState * ecxt_estate
Definition: execnodes.h:156
static void ShutdownExprContext(ExprContext *econtext, bool isCommit)
Definition: execUtils.c:928
List * es_exprcontexts
Definition: execnodes.h:410
static bool get_last_attnums ( Node node,
ProjectionInfo projInfo 
)
static

Definition at line 600 of file execUtils.c.

References expression_tree_walker(), INNER_VAR, IsA, NULL, OUTER_VAR, ProjectionInfo::pi_lastInnerVar, ProjectionInfo::pi_lastOuterVar, ProjectionInfo::pi_lastScanVar, Var::varattno, and Var::varno.

Referenced by ExecBuildProjectionInfo().

601 {
602  if (node == NULL)
603  return false;
604  if (IsA(node, Var))
605  {
606  Var *variable = (Var *) node;
607  AttrNumber attnum = variable->varattno;
608 
609  switch (variable->varno)
610  {
611  case INNER_VAR:
612  if (projInfo->pi_lastInnerVar < attnum)
613  projInfo->pi_lastInnerVar = attnum;
614  break;
615 
616  case OUTER_VAR:
617  if (projInfo->pi_lastOuterVar < attnum)
618  projInfo->pi_lastOuterVar = attnum;
619  break;
620 
621  /* INDEX_VAR is handled by default case */
622 
623  default:
624  if (projInfo->pi_lastScanVar < attnum)
625  projInfo->pi_lastScanVar = attnum;
626  break;
627  }
628  return false;
629  }
630 
631  /*
632  * Don't examine the arguments or filters of Aggrefs or WindowFuncs,
633  * because those do not represent expressions to be evaluated within the
634  * overall targetlist's econtext. GroupingFunc arguments are never
635  * evaluated at all.
636  */
637  if (IsA(node, Aggref))
638  return false;
639  if (IsA(node, WindowFunc))
640  return false;
641  if (IsA(node, GroupingFunc))
642  return false;
644  (void *) projInfo);
645 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:559
AttrNumber varattno
Definition: primnodes.h:146
Definition: primnodes.h:141
int pi_lastScanVar
Definition: execnodes.h:259
Index varno
Definition: primnodes.h:144
static bool get_last_attnums(Node *node, ProjectionInfo *projInfo)
Definition: execUtils.c:600
#define INNER_VAR
Definition: primnodes.h:131
#define NULL
Definition: c.h:226
bool expression_tree_walker(Node *node, bool(*walker)(), void *context)
Definition: nodeFuncs.c:1852
int pi_lastInnerVar
Definition: execnodes.h:257
int pi_lastOuterVar
Definition: execnodes.h:258
int16 AttrNumber
Definition: attnum.h:21
#define OUTER_VAR
Definition: primnodes.h:132
ExprContext* MakePerTupleExprContext ( EState estate)

Definition at line 381 of file execUtils.c.

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

382 {
383  if (estate->es_per_tuple_exprcontext == NULL)
385 
386  return estate->es_per_tuple_exprcontext;
387 }
ExprContext * es_per_tuple_exprcontext
Definition: execnodes.h:421
#define NULL
Definition: c.h:226
ExprContext * CreateExprContext(EState *estate)
Definition: execUtils.c:208
void RegisterExprContextCallback ( ExprContext econtext,
ExprContextCallbackFunction  function,
Datum  arg 
)

Definition at line 871 of file execUtils.c.

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

Referenced by AggRegisterCallback(), ExecMakeFunctionResultSet(), ExecPrepareTuplestoreResult(), fmgr_sql(), get_cached_rowtype(), and init_MultiFuncCall().

874 {
875  ExprContext_CB *ecxt_callback;
876 
877  /* Save the info in appropriate memory context */
878  ecxt_callback = (ExprContext_CB *)
880  sizeof(ExprContext_CB));
881 
882  ecxt_callback->function = function;
883  ecxt_callback->arg = arg;
884 
885  /* link to front of list for appropriate execution order */
886  ecxt_callback->next = econtext->ecxt_callbacks;
887  econtext->ecxt_callbacks = ecxt_callback;
888 }
ExprContextCallbackFunction function
Definition: execnodes.h:96
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:159
struct ExprContext_CB * next
Definition: execnodes.h:95
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:133
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:749
void * arg
void ReScanExprContext ( ExprContext econtext)

Definition at line 366 of file execUtils.c.

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

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

367 {
368  /* Call any registered callbacks */
369  ShutdownExprContext(econtext, true);
370  /* And clean up the memory used */
372 }
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:134
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:135
static void ShutdownExprContext(ExprContext *econtext, bool isCommit)
Definition: execUtils.c:928
static void ShutdownExprContext ( ExprContext econtext,
bool  isCommit 
)
static

Definition at line 928 of file execUtils.c.

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

Referenced by FreeExprContext(), and ReScanExprContext().

929 {
930  ExprContext_CB *ecxt_callback;
931  MemoryContext oldcontext;
932 
933  /* Fast path in normal case where there's nothing to do. */
934  if (econtext->ecxt_callbacks == NULL)
935  return;
936 
937  /*
938  * Call the callbacks in econtext's per-tuple context. This ensures that
939  * any memory they might leak will get cleaned up.
940  */
941  oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
942 
943  /*
944  * Call each callback function in reverse registration order.
945  */
946  while ((ecxt_callback = econtext->ecxt_callbacks) != NULL)
947  {
948  econtext->ecxt_callbacks = ecxt_callback->next;
949  if (isCommit)
950  (*ecxt_callback->function) (ecxt_callback->arg);
951  pfree(ecxt_callback);
952  }
953 
954  MemoryContextSwitchTo(oldcontext);
955 }
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:134
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void pfree(void *pointer)
Definition: mcxt.c:992
ExprContextCallbackFunction function
Definition: execnodes.h:96
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:159
struct ExprContext_CB * next
Definition: execnodes.h:95
#define NULL
Definition: c.h:226
void UnregisterExprContextCallback ( ExprContext econtext,
ExprContextCallbackFunction  function,
Datum  arg 
)

Definition at line 897 of file execUtils.c.

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

Referenced by end_MultiFuncCall(), and fmgr_sql().

900 {
901  ExprContext_CB **prev_callback;
902  ExprContext_CB *ecxt_callback;
903 
904  prev_callback = &econtext->ecxt_callbacks;
905 
906  while ((ecxt_callback = *prev_callback) != NULL)
907  {
908  if (ecxt_callback->function == function && ecxt_callback->arg == arg)
909  {
910  *prev_callback = ecxt_callback->next;
911  pfree(ecxt_callback);
912  }
913  else
914  prev_callback = &ecxt_callback->next;
915  }
916 }
void pfree(void *pointer)
Definition: mcxt.c:992
ExprContextCallbackFunction function
Definition: execnodes.h:96
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:159
struct ExprContext_CB * next
Definition: execnodes.h:95
#define NULL
Definition: c.h:226
void * arg
void UpdateChangedParamSet ( PlanState node,
Bitmapset newchg 
)

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

841 {
842  Bitmapset *parmset;
843 
844  /*
845  * The plan node only depends on params listed in its allParam set. Don't
846  * include anything else into its chgParam set.
847  */
848  parmset = bms_intersect(node->plan->allParam, newchg);
849 
850  /*
851  * Keep node->chgParam == NULL if there's not actually any members; this
852  * allows the simplest possible tests in executor node files.
853  */
854  if (!bms_is_empty(parmset))
855  node->chgParam = bms_join(node->chgParam, parmset);
856  else
857  bms_free(parmset);
858 }
Bitmapset * bms_join(Bitmapset *a, Bitmapset *b)
Definition: bitmapset.c:808
Bitmapset * allParam
Definition: plannodes.h:148
Bitmapset * chgParam
Definition: execnodes.h:1072
bool bms_is_empty(const Bitmapset *a)
Definition: bitmapset.c:633
Bitmapset * bms_intersect(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:251
Plan * plan
Definition: execnodes.h:1047
void bms_free(Bitmapset *a)
Definition: bitmapset.c:200