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