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