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