PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
execUtils.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * execUtils.c
4  * miscellaneous executor utility routines
5  *
6  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  * src/backend/executor/execUtils.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 /*
16  * INTERFACE ROUTINES
17  * CreateExecutorState Create/delete executor working state
18  * FreeExecutorState
19  * CreateExprContext
20  * CreateStandaloneExprContext
21  * FreeExprContext
22  * ReScanExprContext
23  *
24  * ExecAssignExprContext Common code for plan node init routines.
25  * ExecAssignResultType
26  * etc
27  *
28  * ExecOpenScanRelation Common code for scan node init routines.
29  * ExecCloseScanRelation
30  *
31  * RegisterExprContextCallback Register function shutdown callback
32  * UnregisterExprContextCallback Deregister function shutdown callback
33  *
34  * NOTES
35  * This file has traditionally been the place to stick misc.
36  * executor support stuff that doesn't really go anyplace else.
37  */
38 
39 #include "postgres.h"
40 
41 #include "access/relscan.h"
42 #include "access/transam.h"
43 #include "executor/executor.h"
44 #include "nodes/nodeFuncs.h"
45 #include "parser/parsetree.h"
46 #include "storage/lmgr.h"
47 #include "utils/memutils.h"
48 #include "utils/rel.h"
49 
50 
51 static bool get_last_attnums(Node *node, ProjectionInfo *projInfo);
52 static void ShutdownExprContext(ExprContext *econtext, bool isCommit);
53 
54 
55 /* ----------------------------------------------------------------
56  * Executor state and memory management functions
57  * ----------------------------------------------------------------
58  */
59 
60 /* ----------------
61  * CreateExecutorState
62  *
63  * Create and initialize an EState node, which is the root of
64  * working storage for an entire Executor invocation.
65  *
66  * Principally, this creates the per-query memory context that will be
67  * used to hold all working data that lives till the end of the query.
68  * Note that the per-query context will become a child of the caller's
69  * CurrentMemoryContext.
70  * ----------------
71  */
72 EState *
74 {
75  EState *estate;
76  MemoryContext qcontext;
77  MemoryContext oldcontext;
78 
79  /*
80  * Create the per-query context for this Executor run.
81  */
83  "ExecutorState",
85 
86  /*
87  * Make the EState node within the per-query context. This way, we don't
88  * need a separate pfree() operation for it at shutdown.
89  */
90  oldcontext = MemoryContextSwitchTo(qcontext);
91 
92  estate = makeNode(EState);
93 
94  /*
95  * Initialize all fields of the Executor State structure
96  */
98  estate->es_snapshot = InvalidSnapshot; /* caller must initialize this */
99  estate->es_crosscheck_snapshot = InvalidSnapshot; /* no crosscheck */
100  estate->es_range_table = NIL;
101  estate->es_plannedstmt = NULL;
102 
103  estate->es_junkFilter = NULL;
104 
105  estate->es_output_cid = (CommandId) 0;
106 
107  estate->es_result_relations = NULL;
108  estate->es_num_result_relations = 0;
109  estate->es_result_relation_info = NULL;
110 
111  estate->es_trig_target_relations = NIL;
112  estate->es_trig_tuple_slot = NULL;
113  estate->es_trig_oldtup_slot = NULL;
114  estate->es_trig_newtup_slot = NULL;
115 
116  estate->es_param_list_info = NULL;
117  estate->es_param_exec_vals = NULL;
118 
119  estate->es_query_cxt = qcontext;
120 
121  estate->es_tupleTable = NIL;
122 
123  estate->es_rowMarks = NIL;
124 
125  estate->es_processed = 0;
126  estate->es_lastoid = InvalidOid;
127 
128  estate->es_top_eflags = 0;
129  estate->es_instrument = 0;
130  estate->es_finished = false;
131 
132  estate->es_exprcontexts = NIL;
133 
134  estate->es_subplanstates = NIL;
135 
136  estate->es_auxmodifytables = NIL;
137 
138  estate->es_per_tuple_exprcontext = NULL;
139 
140  estate->es_epqTuple = NULL;
141  estate->es_epqTupleSet = NULL;
142  estate->es_epqScanDone = NULL;
143  estate->es_sourceText = NULL;
144 
145  /*
146  * Return the executor state structure
147  */
148  MemoryContextSwitchTo(oldcontext);
149 
150  return estate;
151 }
152 
153 /* ----------------
154  * FreeExecutorState
155  *
156  * Release an EState along with all remaining working storage.
157  *
158  * Note: this is not responsible for releasing non-memory resources,
159  * such as open relations or buffer pins. But it will shut down any
160  * still-active ExprContexts within the EState. That is sufficient
161  * cleanup for situations where the EState has only been used for expression
162  * evaluation, and not to run a complete Plan.
163  *
164  * This can be called in any memory context ... so long as it's not one
165  * of the ones to be freed.
166  * ----------------
167  */
168 void
170 {
171  /*
172  * Shut down and free any remaining ExprContexts. We do this explicitly
173  * to ensure that any remaining shutdown callbacks get called (since they
174  * might need to release resources that aren't simply memory within the
175  * per-query memory context).
176  */
177  while (estate->es_exprcontexts)
178  {
179  /*
180  * XXX: seems there ought to be a faster way to implement this than
181  * repeated list_delete(), no?
182  */
184  true);
185  /* FreeExprContext removed the list link for us */
186  }
187 
188  /*
189  * Free the per-query memory context, thereby releasing all working
190  * memory, including the EState node itself.
191  */
193 }
194 
195 /* ----------------
196  * CreateExprContext
197  *
198  * Create a context for expression evaluation within an EState.
199  *
200  * An executor run may require multiple ExprContexts (we usually make one
201  * for each Plan node, and a separate one for per-output-tuple processing
202  * such as constraint checking). Each ExprContext has its own "per-tuple"
203  * memory context.
204  *
205  * Note we make no assumption about the caller's memory context.
206  * ----------------
207  */
208 ExprContext *
210 {
211  ExprContext *econtext;
212  MemoryContext oldcontext;
213 
214  /* Create the ExprContext node within the per-query memory context */
215  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
216 
217  econtext = makeNode(ExprContext);
218 
219  /* Initialize fields of ExprContext */
220  econtext->ecxt_scantuple = NULL;
221  econtext->ecxt_innertuple = NULL;
222  econtext->ecxt_outertuple = NULL;
223 
224  econtext->ecxt_per_query_memory = estate->es_query_cxt;
225 
226  /*
227  * Create working memory for expression evaluation in this context.
228  */
229  econtext->ecxt_per_tuple_memory =
231  "ExprContext",
233 
234  econtext->ecxt_param_exec_vals = estate->es_param_exec_vals;
235  econtext->ecxt_param_list_info = estate->es_param_list_info;
236 
237  econtext->ecxt_aggvalues = NULL;
238  econtext->ecxt_aggnulls = NULL;
239 
240  econtext->caseValue_datum = (Datum) 0;
241  econtext->caseValue_isNull = true;
242 
243  econtext->domainValue_datum = (Datum) 0;
244  econtext->domainValue_isNull = true;
245 
246  econtext->ecxt_estate = estate;
247 
248  econtext->ecxt_callbacks = NULL;
249 
250  /*
251  * Link the ExprContext into the EState to ensure it is shut down when the
252  * EState is freed. Because we use lcons(), shutdowns will occur in
253  * reverse order of creation, which may not be essential but can't hurt.
254  */
255  estate->es_exprcontexts = lcons(econtext, estate->es_exprcontexts);
256 
257  MemoryContextSwitchTo(oldcontext);
258 
259  return econtext;
260 }
261 
262 /* ----------------
263  * CreateStandaloneExprContext
264  *
265  * Create a context for standalone expression evaluation.
266  *
267  * An ExprContext made this way can be used for evaluation of expressions
268  * that contain no Params, subplans, or Var references (it might work to
269  * put tuple references into the scantuple field, but it seems unwise).
270  *
271  * The ExprContext struct is allocated in the caller's current memory
272  * context, which also becomes its "per query" context.
273  *
274  * It is caller's responsibility to free the ExprContext when done,
275  * or at least ensure that any shutdown callbacks have been called
276  * (ReScanExprContext() is suitable). Otherwise, non-memory resources
277  * might be leaked.
278  * ----------------
279  */
280 ExprContext *
282 {
283  ExprContext *econtext;
284 
285  /* Create the ExprContext node within the caller's memory context */
286  econtext = makeNode(ExprContext);
287 
288  /* Initialize fields of ExprContext */
289  econtext->ecxt_scantuple = NULL;
290  econtext->ecxt_innertuple = NULL;
291  econtext->ecxt_outertuple = NULL;
292 
294 
295  /*
296  * Create working memory for expression evaluation in this context.
297  */
298  econtext->ecxt_per_tuple_memory =
300  "ExprContext",
302 
303  econtext->ecxt_param_exec_vals = NULL;
304  econtext->ecxt_param_list_info = NULL;
305 
306  econtext->ecxt_aggvalues = NULL;
307  econtext->ecxt_aggnulls = NULL;
308 
309  econtext->caseValue_datum = (Datum) 0;
310  econtext->caseValue_isNull = true;
311 
312  econtext->domainValue_datum = (Datum) 0;
313  econtext->domainValue_isNull = true;
314 
315  econtext->ecxt_estate = NULL;
316 
317  econtext->ecxt_callbacks = NULL;
318 
319  return econtext;
320 }
321 
322 /* ----------------
323  * FreeExprContext
324  *
325  * Free an expression context, including calling any remaining
326  * shutdown callbacks.
327  *
328  * Since we free the temporary context used for expression evaluation,
329  * any previously computed pass-by-reference expression result will go away!
330  *
331  * If isCommit is false, we are being called in error cleanup, and should
332  * not call callbacks but only release memory. (It might be better to call
333  * the callbacks and pass the isCommit flag to them, but that would require
334  * more invasive code changes than currently seems justified.)
335  *
336  * Note we make no assumption about the caller's memory context.
337  * ----------------
338  */
339 void
340 FreeExprContext(ExprContext *econtext, bool isCommit)
341 {
342  EState *estate;
343 
344  /* Call any registered callbacks */
345  ShutdownExprContext(econtext, isCommit);
346  /* And clean up the memory used */
348  /* Unlink self from owning EState, if any */
349  estate = econtext->ecxt_estate;
350  if (estate)
352  econtext);
353  /* And delete the ExprContext node */
354  pfree(econtext);
355 }
356 
357 /*
358  * ReScanExprContext
359  *
360  * Reset an expression context in preparation for a rescan of its
361  * plan node. This requires calling any registered shutdown callbacks,
362  * since any partially complete set-returning-functions must be canceled.
363  *
364  * Note we make no assumption about the caller's memory context.
365  */
366 void
368 {
369  /* Call any registered callbacks */
370  ShutdownExprContext(econtext, true);
371  /* And clean up the memory used */
373 }
374 
375 /*
376  * Build a per-output-tuple ExprContext for an EState.
377  *
378  * This is normally invoked via GetPerTupleExprContext() macro,
379  * not directly.
380  */
381 ExprContext *
383 {
384  if (estate->es_per_tuple_exprcontext == NULL)
386 
387  return estate->es_per_tuple_exprcontext;
388 }
389 
390 
391 /* ----------------------------------------------------------------
392  * miscellaneous node-init support functions
393  *
394  * Note: all of these are expected to be called with CurrentMemoryContext
395  * equal to the per-query memory context.
396  * ----------------------------------------------------------------
397  */
398 
399 /* ----------------
400  * ExecAssignExprContext
401  *
402  * This initializes the ps_ExprContext field. It is only necessary
403  * to do this for nodes which use ExecQual or ExecProject
404  * because those routines require an econtext. Other nodes that
405  * don't have to evaluate expressions don't need to do this.
406  * ----------------
407  */
408 void
410 {
411  planstate->ps_ExprContext = CreateExprContext(estate);
412 }
413 
414 /* ----------------
415  * ExecAssignResultType
416  * ----------------
417  */
418 void
420 {
421  TupleTableSlot *slot = planstate->ps_ResultTupleSlot;
422 
423  ExecSetSlotDescriptor(slot, tupDesc);
424 }
425 
426 /* ----------------
427  * ExecAssignResultTypeFromTL
428  * ----------------
429  */
430 void
432 {
433  bool hasoid;
434  TupleDesc tupDesc;
435 
436  if (ExecContextForcesOids(planstate, &hasoid))
437  {
438  /* context forces OID choice; hasoid is now set correctly */
439  }
440  else
441  {
442  /* given free choice, don't leave space for OIDs in result tuples */
443  hasoid = false;
444  }
445 
446  /*
447  * ExecTypeFromTL needs the parse-time representation of the tlist, not a
448  * list of ExprStates. This is good because some plan nodes don't bother
449  * to set up planstate->targetlist ...
450  */
451  tupDesc = ExecTypeFromTL(planstate->plan->targetlist, hasoid);
452  ExecAssignResultType(planstate, tupDesc);
453 }
454 
455 /* ----------------
456  * ExecGetResultType
457  * ----------------
458  */
459 TupleDesc
461 {
462  TupleTableSlot *slot = planstate->ps_ResultTupleSlot;
463 
464  return slot->tts_tupleDescriptor;
465 }
466 
467 /* ----------------
468  * ExecBuildProjectionInfo
469  *
470  * Build a ProjectionInfo node for evaluating the given tlist in the given
471  * econtext, and storing the result into the tuple slot. (Caller must have
472  * ensured that tuple slot has a descriptor matching the tlist!) Note that
473  * the given tlist should be a list of ExprState nodes, not Expr nodes.
474  *
475  * inputDesc can be NULL, but if it is not, we check to see whether simple
476  * Vars in the tlist match the descriptor. It is important to provide
477  * inputDesc for relation-scan plan nodes, as a cross check that the relation
478  * hasn't been changed since the plan was made. At higher levels of a plan,
479  * there is no need to recheck.
480  * ----------------
481  */
484  ExprContext *econtext,
485  TupleTableSlot *slot,
486  TupleDesc inputDesc)
487 {
489  int len = ExecTargetListLength(targetList);
490  int *workspace;
491  int *varSlotOffsets;
492  int *varNumbers;
493  int *varOutputCols;
494  List *exprlist;
495  int numSimpleVars;
496  bool directMap;
497  ListCell *tl;
498 
499  projInfo->pi_exprContext = econtext;
500  projInfo->pi_slot = slot;
501  /* since these are all int arrays, we need do just one palloc */
502  workspace = (int *) palloc(len * 3 * sizeof(int));
503  projInfo->pi_varSlotOffsets = varSlotOffsets = workspace;
504  projInfo->pi_varNumbers = varNumbers = workspace + len;
505  projInfo->pi_varOutputCols = varOutputCols = workspace + len * 2;
506  projInfo->pi_lastInnerVar = 0;
507  projInfo->pi_lastOuterVar = 0;
508  projInfo->pi_lastScanVar = 0;
509 
510  /*
511  * We separate the target list elements into simple Var references and
512  * expressions which require the full ExecTargetList machinery. To be a
513  * simple Var, a Var has to be a user attribute and not mismatch the
514  * inputDesc. (Note: if there is a type mismatch then ExecEvalScalarVar
515  * will probably throw an error at runtime, but we leave that to it.)
516  */
517  exprlist = NIL;
518  numSimpleVars = 0;
519  directMap = true;
520  foreach(tl, targetList)
521  {
522  GenericExprState *gstate = (GenericExprState *) lfirst(tl);
523  Var *variable = (Var *) gstate->arg->expr;
524  bool isSimpleVar = false;
525 
526  if (variable != NULL &&
527  IsA(variable, Var) &&
528  variable->varattno > 0)
529  {
530  if (!inputDesc)
531  isSimpleVar = true; /* can't check type, assume OK */
532  else if (variable->varattno <= inputDesc->natts)
533  {
534  Form_pg_attribute attr;
535 
536  attr = inputDesc->attrs[variable->varattno - 1];
537  if (!attr->attisdropped && variable->vartype == attr->atttypid)
538  isSimpleVar = true;
539  }
540  }
541 
542  if (isSimpleVar)
543  {
544  TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
545  AttrNumber attnum = variable->varattno;
546 
547  varNumbers[numSimpleVars] = attnum;
548  varOutputCols[numSimpleVars] = tle->resno;
549  if (tle->resno != numSimpleVars + 1)
550  directMap = false;
551 
552  switch (variable->varno)
553  {
554  case INNER_VAR:
555  varSlotOffsets[numSimpleVars] = offsetof(ExprContext,
556  ecxt_innertuple);
557  if (projInfo->pi_lastInnerVar < attnum)
558  projInfo->pi_lastInnerVar = attnum;
559  break;
560 
561  case OUTER_VAR:
562  varSlotOffsets[numSimpleVars] = offsetof(ExprContext,
563  ecxt_outertuple);
564  if (projInfo->pi_lastOuterVar < attnum)
565  projInfo->pi_lastOuterVar = attnum;
566  break;
567 
568  /* INDEX_VAR is handled by default case */
569 
570  default:
571  varSlotOffsets[numSimpleVars] = offsetof(ExprContext,
572  ecxt_scantuple);
573  if (projInfo->pi_lastScanVar < attnum)
574  projInfo->pi_lastScanVar = attnum;
575  break;
576  }
577  numSimpleVars++;
578  }
579  else
580  {
581  /* Not a simple variable, add it to generic targetlist */
582  exprlist = lappend(exprlist, gstate);
583  /* Examine expr to include contained Vars in lastXXXVar counts */
584  get_last_attnums((Node *) variable, projInfo);
585  }
586  }
587  projInfo->pi_targetlist = exprlist;
588  projInfo->pi_numSimpleVars = numSimpleVars;
589  projInfo->pi_directMap = directMap;
590 
591  return projInfo;
592 }
593 
594 /*
595  * get_last_attnums: expression walker for ExecBuildProjectionInfo
596  *
597  * Update the lastXXXVar counts to be at least as large as the largest
598  * attribute numbers found in the expression
599  */
600 static bool
602 {
603  if (node == NULL)
604  return false;
605  if (IsA(node, Var))
606  {
607  Var *variable = (Var *) node;
608  AttrNumber attnum = variable->varattno;
609 
610  switch (variable->varno)
611  {
612  case INNER_VAR:
613  if (projInfo->pi_lastInnerVar < attnum)
614  projInfo->pi_lastInnerVar = attnum;
615  break;
616 
617  case OUTER_VAR:
618  if (projInfo->pi_lastOuterVar < attnum)
619  projInfo->pi_lastOuterVar = attnum;
620  break;
621 
622  /* INDEX_VAR is handled by default case */
623 
624  default:
625  if (projInfo->pi_lastScanVar < attnum)
626  projInfo->pi_lastScanVar = attnum;
627  break;
628  }
629  return false;
630  }
631 
632  /*
633  * Don't examine the arguments or filters of Aggrefs or WindowFuncs,
634  * because those do not represent expressions to be evaluated within the
635  * overall targetlist's econtext. GroupingFunc arguments are never
636  * evaluated at all.
637  */
638  if (IsA(node, Aggref))
639  return false;
640  if (IsA(node, WindowFunc))
641  return false;
642  if (IsA(node, GroupingFunc))
643  return false;
645  (void *) projInfo);
646 }
647 
648 /* ----------------
649  * ExecAssignProjectionInfo
650  *
651  * forms the projection information from the node's targetlist
652  *
653  * Notes for inputDesc are same as for ExecBuildProjectionInfo: supply it
654  * for a relation-scan node, can pass NULL for upper-level nodes
655  * ----------------
656  */
657 void
659  TupleDesc inputDesc)
660 {
661  planstate->ps_ProjInfo =
663  planstate->ps_ExprContext,
664  planstate->ps_ResultTupleSlot,
665  inputDesc);
666 }
667 
668 
669 /* ----------------
670  * ExecFreeExprContext
671  *
672  * A plan node's ExprContext should be freed explicitly during executor
673  * shutdown because there may be shutdown callbacks to call. (Other resources
674  * made by the above routines, such as projection info, don't need to be freed
675  * explicitly because they're just memory in the per-query memory context.)
676  *
677  * However ... there is no particular need to do it during ExecEndNode,
678  * because FreeExecutorState will free any remaining ExprContexts within
679  * the EState. Letting FreeExecutorState do it allows the ExprContexts to
680  * be freed in reverse order of creation, rather than order of creation as
681  * will happen if we delete them here, which saves O(N^2) work in the list
682  * cleanup inside FreeExprContext.
683  * ----------------
684  */
685 void
687 {
688  /*
689  * Per above discussion, don't actually delete the ExprContext. We do
690  * unlink it from the plan node, though.
691  */
692  planstate->ps_ExprContext = NULL;
693 }
694 
695 /* ----------------------------------------------------------------
696  * the following scan type support functions are for
697  * those nodes which are stubborn and return tuples in
698  * their Scan tuple slot instead of their Result tuple
699  * slot.. luck fur us, these nodes do not do projections
700  * so we don't have to worry about getting the ProjectionInfo
701  * right for them... -cim 6/3/91
702  * ----------------------------------------------------------------
703  */
704 
705 /* ----------------
706  * ExecAssignScanType
707  * ----------------
708  */
709 void
711 {
712  TupleTableSlot *slot = scanstate->ss_ScanTupleSlot;
713 
714  ExecSetSlotDescriptor(slot, tupDesc);
715 }
716 
717 /* ----------------
718  * ExecAssignScanTypeFromOuterPlan
719  * ----------------
720  */
721 void
723 {
725  TupleDesc tupDesc;
726 
727  outerPlan = outerPlanState(scanstate);
728  tupDesc = ExecGetResultType(outerPlan);
729 
730  ExecAssignScanType(scanstate, tupDesc);
731 }
732 
733 
734 /* ----------------------------------------------------------------
735  * Scan node support
736  * ----------------------------------------------------------------
737  */
738 
739 /* ----------------------------------------------------------------
740  * ExecRelationIsTargetRelation
741  *
742  * Detect whether a relation (identified by rangetable index)
743  * is one of the target relations of the query.
744  * ----------------------------------------------------------------
745  */
746 bool
748 {
749  ResultRelInfo *resultRelInfos;
750  int i;
751 
752  resultRelInfos = estate->es_result_relations;
753  for (i = 0; i < estate->es_num_result_relations; i++)
754  {
755  if (resultRelInfos[i].ri_RangeTableIndex == scanrelid)
756  return true;
757  }
758  return false;
759 }
760 
761 /* ----------------------------------------------------------------
762  * ExecOpenScanRelation
763  *
764  * Open the heap relation to be scanned by a base-level scan plan node.
765  * This should be called during the node's ExecInit routine.
766  *
767  * By default, this acquires AccessShareLock on the relation. However,
768  * if the relation was already locked by InitPlan, we don't need to acquire
769  * any additional lock. This saves trips to the shared lock manager.
770  * ----------------------------------------------------------------
771  */
772 Relation
773 ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags)
774 {
775  Relation rel;
776  Oid reloid;
777  LOCKMODE lockmode;
778 
779  /*
780  * Determine the lock type we need. First, scan to see if target relation
781  * is a result relation. If not, check if it's a FOR UPDATE/FOR SHARE
782  * relation. In either of those cases, we got the lock already.
783  */
784  lockmode = AccessShareLock;
785  if (ExecRelationIsTargetRelation(estate, scanrelid))
786  lockmode = NoLock;
787  else
788  {
789  /* Keep this check in sync with InitPlan! */
790  ExecRowMark *erm = ExecFindRowMark(estate, scanrelid, true);
791 
792  if (erm != NULL && erm->relation != NULL)
793  lockmode = NoLock;
794  }
795 
796  /* Open the relation and acquire lock as needed */
797  reloid = getrelid(scanrelid, estate->es_range_table);
798  rel = heap_open(reloid, lockmode);
799 
800  /*
801  * Complain if we're attempting a scan of an unscannable relation, except
802  * when the query won't actually be run. This is a slightly klugy place
803  * to do this, perhaps, but there is no better place.
804  */
805  if ((eflags & (EXEC_FLAG_EXPLAIN_ONLY | EXEC_FLAG_WITH_NO_DATA)) == 0 &&
806  !RelationIsScannable(rel))
807  ereport(ERROR,
808  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
809  errmsg("materialized view \"%s\" has not been populated",
811  errhint("Use the REFRESH MATERIALIZED VIEW command.")));
812 
813  return rel;
814 }
815 
816 /* ----------------------------------------------------------------
817  * ExecCloseScanRelation
818  *
819  * Close the heap relation scanned by a base-level scan plan node.
820  * This should be called during the node's ExecEnd routine.
821  *
822  * Currently, we do not release the lock acquired by ExecOpenScanRelation.
823  * This lock should be held till end of transaction. (There is a faction
824  * that considers this too much locking, however.)
825  *
826  * If we did want to release the lock, we'd have to repeat the logic in
827  * ExecOpenScanRelation in order to figure out what to release.
828  * ----------------------------------------------------------------
829  */
830 void
832 {
833  heap_close(scanrel, NoLock);
834 }
835 
836 /*
837  * UpdateChangedParamSet
838  * Add changed parameters to a plan node's chgParam set
839  */
840 void
842 {
843  Bitmapset *parmset;
844 
845  /*
846  * The plan node only depends on params listed in its allParam set. Don't
847  * include anything else into its chgParam set.
848  */
849  parmset = bms_intersect(node->plan->allParam, newchg);
850 
851  /*
852  * Keep node->chgParam == NULL if there's not actually any members; this
853  * allows the simplest possible tests in executor node files.
854  */
855  if (!bms_is_empty(parmset))
856  node->chgParam = bms_join(node->chgParam, parmset);
857  else
858  bms_free(parmset);
859 }
860 
861 /*
862  * Register a shutdown callback in an ExprContext.
863  *
864  * Shutdown callbacks will be called (in reverse order of registration)
865  * when the ExprContext is deleted or rescanned. This provides a hook
866  * for functions called in the context to do any cleanup needed --- it's
867  * particularly useful for functions returning sets. Note that the
868  * callback will *not* be called in the event that execution is aborted
869  * by an error.
870  */
871 void
874  Datum arg)
875 {
876  ExprContext_CB *ecxt_callback;
877 
878  /* Save the info in appropriate memory context */
879  ecxt_callback = (ExprContext_CB *)
881  sizeof(ExprContext_CB));
882 
883  ecxt_callback->function = function;
884  ecxt_callback->arg = arg;
885 
886  /* link to front of list for appropriate execution order */
887  ecxt_callback->next = econtext->ecxt_callbacks;
888  econtext->ecxt_callbacks = ecxt_callback;
889 }
890 
891 /*
892  * Deregister a shutdown callback in an ExprContext.
893  *
894  * Any list entries matching the function and arg will be removed.
895  * This can be used if it's no longer necessary to call the callback.
896  */
897 void
900  Datum arg)
901 {
902  ExprContext_CB **prev_callback;
903  ExprContext_CB *ecxt_callback;
904 
905  prev_callback = &econtext->ecxt_callbacks;
906 
907  while ((ecxt_callback = *prev_callback) != NULL)
908  {
909  if (ecxt_callback->function == function && ecxt_callback->arg == arg)
910  {
911  *prev_callback = ecxt_callback->next;
912  pfree(ecxt_callback);
913  }
914  else
915  prev_callback = &ecxt_callback->next;
916  }
917 }
918 
919 /*
920  * Call all the shutdown callbacks registered in an ExprContext.
921  *
922  * The callback list is emptied (important in case this is only a rescan
923  * reset, and not deletion of the ExprContext).
924  *
925  * If isCommit is false, just clean the callback list but don't call 'em.
926  * (See comment for FreeExprContext.)
927  */
928 static void
929 ShutdownExprContext(ExprContext *econtext, bool isCommit)
930 {
931  ExprContext_CB *ecxt_callback;
932  MemoryContext oldcontext;
933 
934  /* Fast path in normal case where there's nothing to do. */
935  if (econtext->ecxt_callbacks == NULL)
936  return;
937 
938  /*
939  * Call the callbacks in econtext's per-tuple context. This ensures that
940  * any memory they might leak will get cleaned up.
941  */
942  oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
943 
944  /*
945  * Call each callback function in reverse registration order.
946  */
947  while ((ecxt_callback = econtext->ecxt_callbacks) != NULL)
948  {
949  econtext->ecxt_callbacks = ecxt_callback->next;
950  if (isCommit)
951  (*ecxt_callback->function) (ecxt_callback->arg);
952  pfree(ecxt_callback);
953  }
954 
955  MemoryContextSwitchTo(oldcontext);
956 }
957 
958 /*
959  * ExecLockNonLeafAppendTables
960  *
961  * Locks, if necessary, the tables indicated by the RT indexes contained in
962  * the partitioned_rels list. These are the non-leaf tables in the partition
963  * tree controlled by a given Append or MergeAppend node.
964  */
965 void
966 ExecLockNonLeafAppendTables(List *partitioned_rels, EState *estate)
967 {
968  PlannedStmt *stmt = estate->es_plannedstmt;
969  ListCell *lc;
970 
971  foreach(lc, partitioned_rels)
972  {
973  ListCell *l;
974  Index rti = lfirst_int(lc);
975  bool is_result_rel = false;
976  Oid relid = getrelid(rti, estate->es_range_table);
977 
978  /* If this is a result relation, already locked in InitPlan */
979  foreach(l, stmt->nonleafResultRelations)
980  {
981  if (rti == lfirst_int(l))
982  {
983  is_result_rel = true;
984  break;
985  }
986  }
987 
988  /*
989  * Not a result relation; check if there is a RowMark that requires
990  * taking a RowShareLock on this rel.
991  */
992  if (!is_result_rel)
993  {
994  PlanRowMark *rc = NULL;
995 
996  foreach(l, stmt->rowMarks)
997  {
998  if (((PlanRowMark *) lfirst(l))->rti == rti)
999  {
1000  rc = lfirst(l);
1001  break;
1002  }
1003  }
1004 
1005  if (rc && RowMarkRequiresRowShareLock(rc->markType))
1006  LockRelationOid(relid, RowShareLock);
1007  else
1009  }
1010  }
1011 }
#define NIL
Definition: pg_list.h:69
void ExecLockNonLeafAppendTables(List *partitioned_rels, EState *estate)
Definition: execUtils.c:966
uint32 CommandId
Definition: c.h:411
ExprContext * CreateStandaloneExprContext(void)
Definition: execUtils.c:281
HeapTuple * es_epqTuple
Definition: execnodes.h:434
JunkFilter * es_junkFilter
Definition: execnodes.h:378
#define IsA(nodeptr, _type_)
Definition: nodes.h:570
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:200
Datum * ecxt_aggvalues
Definition: execnodes.h:146
int errhint(const char *fmt,...)
Definition: elog.c:987
RowMarkType markType
Definition: plannodes.h:981
ExprState xprstate
Definition: execnodes.h:613
int ExecTargetListLength(List *targetlist)
Definition: execQual.c:5123
CommandId es_output_cid
Definition: execnodes.h:381
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:1081
int LOCKMODE
Definition: lockdefs.h:26
List * nonleafResultRelations
Definition: plannodes.h:69
TupleTableSlot * es_trig_newtup_slot
Definition: execnodes.h:392
Oid es_lastoid
Definition: execnodes.h:406
#define RelationIsScannable(relation)
Definition: rel.h:541
Relation relation
Definition: execnodes.h:462
void UnregisterExprContextCallback(ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
Definition: execUtils.c:898
ExprContext * ps_ExprContext
Definition: execnodes.h:1080
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:136
Form_pg_attribute * attrs
Definition: tupdesc.h:74
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define AccessShareLock
Definition: lockdefs.h:36
PlannedStmt * es_plannedstmt
Definition: execnodes.h:375
Definition: nodes.h:519
Snapshot es_crosscheck_snapshot
Definition: execnodes.h:373
int errcode(int sqlerrcode)
Definition: elog.c:575
ExprContext * es_per_tuple_exprcontext
Definition: execnodes.h:423
AttrNumber varattno
Definition: primnodes.h:168
List * targetlist
Definition: execnodes.h:1063
Snapshot es_snapshot
Definition: execnodes.h:372
#define EXEC_FLAG_WITH_NO_DATA
Definition: executor.h:65
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1293
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:135
#define heap_close(r, l)
Definition: heapam.h:97
int * pi_varSlotOffsets
Definition: execnodes.h:256
List * list_delete_ptr(List *list, void *datum)
Definition: list.c:590
List * es_range_table
Definition: execnodes.h:374
unsigned int Oid
Definition: postgres_ext.h:31
Datum domainValue_datum
Definition: execnodes.h:154
Definition: primnodes.h:163
#define RowMarkRequiresRowShareLock(marktype)
Definition: plannodes.h:934
int natts
Definition: tupdesc.h:73
void ExecFreeExprContext(PlanState *planstate)
Definition: execUtils.c:686
void ExecAssignResultType(PlanState *planstate, TupleDesc tupDesc)
Definition: execUtils.c:419
ScanDirection es_direction
Definition: execnodes.h:371
void ExecAssignResultTypeFromTL(PlanState *planstate)
Definition: execUtils.c:431
void FreeExecutorState(EState *estate)
Definition: execUtils.c:169
const char * es_sourceText
Definition: execnodes.h:376
int pi_lastScanVar
Definition: execnodes.h:261
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:1079
ParamExecData * es_param_exec_vals
Definition: execnodes.h:396
void pfree(void *pointer)
Definition: mcxt.c:950
MemoryContext es_query_cxt
Definition: execnodes.h:399
ExprContextCallbackFunction function
Definition: execnodes.h:98
List * pi_targetlist
Definition: execnodes.h:251
#define linitial(l)
Definition: pg_list.h:110
#define ERROR
Definition: elog.h:43
Expr * expr
Definition: execnodes.h:600
#define lfirst_int(lc)
Definition: pg_list.h:107
Oid vartype
Definition: primnodes.h:170
Datum caseValue_datum
Definition: execnodes.h:150
Bitmapset * bms_join(Bitmapset *a, Bitmapset *b)
Definition: bitmapset.c:808
Relation ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags)
Definition: execUtils.c:773
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:161
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:165
#define outerPlanState(node)
Definition: execnodes.h:1092
#define NoLock
Definition: lockdefs.h:34
TupleTableSlot * pi_slot
Definition: execnodes.h:253
void ExecAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc)
Definition: execUtils.c:658
ResultRelInfo * es_result_relations
Definition: execnodes.h:384
AttrNumber resno
Definition: primnodes.h:1353
ProjectionInfo * ExecBuildProjectionInfo(List *targetList, ExprContext *econtext, TupleTableSlot *slot, TupleDesc inputDesc)
Definition: execUtils.c:483
TupleTableSlot * ecxt_innertuple
Definition: execnodes.h:131
TupleTableSlot * es_trig_oldtup_slot
Definition: execnodes.h:391
ParamExecData * ecxt_param_exec_vals
Definition: execnodes.h:139
#define RelationGetRelationName(relation)
Definition: rel.h:433
struct EState * ecxt_estate
Definition: execnodes.h:158
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:184
Bitmapset * allParam
Definition: plannodes.h:151
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
int es_instrument
Definition: execnodes.h:409
TupleTableSlot * es_trig_tuple_slot
Definition: execnodes.h:390
#define ereport(elevel, rest)
Definition: elog.h:122
EState * CreateExecutorState(void)
Definition: execUtils.c:73
int * pi_varNumbers
Definition: execnodes.h:257
Bitmapset * chgParam
Definition: execnodes.h:1074
TupleDesc ExecTypeFromTL(List *targetList, bool hasoid)
Definition: execTuples.c:888
struct ExprContext_CB * next
Definition: execnodes.h:97
#define outerPlan(node)
Definition: plannodes.h:162
List * lappend(List *list, void *datum)
Definition: list.c:128
bool bms_is_empty(const Bitmapset *a)
Definition: bitmapset.c:633
static void ShutdownExprContext(ExprContext *econtext, bool isCommit)
Definition: execUtils.c:929
Index varno
Definition: primnodes.h:166
ExprState * arg
Definition: execnodes.h:614
bool domainValue_isNull
Definition: execnodes.h:155
#define InvalidSnapshot
Definition: snapshot.h:25
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:121
bool * ecxt_aggnulls
Definition: execnodes.h:147
List * es_trig_target_relations
Definition: execnodes.h:389
#define RowShareLock
Definition: lockdefs.h:37
List * es_tupleTable
Definition: execnodes.h:401
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:322
List * es_auxmodifytables
Definition: execnodes.h:416
uintptr_t Datum
Definition: postgres.h:372
void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc)
Definition: execTuples.c:247
Bitmapset * bms_intersect(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:251
void FreeExprContext(ExprContext *econtext, bool isCommit)
Definition: execUtils.c:340
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
int es_num_result_relations
Definition: execnodes.h:385
unsigned int Index
Definition: c.h:365
List * rowMarks
Definition: plannodes.h:75
Plan * plan
Definition: execnodes.h:1049
#define InvalidOid
Definition: postgres_ext.h:36
bool es_finished
Definition: execnodes.h:410
int * pi_varOutputCols
Definition: execnodes.h:258
static bool get_last_attnums(Node *node, ProjectionInfo *projInfo)
Definition: execUtils.c:601
void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
Definition: execUtils.c:841
#define INNER_VAR
Definition: primnodes.h:153
List * lcons(void *datum, List *list)
Definition: list.c:259
void bms_free(Bitmapset *a)
Definition: bitmapset.c:200
#define makeNode(_type_)
Definition: nodes.h:567
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:132
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
void RegisterExprContextCallback(ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
Definition: execUtils.c:872
uint64 es_processed
Definition: execnodes.h:405
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:409
bool expression_tree_walker(Node *node, bool(*walker)(), void *context)
Definition: nodeFuncs.c:1855
void ExecCloseScanRelation(Relation scanrel)
Definition: execUtils.c:831
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:130
void ReScanExprContext(ExprContext *econtext)
Definition: execUtils.c:367
bool * es_epqTupleSet
Definition: execnodes.h:435
List * es_subplanstates
Definition: execnodes.h:414
List * es_rowMarks
Definition: execnodes.h:403
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:135
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:460
bool pi_directMap
Definition: execnodes.h:254
List * targetlist
Definition: plannodes.h:132
bool caseValue_isNull
Definition: execnodes.h:151
void ExecAssignScanTypeFromOuterPlan(ScanState *scanstate)
Definition: execUtils.c:722
void * palloc(Size size)
Definition: mcxt.c:849
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define getrelid(rangeindex, rangetable)
Definition: parsetree.h:41
int es_top_eflags
Definition: execnodes.h:408
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:707
ExprContext * MakePerTupleExprContext(EState *estate)
Definition: execUtils.c:382
int i
bool * es_epqScanDone
Definition: execnodes.h:436
int pi_lastInnerVar
Definition: execnodes.h:259
ExprContext * CreateExprContext(EState *estate)
Definition: execUtils.c:209
void ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc)
Definition: execUtils.c:710
void * arg
ParamListInfo es_param_list_info
Definition: execnodes.h:395
List * es_exprcontexts
Definition: execnodes.h:412
int pi_lastOuterVar
Definition: execnodes.h:260
bool ExecContextForcesOids(PlanState *planstate, bool *hasoids)
Definition: execMain.c:1440
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:105
void(* ExprContextCallbackFunction)(Datum arg)
Definition: execnodes.h:93
ParamListInfo ecxt_param_list_info
Definition: execnodes.h:140
ExprContext * pi_exprContext
Definition: execnodes.h:252
Definition: pg_list.h:45
#define EXEC_FLAG_EXPLAIN_ONLY
Definition: executor.h:58
int16 AttrNumber
Definition: attnum.h:21
#define OUTER_VAR
Definition: primnodes.h:154
int pi_numSimpleVars
Definition: execnodes.h:255
bool ExecRelationIsTargetRelation(EState *estate, Index scanrelid)
Definition: execUtils.c:747
#define offsetof(type, field)
Definition: c.h:555
ExecRowMark * ExecFindRowMark(EState *estate, Index rti, bool missing_ok)
Definition: execMain.c:2247
ResultRelInfo * es_result_relation_info
Definition: execnodes.h:386