PostgreSQL Source Code  git master
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-2018, 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  * executor_errposition Report syntactic position of an error.
32  *
33  * RegisterExprContextCallback Register function shutdown callback
34  * UnregisterExprContextCallback Deregister function shutdown callback
35  *
36  * GetAttributeByName Runtime extraction of columns from tuples.
37  * GetAttributeByNum
38  *
39  * NOTES
40  * This file has traditionally been the place to stick misc.
41  * executor support stuff that doesn't really go anyplace else.
42  */
43 
44 #include "postgres.h"
45 
46 #include "access/relscan.h"
47 #include "access/transam.h"
48 #include "executor/executor.h"
49 #include "mb/pg_wchar.h"
50 #include "nodes/nodeFuncs.h"
51 #include "parser/parsetree.h"
52 #include "storage/lmgr.h"
53 #include "utils/builtins.h"
54 #include "utils/memutils.h"
55 #include "utils/rel.h"
56 #include "utils/typcache.h"
57 
58 
59 static bool tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc);
60 static void ShutdownExprContext(ExprContext *econtext, bool isCommit);
61 
62 
63 /* ----------------------------------------------------------------
64  * Executor state and memory management functions
65  * ----------------------------------------------------------------
66  */
67 
68 /* ----------------
69  * CreateExecutorState
70  *
71  * Create and initialize an EState node, which is the root of
72  * working storage for an entire Executor invocation.
73  *
74  * Principally, this creates the per-query memory context that will be
75  * used to hold all working data that lives till the end of the query.
76  * Note that the per-query context will become a child of the caller's
77  * CurrentMemoryContext.
78  * ----------------
79  */
80 EState *
82 {
83  EState *estate;
84  MemoryContext qcontext;
85  MemoryContext oldcontext;
86 
87  /*
88  * Create the per-query context for this Executor run.
89  */
91  "ExecutorState",
93 
94  /*
95  * Make the EState node within the per-query context. This way, we don't
96  * need a separate pfree() operation for it at shutdown.
97  */
98  oldcontext = MemoryContextSwitchTo(qcontext);
99 
100  estate = makeNode(EState);
101 
102  /*
103  * Initialize all fields of the Executor State structure
104  */
106  estate->es_snapshot = InvalidSnapshot; /* caller must initialize this */
107  estate->es_crosscheck_snapshot = InvalidSnapshot; /* no crosscheck */
108  estate->es_range_table = NIL;
109  estate->es_plannedstmt = NULL;
110 
111  estate->es_junkFilter = NULL;
112 
113  estate->es_output_cid = (CommandId) 0;
114 
115  estate->es_result_relations = NULL;
116  estate->es_num_result_relations = 0;
117  estate->es_result_relation_info = NULL;
118 
119  estate->es_root_result_relations = NULL;
120  estate->es_num_root_result_relations = 0;
121 
122  estate->es_leaf_result_relations = NIL;
123 
124  estate->es_trig_target_relations = NIL;
125  estate->es_trig_tuple_slot = NULL;
126  estate->es_trig_oldtup_slot = NULL;
127  estate->es_trig_newtup_slot = NULL;
128 
129  estate->es_param_list_info = NULL;
130  estate->es_param_exec_vals = NULL;
131 
132  estate->es_queryEnv = NULL;
133 
134  estate->es_query_cxt = qcontext;
135 
136  estate->es_tupleTable = NIL;
137 
138  estate->es_rowMarks = NIL;
139 
140  estate->es_processed = 0;
141  estate->es_lastoid = InvalidOid;
142 
143  estate->es_top_eflags = 0;
144  estate->es_instrument = 0;
145  estate->es_finished = false;
146 
147  estate->es_exprcontexts = NIL;
148 
149  estate->es_subplanstates = NIL;
150 
151  estate->es_auxmodifytables = NIL;
152 
153  estate->es_per_tuple_exprcontext = NULL;
154 
155  estate->es_epqTuple = NULL;
156  estate->es_epqTupleSet = NULL;
157  estate->es_epqScanDone = NULL;
158  estate->es_sourceText = NULL;
159 
160  estate->es_use_parallel_mode = false;
161 
162  /*
163  * Return the executor state structure
164  */
165  MemoryContextSwitchTo(oldcontext);
166 
167  return estate;
168 }
169 
170 /* ----------------
171  * FreeExecutorState
172  *
173  * Release an EState along with all remaining working storage.
174  *
175  * Note: this is not responsible for releasing non-memory resources,
176  * such as open relations or buffer pins. But it will shut down any
177  * still-active ExprContexts within the EState. That is sufficient
178  * cleanup for situations where the EState has only been used for expression
179  * evaluation, and not to run a complete Plan.
180  *
181  * This can be called in any memory context ... so long as it's not one
182  * of the ones to be freed.
183  * ----------------
184  */
185 void
187 {
188  /*
189  * Shut down and free any remaining ExprContexts. We do this explicitly
190  * to ensure that any remaining shutdown callbacks get called (since they
191  * might need to release resources that aren't simply memory within the
192  * per-query memory context).
193  */
194  while (estate->es_exprcontexts)
195  {
196  /*
197  * XXX: seems there ought to be a faster way to implement this than
198  * repeated list_delete(), no?
199  */
201  true);
202  /* FreeExprContext removed the list link for us */
203  }
204 
205  /*
206  * Free the per-query memory context, thereby releasing all working
207  * memory, including the EState node itself.
208  */
210 }
211 
212 /* ----------------
213  * CreateExprContext
214  *
215  * Create a context for expression evaluation within an EState.
216  *
217  * An executor run may require multiple ExprContexts (we usually make one
218  * for each Plan node, and a separate one for per-output-tuple processing
219  * such as constraint checking). Each ExprContext has its own "per-tuple"
220  * memory context.
221  *
222  * Note we make no assumption about the caller's memory context.
223  * ----------------
224  */
225 ExprContext *
227 {
228  ExprContext *econtext;
229  MemoryContext oldcontext;
230 
231  /* Create the ExprContext node within the per-query memory context */
232  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
233 
234  econtext = makeNode(ExprContext);
235 
236  /* Initialize fields of ExprContext */
237  econtext->ecxt_scantuple = NULL;
238  econtext->ecxt_innertuple = NULL;
239  econtext->ecxt_outertuple = NULL;
240 
241  econtext->ecxt_per_query_memory = estate->es_query_cxt;
242 
243  /*
244  * Create working memory for expression evaluation in this context.
245  */
246  econtext->ecxt_per_tuple_memory =
248  "ExprContext",
250 
251  econtext->ecxt_param_exec_vals = estate->es_param_exec_vals;
252  econtext->ecxt_param_list_info = estate->es_param_list_info;
253 
254  econtext->ecxt_aggvalues = NULL;
255  econtext->ecxt_aggnulls = NULL;
256 
257  econtext->caseValue_datum = (Datum) 0;
258  econtext->caseValue_isNull = true;
259 
260  econtext->domainValue_datum = (Datum) 0;
261  econtext->domainValue_isNull = true;
262 
263  econtext->ecxt_estate = estate;
264 
265  econtext->ecxt_callbacks = NULL;
266 
267  /*
268  * Link the ExprContext into the EState to ensure it is shut down when the
269  * EState is freed. Because we use lcons(), shutdowns will occur in
270  * reverse order of creation, which may not be essential but can't hurt.
271  */
272  estate->es_exprcontexts = lcons(econtext, estate->es_exprcontexts);
273 
274  MemoryContextSwitchTo(oldcontext);
275 
276  return econtext;
277 }
278 
279 /* ----------------
280  * CreateStandaloneExprContext
281  *
282  * Create a context for standalone expression evaluation.
283  *
284  * An ExprContext made this way can be used for evaluation of expressions
285  * that contain no Params, subplans, or Var references (it might work to
286  * put tuple references into the scantuple field, but it seems unwise).
287  *
288  * The ExprContext struct is allocated in the caller's current memory
289  * context, which also becomes its "per query" context.
290  *
291  * It is caller's responsibility to free the ExprContext when done,
292  * or at least ensure that any shutdown callbacks have been called
293  * (ReScanExprContext() is suitable). Otherwise, non-memory resources
294  * might be leaked.
295  * ----------------
296  */
297 ExprContext *
299 {
300  ExprContext *econtext;
301 
302  /* Create the ExprContext node within the caller's memory context */
303  econtext = makeNode(ExprContext);
304 
305  /* Initialize fields of ExprContext */
306  econtext->ecxt_scantuple = NULL;
307  econtext->ecxt_innertuple = NULL;
308  econtext->ecxt_outertuple = NULL;
309 
311 
312  /*
313  * Create working memory for expression evaluation in this context.
314  */
315  econtext->ecxt_per_tuple_memory =
317  "ExprContext",
319 
320  econtext->ecxt_param_exec_vals = NULL;
321  econtext->ecxt_param_list_info = NULL;
322 
323  econtext->ecxt_aggvalues = NULL;
324  econtext->ecxt_aggnulls = NULL;
325 
326  econtext->caseValue_datum = (Datum) 0;
327  econtext->caseValue_isNull = true;
328 
329  econtext->domainValue_datum = (Datum) 0;
330  econtext->domainValue_isNull = true;
331 
332  econtext->ecxt_estate = NULL;
333 
334  econtext->ecxt_callbacks = NULL;
335 
336  return econtext;
337 }
338 
339 /* ----------------
340  * FreeExprContext
341  *
342  * Free an expression context, including calling any remaining
343  * shutdown callbacks.
344  *
345  * Since we free the temporary context used for expression evaluation,
346  * any previously computed pass-by-reference expression result will go away!
347  *
348  * If isCommit is false, we are being called in error cleanup, and should
349  * not call callbacks but only release memory. (It might be better to call
350  * the callbacks and pass the isCommit flag to them, but that would require
351  * more invasive code changes than currently seems justified.)
352  *
353  * Note we make no assumption about the caller's memory context.
354  * ----------------
355  */
356 void
357 FreeExprContext(ExprContext *econtext, bool isCommit)
358 {
359  EState *estate;
360 
361  /* Call any registered callbacks */
362  ShutdownExprContext(econtext, isCommit);
363  /* And clean up the memory used */
365  /* Unlink self from owning EState, if any */
366  estate = econtext->ecxt_estate;
367  if (estate)
369  econtext);
370  /* And delete the ExprContext node */
371  pfree(econtext);
372 }
373 
374 /*
375  * ReScanExprContext
376  *
377  * Reset an expression context in preparation for a rescan of its
378  * plan node. This requires calling any registered shutdown callbacks,
379  * since any partially complete set-returning-functions must be canceled.
380  *
381  * Note we make no assumption about the caller's memory context.
382  */
383 void
385 {
386  /* Call any registered callbacks */
387  ShutdownExprContext(econtext, true);
388  /* And clean up the memory used */
390 }
391 
392 /*
393  * Build a per-output-tuple ExprContext for an EState.
394  *
395  * This is normally invoked via GetPerTupleExprContext() macro,
396  * not directly.
397  */
398 ExprContext *
400 {
401  if (estate->es_per_tuple_exprcontext == NULL)
403 
404  return estate->es_per_tuple_exprcontext;
405 }
406 
407 
408 /* ----------------------------------------------------------------
409  * miscellaneous node-init support functions
410  *
411  * Note: all of these are expected to be called with CurrentMemoryContext
412  * equal to the per-query memory context.
413  * ----------------------------------------------------------------
414  */
415 
416 /* ----------------
417  * ExecAssignExprContext
418  *
419  * This initializes the ps_ExprContext field. It is only necessary
420  * to do this for nodes which use ExecQual or ExecProject
421  * because those routines require an econtext. Other nodes that
422  * don't have to evaluate expressions don't need to do this.
423  * ----------------
424  */
425 void
427 {
428  planstate->ps_ExprContext = CreateExprContext(estate);
429 }
430 
431 /* ----------------
432  * ExecAssignResultType
433  * ----------------
434  */
435 void
437 {
438  TupleTableSlot *slot = planstate->ps_ResultTupleSlot;
439 
440  ExecSetSlotDescriptor(slot, tupDesc);
441 }
442 
443 /* ----------------
444  * ExecAssignResultTypeFromTL
445  * ----------------
446  */
447 void
449 {
450  bool hasoid;
451  TupleDesc tupDesc;
452 
453  if (ExecContextForcesOids(planstate, &hasoid))
454  {
455  /* context forces OID choice; hasoid is now set correctly */
456  }
457  else
458  {
459  /* given free choice, don't leave space for OIDs in result tuples */
460  hasoid = false;
461  }
462 
463  /*
464  * ExecTypeFromTL needs the parse-time representation of the tlist, not a
465  * list of ExprStates. This is good because some plan nodes don't bother
466  * to set up planstate->targetlist ...
467  */
468  tupDesc = ExecTypeFromTL(planstate->plan->targetlist, hasoid);
469  ExecAssignResultType(planstate, tupDesc);
470 }
471 
472 /* ----------------
473  * ExecGetResultType
474  * ----------------
475  */
476 TupleDesc
478 {
479  TupleTableSlot *slot = planstate->ps_ResultTupleSlot;
480 
481  return slot->tts_tupleDescriptor;
482 }
483 
484 
485 /* ----------------
486  * ExecAssignProjectionInfo
487  *
488  * forms the projection information from the node's targetlist
489  *
490  * Notes for inputDesc are same as for ExecBuildProjectionInfo: supply it
491  * for a relation-scan node, can pass NULL for upper-level nodes
492  * ----------------
493  */
494 void
496  TupleDesc inputDesc)
497 {
498  planstate->ps_ProjInfo =
500  planstate->ps_ExprContext,
501  planstate->ps_ResultTupleSlot,
502  planstate,
503  inputDesc);
504 }
505 
506 
507 /* ----------------
508  * ExecConditionalAssignProjectionInfo
509  *
510  * as ExecAssignProjectionInfo, but store NULL rather than building projection
511  * info if no projection is required
512  * ----------------
513  */
514 void
516  Index varno)
517 {
518  if (tlist_matches_tupdesc(planstate,
519  planstate->plan->targetlist,
520  varno,
521  inputDesc))
522  planstate->ps_ProjInfo = NULL;
523  else
524  ExecAssignProjectionInfo(planstate, inputDesc);
525 }
526 
527 static bool
528 tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc)
529 {
530  int numattrs = tupdesc->natts;
531  int attrno;
532  bool hasoid;
533  ListCell *tlist_item = list_head(tlist);
534 
535  /* Check the tlist attributes */
536  for (attrno = 1; attrno <= numattrs; attrno++)
537  {
538  Form_pg_attribute att_tup = TupleDescAttr(tupdesc, attrno - 1);
539  Var *var;
540 
541  if (tlist_item == NULL)
542  return false; /* tlist too short */
543  var = (Var *) ((TargetEntry *) lfirst(tlist_item))->expr;
544  if (!var || !IsA(var, Var))
545  return false; /* tlist item not a Var */
546  /* if these Asserts fail, planner messed up */
547  Assert(var->varno == varno);
548  Assert(var->varlevelsup == 0);
549  if (var->varattno != attrno)
550  return false; /* out of order */
551  if (att_tup->attisdropped)
552  return false; /* table contains dropped columns */
553 
554  /*
555  * Note: usually the Var's type should match the tupdesc exactly, but
556  * in situations involving unions of columns that have different
557  * typmods, the Var may have come from above the union and hence have
558  * typmod -1. This is a legitimate situation since the Var still
559  * describes the column, just not as exactly as the tupdesc does. We
560  * could change the planner to prevent it, but it'd then insert
561  * projection steps just to convert from specific typmod to typmod -1,
562  * which is pretty silly.
563  */
564  if (var->vartype != att_tup->atttypid ||
565  (var->vartypmod != att_tup->atttypmod &&
566  var->vartypmod != -1))
567  return false; /* type mismatch */
568 
569  tlist_item = lnext(tlist_item);
570  }
571 
572  if (tlist_item)
573  return false; /* tlist too long */
574 
575  /*
576  * If the plan context requires a particular hasoid setting, then that has
577  * to match, too.
578  */
579  if (ExecContextForcesOids(ps, &hasoid) &&
580  hasoid != tupdesc->tdhasoid)
581  return false;
582 
583  return true;
584 }
585 
586 /* ----------------
587  * ExecFreeExprContext
588  *
589  * A plan node's ExprContext should be freed explicitly during executor
590  * shutdown because there may be shutdown callbacks to call. (Other resources
591  * made by the above routines, such as projection info, don't need to be freed
592  * explicitly because they're just memory in the per-query memory context.)
593  *
594  * However ... there is no particular need to do it during ExecEndNode,
595  * because FreeExecutorState will free any remaining ExprContexts within
596  * the EState. Letting FreeExecutorState do it allows the ExprContexts to
597  * be freed in reverse order of creation, rather than order of creation as
598  * will happen if we delete them here, which saves O(N^2) work in the list
599  * cleanup inside FreeExprContext.
600  * ----------------
601  */
602 void
604 {
605  /*
606  * Per above discussion, don't actually delete the ExprContext. We do
607  * unlink it from the plan node, though.
608  */
609  planstate->ps_ExprContext = NULL;
610 }
611 
612 /* ----------------------------------------------------------------
613  * the following scan type support functions are for
614  * those nodes which are stubborn and return tuples in
615  * their Scan tuple slot instead of their Result tuple
616  * slot.. luck fur us, these nodes do not do projections
617  * so we don't have to worry about getting the ProjectionInfo
618  * right for them... -cim 6/3/91
619  * ----------------------------------------------------------------
620  */
621 
622 /* ----------------
623  * ExecAssignScanType
624  * ----------------
625  */
626 void
628 {
629  TupleTableSlot *slot = scanstate->ss_ScanTupleSlot;
630 
631  ExecSetSlotDescriptor(slot, tupDesc);
632 }
633 
634 /* ----------------
635  * ExecAssignScanTypeFromOuterPlan
636  * ----------------
637  */
638 void
640 {
642  TupleDesc tupDesc;
643 
644  outerPlan = outerPlanState(scanstate);
645  tupDesc = ExecGetResultType(outerPlan);
646 
647  ExecAssignScanType(scanstate, tupDesc);
648 }
649 
650 
651 /* ----------------------------------------------------------------
652  * Scan node support
653  * ----------------------------------------------------------------
654  */
655 
656 /* ----------------------------------------------------------------
657  * ExecRelationIsTargetRelation
658  *
659  * Detect whether a relation (identified by rangetable index)
660  * is one of the target relations of the query.
661  * ----------------------------------------------------------------
662  */
663 bool
665 {
666  ResultRelInfo *resultRelInfos;
667  int i;
668 
669  resultRelInfos = estate->es_result_relations;
670  for (i = 0; i < estate->es_num_result_relations; i++)
671  {
672  if (resultRelInfos[i].ri_RangeTableIndex == scanrelid)
673  return true;
674  }
675  return false;
676 }
677 
678 /* ----------------------------------------------------------------
679  * ExecOpenScanRelation
680  *
681  * Open the heap relation to be scanned by a base-level scan plan node.
682  * This should be called during the node's ExecInit routine.
683  *
684  * By default, this acquires AccessShareLock on the relation. However,
685  * if the relation was already locked by InitPlan, we don't need to acquire
686  * any additional lock. This saves trips to the shared lock manager.
687  * ----------------------------------------------------------------
688  */
689 Relation
690 ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags)
691 {
692  Relation rel;
693  Oid reloid;
694  LOCKMODE lockmode;
695 
696  /*
697  * Determine the lock type we need. First, scan to see if target relation
698  * is a result relation. If not, check if it's a FOR UPDATE/FOR SHARE
699  * relation. In either of those cases, we got the lock already.
700  */
701  lockmode = AccessShareLock;
702  if (ExecRelationIsTargetRelation(estate, scanrelid))
703  lockmode = NoLock;
704  else
705  {
706  /* Keep this check in sync with InitPlan! */
707  ExecRowMark *erm = ExecFindRowMark(estate, scanrelid, true);
708 
709  if (erm != NULL && erm->relation != NULL)
710  lockmode = NoLock;
711  }
712 
713  /* Open the relation and acquire lock as needed */
714  reloid = getrelid(scanrelid, estate->es_range_table);
715  rel = heap_open(reloid, lockmode);
716 
717  /*
718  * Complain if we're attempting a scan of an unscannable relation, except
719  * when the query won't actually be run. This is a slightly klugy place
720  * to do this, perhaps, but there is no better place.
721  */
722  if ((eflags & (EXEC_FLAG_EXPLAIN_ONLY | EXEC_FLAG_WITH_NO_DATA)) == 0 &&
723  !RelationIsScannable(rel))
724  ereport(ERROR,
725  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
726  errmsg("materialized view \"%s\" has not been populated",
728  errhint("Use the REFRESH MATERIALIZED VIEW command.")));
729 
730  return rel;
731 }
732 
733 /* ----------------------------------------------------------------
734  * ExecCloseScanRelation
735  *
736  * Close the heap relation scanned by a base-level scan plan node.
737  * This should be called during the node's ExecEnd routine.
738  *
739  * Currently, we do not release the lock acquired by ExecOpenScanRelation.
740  * This lock should be held till end of transaction. (There is a faction
741  * that considers this too much locking, however.)
742  *
743  * If we did want to release the lock, we'd have to repeat the logic in
744  * ExecOpenScanRelation in order to figure out what to release.
745  * ----------------------------------------------------------------
746  */
747 void
749 {
750  heap_close(scanrel, NoLock);
751 }
752 
753 /*
754  * UpdateChangedParamSet
755  * Add changed parameters to a plan node's chgParam set
756  */
757 void
759 {
760  Bitmapset *parmset;
761 
762  /*
763  * The plan node only depends on params listed in its allParam set. Don't
764  * include anything else into its chgParam set.
765  */
766  parmset = bms_intersect(node->plan->allParam, newchg);
767 
768  /*
769  * Keep node->chgParam == NULL if there's not actually any members; this
770  * allows the simplest possible tests in executor node files.
771  */
772  if (!bms_is_empty(parmset))
773  node->chgParam = bms_join(node->chgParam, parmset);
774  else
775  bms_free(parmset);
776 }
777 
778 /*
779  * executor_errposition
780  * Report an execution-time cursor position, if possible.
781  *
782  * This is expected to be used within an ereport() call. The return value
783  * is a dummy (always 0, in fact).
784  *
785  * The locations stored in parsetrees are byte offsets into the source string.
786  * We have to convert them to 1-based character indexes for reporting to
787  * clients. (We do things this way to avoid unnecessary overhead in the
788  * normal non-error case: computing character indexes would be much more
789  * expensive than storing token offsets.)
790  */
791 int
792 executor_errposition(EState *estate, int location)
793 {
794  int pos;
795 
796  /* No-op if location was not provided */
797  if (location < 0)
798  return 0;
799  /* Can't do anything if source text is not available */
800  if (estate == NULL || estate->es_sourceText == NULL)
801  return 0;
802  /* Convert offset to character number */
803  pos = pg_mbstrlen_with_len(estate->es_sourceText, location) + 1;
804  /* And pass it to the ereport mechanism */
805  return errposition(pos);
806 }
807 
808 /*
809  * Register a shutdown callback in an ExprContext.
810  *
811  * Shutdown callbacks will be called (in reverse order of registration)
812  * when the ExprContext is deleted or rescanned. This provides a hook
813  * for functions called in the context to do any cleanup needed --- it's
814  * particularly useful for functions returning sets. Note that the
815  * callback will *not* be called in the event that execution is aborted
816  * by an error.
817  */
818 void
821  Datum arg)
822 {
823  ExprContext_CB *ecxt_callback;
824 
825  /* Save the info in appropriate memory context */
826  ecxt_callback = (ExprContext_CB *)
828  sizeof(ExprContext_CB));
829 
830  ecxt_callback->function = function;
831  ecxt_callback->arg = arg;
832 
833  /* link to front of list for appropriate execution order */
834  ecxt_callback->next = econtext->ecxt_callbacks;
835  econtext->ecxt_callbacks = ecxt_callback;
836 }
837 
838 /*
839  * Deregister a shutdown callback in an ExprContext.
840  *
841  * Any list entries matching the function and arg will be removed.
842  * This can be used if it's no longer necessary to call the callback.
843  */
844 void
847  Datum arg)
848 {
849  ExprContext_CB **prev_callback;
850  ExprContext_CB *ecxt_callback;
851 
852  prev_callback = &econtext->ecxt_callbacks;
853 
854  while ((ecxt_callback = *prev_callback) != NULL)
855  {
856  if (ecxt_callback->function == function && ecxt_callback->arg == arg)
857  {
858  *prev_callback = ecxt_callback->next;
859  pfree(ecxt_callback);
860  }
861  else
862  prev_callback = &ecxt_callback->next;
863  }
864 }
865 
866 /*
867  * Call all the shutdown callbacks registered in an ExprContext.
868  *
869  * The callback list is emptied (important in case this is only a rescan
870  * reset, and not deletion of the ExprContext).
871  *
872  * If isCommit is false, just clean the callback list but don't call 'em.
873  * (See comment for FreeExprContext.)
874  */
875 static void
876 ShutdownExprContext(ExprContext *econtext, bool isCommit)
877 {
878  ExprContext_CB *ecxt_callback;
879  MemoryContext oldcontext;
880 
881  /* Fast path in normal case where there's nothing to do. */
882  if (econtext->ecxt_callbacks == NULL)
883  return;
884 
885  /*
886  * Call the callbacks in econtext's per-tuple context. This ensures that
887  * any memory they might leak will get cleaned up.
888  */
889  oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
890 
891  /*
892  * Call each callback function in reverse registration order.
893  */
894  while ((ecxt_callback = econtext->ecxt_callbacks) != NULL)
895  {
896  econtext->ecxt_callbacks = ecxt_callback->next;
897  if (isCommit)
898  ecxt_callback->function(ecxt_callback->arg);
899  pfree(ecxt_callback);
900  }
901 
902  MemoryContextSwitchTo(oldcontext);
903 }
904 
905 /*
906  * ExecLockNonLeafAppendTables
907  *
908  * Locks, if necessary, the tables indicated by the RT indexes contained in
909  * the partitioned_rels list. These are the non-leaf tables in the partition
910  * tree controlled by a given Append or MergeAppend node.
911  */
912 void
913 ExecLockNonLeafAppendTables(List *partitioned_rels, EState *estate)
914 {
915  PlannedStmt *stmt = estate->es_plannedstmt;
916  ListCell *lc;
917 
918  foreach(lc, partitioned_rels)
919  {
920  ListCell *l;
921  Index rti = lfirst_int(lc);
922  bool is_result_rel = false;
923  Oid relid = getrelid(rti, estate->es_range_table);
924 
925  /* If this is a result relation, already locked in InitPlan */
926  foreach(l, stmt->nonleafResultRelations)
927  {
928  if (rti == lfirst_int(l))
929  {
930  is_result_rel = true;
931  break;
932  }
933  }
934 
935  /*
936  * Not a result relation; check if there is a RowMark that requires
937  * taking a RowShareLock on this rel.
938  */
939  if (!is_result_rel)
940  {
941  PlanRowMark *rc = NULL;
942 
943  foreach(l, stmt->rowMarks)
944  {
945  if (((PlanRowMark *) lfirst(l))->rti == rti)
946  {
947  rc = lfirst(l);
948  break;
949  }
950  }
951 
952  if (rc && RowMarkRequiresRowShareLock(rc->markType))
954  else
956  }
957  }
958 }
959 
960 /*
961  * GetAttributeByName
962  * GetAttributeByNum
963  *
964  * These functions return the value of the requested attribute
965  * out of the given tuple Datum.
966  * C functions which take a tuple as an argument are expected
967  * to use these. Ex: overpaid(EMP) might call GetAttributeByNum().
968  * Note: these are actually rather slow because they do a typcache
969  * lookup on each call.
970  */
971 Datum
972 GetAttributeByName(HeapTupleHeader tuple, const char *attname, bool *isNull)
973 {
974  AttrNumber attrno;
975  Datum result;
976  Oid tupType;
977  int32 tupTypmod;
978  TupleDesc tupDesc;
979  HeapTupleData tmptup;
980  int i;
981 
982  if (attname == NULL)
983  elog(ERROR, "invalid attribute name");
984 
985  if (isNull == NULL)
986  elog(ERROR, "a NULL isNull pointer was passed");
987 
988  if (tuple == NULL)
989  {
990  /* Kinda bogus but compatible with old behavior... */
991  *isNull = true;
992  return (Datum) 0;
993  }
994 
995  tupType = HeapTupleHeaderGetTypeId(tuple);
996  tupTypmod = HeapTupleHeaderGetTypMod(tuple);
997  tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
998 
999  attrno = InvalidAttrNumber;
1000  for (i = 0; i < tupDesc->natts; i++)
1001  {
1002  Form_pg_attribute att = TupleDescAttr(tupDesc, i);
1003 
1004  if (namestrcmp(&(att->attname), attname) == 0)
1005  {
1006  attrno = att->attnum;
1007  break;
1008  }
1009  }
1010 
1011  if (attrno == InvalidAttrNumber)
1012  elog(ERROR, "attribute \"%s\" does not exist", attname);
1013 
1014  /*
1015  * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
1016  * the fields in the struct just in case user tries to inspect system
1017  * columns.
1018  */
1019  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
1020  ItemPointerSetInvalid(&(tmptup.t_self));
1021  tmptup.t_tableOid = InvalidOid;
1022  tmptup.t_data = tuple;
1023 
1024  result = heap_getattr(&tmptup,
1025  attrno,
1026  tupDesc,
1027  isNull);
1028 
1029  ReleaseTupleDesc(tupDesc);
1030 
1031  return result;
1032 }
1033 
1034 Datum
1036  AttrNumber attrno,
1037  bool *isNull)
1038 {
1039  Datum result;
1040  Oid tupType;
1041  int32 tupTypmod;
1042  TupleDesc tupDesc;
1043  HeapTupleData tmptup;
1044 
1045  if (!AttributeNumberIsValid(attrno))
1046  elog(ERROR, "invalid attribute number %d", attrno);
1047 
1048  if (isNull == NULL)
1049  elog(ERROR, "a NULL isNull pointer was passed");
1050 
1051  if (tuple == NULL)
1052  {
1053  /* Kinda bogus but compatible with old behavior... */
1054  *isNull = true;
1055  return (Datum) 0;
1056  }
1057 
1058  tupType = HeapTupleHeaderGetTypeId(tuple);
1059  tupTypmod = HeapTupleHeaderGetTypMod(tuple);
1060  tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
1061 
1062  /*
1063  * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
1064  * the fields in the struct just in case user tries to inspect system
1065  * columns.
1066  */
1067  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
1068  ItemPointerSetInvalid(&(tmptup.t_self));
1069  tmptup.t_tableOid = InvalidOid;
1070  tmptup.t_data = tuple;
1071 
1072  result = heap_getattr(&tmptup,
1073  attrno,
1074  tupDesc,
1075  isNull);
1076 
1077  ReleaseTupleDesc(tupDesc);
1078 
1079  return result;
1080 }
1081 
1082 /*
1083  * Number of items in a tlist (including any resjunk items!)
1084  */
1085 int
1087 {
1088  /* This used to be more complex, but fjoins are dead */
1089  return list_length(targetlist);
1090 }
1091 
1092 /*
1093  * Number of items in a tlist, not including any resjunk items
1094  */
1095 int
1097 {
1098  int len = 0;
1099  ListCell *tl;
1100 
1101  foreach(tl, targetlist)
1102  {
1103  TargetEntry *curTle = lfirst_node(TargetEntry, tl);
1104 
1105  if (!curTle->resjunk)
1106  len++;
1107  }
1108  return len;
1109 }
#define NIL
Definition: pg_list.h:69
void ExecLockNonLeafAppendTables(List *partitioned_rels, EState *estate)
Definition: execUtils.c:913
uint32 CommandId
Definition: c.h:469
ExprContext * CreateStandaloneExprContext(void)
Definition: execUtils.c:298
HeapTuple * es_epqTuple
Definition: execnodes.h:517
JunkFilter * es_junkFilter
Definition: execnodes.h:446
int ExecTargetListLength(List *targetlist)
Definition: execUtils.c:1086
#define IsA(nodeptr, _type_)
Definition: nodes.h:563
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:198
Datum * ecxt_aggvalues
Definition: execnodes.h:224
Index varlevelsup
Definition: primnodes.h:173
int errhint(const char *fmt,...)
Definition: elog.c:987
RowMarkType markType
Definition: plannodes.h:1022
bool tdhasoid
Definition: tupdesc.h:82
CommandId es_output_cid
Definition: execnodes.h:449
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:893
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition: typcache.c:1618
int LOCKMODE
Definition: lockdefs.h:26
List * nonleafResultRelations
Definition: plannodes.h:72
TupleTableSlot * es_trig_newtup_slot
Definition: execnodes.h:473
Oid es_lastoid
Definition: execnodes.h:489
#define RelationIsScannable(relation)
Definition: rel.h:553
Relation relation
Definition: execnodes.h:547
void UnregisterExprContextCallback(ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
Definition: execUtils.c:845
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:90
ExprContext * ps_ExprContext
Definition: execnodes.h:892
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:214
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define AccessShareLock
Definition: lockdefs.h:36
PlannedStmt * es_plannedstmt
Definition: execnodes.h:443
Snapshot es_crosscheck_snapshot
Definition: execnodes.h:441
int errcode(int sqlerrcode)
Definition: elog.c:575
int namestrcmp(Name name, const char *str)
Definition: name.c:247
ExprContext * es_per_tuple_exprcontext
Definition: execnodes.h:506
AttrNumber varattno
Definition: primnodes.h:168
Snapshot es_snapshot
Definition: execnodes.h:440
#define EXEC_FLAG_WITH_NO_DATA
Definition: executor.h:65
Datum GetAttributeByName(HeapTupleHeader tuple, const char *attname, bool *isNull)
Definition: execUtils.c:972
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1117
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:134
#define heap_close(r, l)
Definition: heapam.h:97
List * list_delete_ptr(List *list, void *datum)
Definition: list.c:590
List * es_range_table
Definition: execnodes.h:442
unsigned int Oid
Definition: postgres_ext.h:31
Datum domainValue_datum
Definition: execnodes.h:232
void ExecConditionalAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc, Index varno)
Definition: execUtils.c:515
Definition: primnodes.h:163
#define RowMarkRequiresRowShareLock(marktype)
Definition: plannodes.h:975
int natts
Definition: tupdesc.h:79
void ExecFreeExprContext(PlanState *planstate)
Definition: execUtils.c:603
void ExecAssignResultType(PlanState *planstate, TupleDesc tupDesc)
Definition: execUtils.c:436
ScanDirection es_direction
Definition: execnodes.h:439
void ExecAssignResultTypeFromTL(PlanState *planstate)
Definition: execUtils.c:448
signed int int32
Definition: c.h:294
bool es_use_parallel_mode
Definition: execnodes.h:521
HeapTupleHeader t_data
Definition: htup.h:67
int pg_mbstrlen_with_len(const char *mbstr, int limit)
Definition: mbutils.c:794
#define HeapTupleHeaderGetTypMod(tup)
Definition: htup_details.h:460
void FreeExecutorState(EState *estate)
Definition: execUtils.c:186
const char * es_sourceText
Definition: execnodes.h:444
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:891
ParamExecData * es_param_exec_vals
Definition: execnodes.h:477
void pfree(void *pointer)
Definition: mcxt.c:936
MemoryContext es_query_cxt
Definition: execnodes.h:482
ExprContextCallbackFunction function
Definition: execnodes.h:176
bool resjunk
Definition: primnodes.h:1382
#define linitial(l)
Definition: pg_list.h:111
#define ERROR
Definition: elog.h:43
#define lfirst_int(lc)
Definition: pg_list.h:107
Oid vartype
Definition: primnodes.h:170
Datum caseValue_datum
Definition: execnodes.h:228
Bitmapset * bms_join(Bitmapset *a, Bitmapset *b)
Definition: bitmapset.c:954
Relation ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags)
Definition: execUtils.c:690
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:239
ItemPointerData t_self
Definition: htup.h:65
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:197
#define lfirst_node(type, lc)
Definition: pg_list.h:109
#define outerPlanState(node)
Definition: execnodes.h:904
uint32 t_len
Definition: htup.h:64
#define NoLock
Definition: lockdefs.h:34
void ExecAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc)
Definition: execUtils.c:495
ResultRelInfo * es_result_relations
Definition: execnodes.h:452
TupleTableSlot * ecxt_innertuple
Definition: execnodes.h:209
TupleTableSlot * es_trig_oldtup_slot
Definition: execnodes.h:472
ParamExecData * ecxt_param_exec_vals
Definition: execnodes.h:217
#define RelationGetRelationName(relation)
Definition: rel.h:445
struct EState * ecxt_estate
Definition: execnodes.h:236
static ListCell * list_head(const List *l)
Definition: pg_list.h:77
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
Oid t_tableOid
Definition: htup.h:66
Bitmapset * allParam
Definition: plannodes.h:163
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
int es_instrument
Definition: execnodes.h:492
TupleTableSlot * es_trig_tuple_slot
Definition: execnodes.h:471
List * es_leaf_result_relations
Definition: execnodes.h:467
#define lnext(lc)
Definition: pg_list.h:105
#define ereport(elevel, rest)
Definition: elog.h:122
EState * CreateExecutorState(void)
Definition: execUtils.c:81
Bitmapset * chgParam
Definition: execnodes.h:886
TupleDesc ExecTypeFromTL(List *targetList, bool hasoid)
Definition: execTuples.c:888
struct ExprContext_CB * next
Definition: execnodes.h:175
#define outerPlan(node)
Definition: plannodes.h:174
int ExecCleanTargetListLength(List *targetlist)
Definition: execUtils.c:1096
QueryEnvironment * es_queryEnv
Definition: execnodes.h:479
bool bms_is_empty(const Bitmapset *a)
Definition: bitmapset.c:707
static void ShutdownExprContext(ExprContext *econtext, bool isCommit)
Definition: execUtils.c:876
#define AllocSetContextCreate(parent, name, allocparams)
Definition: memutils.h:165
int es_num_root_result_relations
Definition: execnodes.h:464
Index varno
Definition: primnodes.h:166
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:774
bool domainValue_isNull
Definition: execnodes.h:233
#define InvalidSnapshot
Definition: snapshot.h:25
#define AttributeNumberIsValid(attributeNumber)
Definition: attnum.h:34
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:121
bool * ecxt_aggnulls
Definition: execnodes.h:225
List * es_trig_target_relations
Definition: execnodes.h:470
#define RowShareLock
Definition: lockdefs.h:37
List * es_tupleTable
Definition: execnodes.h:484
List * es_auxmodifytables
Definition: execnodes.h:499
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:296
void FreeExprContext(ExprContext *econtext, bool isCommit)
Definition: execUtils.c:357
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:450
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
int es_num_result_relations
Definition: execnodes.h:453
unsigned int Index
Definition: c.h:423
List * rowMarks
Definition: plannodes.h:86
Plan * plan
Definition: execnodes.h:858
#define InvalidOid
Definition: postgres_ext.h:36
bool es_finished
Definition: execnodes.h:493
void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
Definition: execUtils.c:758
int executor_errposition(EState *estate, int location)
Definition: execUtils.c:792
List * lcons(void *datum, List *list)
Definition: list.c:259
void bms_free(Bitmapset *a)
Definition: bitmapset.c:245
#define makeNode(_type_)
Definition: nodes.h:560
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:210
#define Assert(condition)
Definition: c.h:680
#define lfirst(lc)
Definition: pg_list.h:106
void RegisterExprContextCallback(ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
Definition: execUtils.c:819
uint64 es_processed
Definition: execnodes.h:488
void(* ExprContextCallbackFunction)(Datum arg)
Definition: execnodes.h:171
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:426
static int list_length(const List *l)
Definition: pg_list.h:89
void ExecCloseScanRelation(Relation scanrel)
Definition: execUtils.c:748
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:208
void ReScanExprContext(ExprContext *econtext)
Definition: execUtils.c:384
bool * es_epqTupleSet
Definition: execnodes.h:518
List * es_subplanstates
Definition: execnodes.h:497
static bool tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc)
Definition: execUtils.c:528
List * es_rowMarks
Definition: execnodes.h:486
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:213
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:477
#define InvalidAttrNumber
Definition: attnum.h:23
List * targetlist
Definition: plannodes.h:144
#define ItemPointerSetInvalid(pointer)
Definition: itemptr.h:150
bool caseValue_isNull
Definition: execnodes.h:229
void ExecAssignScanTypeFromOuterPlan(ScanState *scanstate)
Definition: execUtils.c:639
ProjectionInfo * ExecBuildProjectionInfo(List *targetList, ExprContext *econtext, TupleTableSlot *slot, PlanState *parent, TupleDesc inputDesc)
Definition: execExpr.c:348
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define getrelid(rangeindex, rangetable)
Definition: parsetree.h:41
int es_top_eflags
Definition: execnodes.h:491
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:693
ResultRelInfo * es_root_result_relations
Definition: execnodes.h:463
ExprContext * MakePerTupleExprContext(EState *estate)
Definition: execUtils.c:399
int i
bool * es_epqScanDone
Definition: execnodes.h:519
ExprContext * CreateExprContext(EState *estate)
Definition: execUtils.c:226
void ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc)
Definition: execUtils.c:627
void * arg
ParamListInfo es_param_list_info
Definition: execnodes.h:476
List * es_exprcontexts
Definition: execnodes.h:495
bool ExecContextForcesOids(PlanState *planstate, bool *hasoids)
Definition: execMain.c:1513
#define elog
Definition: elog.h:219
Datum GetAttributeByNum(HeapTupleHeader tuple, AttrNumber attrno, bool *isNull)
Definition: execUtils.c:1035
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:105
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:121
ParamListInfo ecxt_param_list_info
Definition: execnodes.h:218
Definition: pg_list.h:45
#define EXEC_FLAG_EXPLAIN_ONLY
Definition: executor.h:58
int16 AttrNumber
Definition: attnum.h:21
bool ExecRelationIsTargetRelation(EState *estate, Index scanrelid)
Definition: execUtils.c:664
int errposition(int cursorpos)
Definition: elog.c:1125
ExecRowMark * ExecFindRowMark(EState *estate, Index rti, bool missing_ok)
Definition: execMain.c:2398
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:444
int32 vartypmod
Definition: primnodes.h:171
ResultRelInfo * es_result_relation_info
Definition: execnodes.h:454