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