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-2024, 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  *
29  * ExecInitRangeTable Set up executor's range-table-related data.
30  *
31  * ExecGetRangeTableRelation Fetch Relation for a rangetable entry.
32  *
33  * executor_errposition Report syntactic position of an error.
34  *
35  * RegisterExprContextCallback Register function shutdown callback
36  * UnregisterExprContextCallback Deregister function shutdown callback
37  *
38  * GetAttributeByName Runtime extraction of columns from tuples.
39  * GetAttributeByNum
40  *
41  * NOTES
42  * This file has traditionally been the place to stick misc.
43  * executor support stuff that doesn't really go anyplace else.
44  */
45 
46 #include "postgres.h"
47 
48 #include "access/parallel.h"
49 #include "access/table.h"
50 #include "access/tableam.h"
51 #include "executor/executor.h"
53 #include "jit/jit.h"
54 #include "mb/pg_wchar.h"
55 #include "miscadmin.h"
56 #include "parser/parse_relation.h"
57 #include "partitioning/partdesc.h"
58 #include "storage/lmgr.h"
59 #include "utils/builtins.h"
60 #include "utils/memutils.h"
61 #include "utils/rel.h"
62 #include "utils/typcache.h"
63 
64 
65 static bool tlist_matches_tupdesc(PlanState *ps, List *tlist, int varno, TupleDesc tupdesc);
66 static void ShutdownExprContext(ExprContext *econtext, bool isCommit);
68 
69 
70 /* ----------------------------------------------------------------
71  * Executor state and memory management functions
72  * ----------------------------------------------------------------
73  */
74 
75 /* ----------------
76  * CreateExecutorState
77  *
78  * Create and initialize an EState node, which is the root of
79  * working storage for an entire Executor invocation.
80  *
81  * Principally, this creates the per-query memory context that will be
82  * used to hold all working data that lives till the end of the query.
83  * Note that the per-query context will become a child of the caller's
84  * CurrentMemoryContext.
85  * ----------------
86  */
87 EState *
89 {
90  EState *estate;
91  MemoryContext qcontext;
92  MemoryContext oldcontext;
93 
94  /*
95  * Create the per-query context for this Executor run.
96  */
98  "ExecutorState",
100 
101  /*
102  * Make the EState node within the per-query context. This way, we don't
103  * need a separate pfree() operation for it at shutdown.
104  */
105  oldcontext = MemoryContextSwitchTo(qcontext);
106 
107  estate = makeNode(EState);
108 
109  /*
110  * Initialize all fields of the Executor State structure
111  */
113  estate->es_snapshot = InvalidSnapshot; /* caller must initialize this */
114  estate->es_crosscheck_snapshot = InvalidSnapshot; /* no crosscheck */
115  estate->es_range_table = NIL;
116  estate->es_range_table_size = 0;
117  estate->es_relations = NULL;
118  estate->es_rowmarks = NULL;
119  estate->es_rteperminfos = NIL;
120  estate->es_plannedstmt = NULL;
121 
122  estate->es_junkFilter = NULL;
123 
124  estate->es_output_cid = (CommandId) 0;
125 
126  estate->es_result_relations = NULL;
129  estate->es_trig_target_relations = NIL;
130 
133 
134  estate->es_param_list_info = NULL;
135  estate->es_param_exec_vals = NULL;
136 
137  estate->es_queryEnv = NULL;
138 
139  estate->es_query_cxt = qcontext;
140 
141  estate->es_tupleTable = NIL;
142 
143  estate->es_processed = 0;
144  estate->es_total_processed = 0;
145 
146  estate->es_top_eflags = 0;
147  estate->es_instrument = 0;
148  estate->es_finished = false;
149 
150  estate->es_exprcontexts = NIL;
151 
152  estate->es_subplanstates = NIL;
153 
154  estate->es_auxmodifytables = NIL;
155 
156  estate->es_per_tuple_exprcontext = NULL;
157 
158  estate->es_sourceText = NULL;
159 
160  estate->es_use_parallel_mode = false;
161  estate->es_parallel_workers_to_launch = 0;
162  estate->es_parallel_workers_launched = 0;
163 
164  estate->es_jit_flags = 0;
165  estate->es_jit = NULL;
166 
167  /*
168  * Return the executor state structure
169  */
170  MemoryContextSwitchTo(oldcontext);
171 
172  return estate;
173 }
174 
175 /* ----------------
176  * FreeExecutorState
177  *
178  * Release an EState along with all remaining working storage.
179  *
180  * Note: this is not responsible for releasing non-memory resources, such as
181  * open relations or buffer pins. But it will shut down any still-active
182  * ExprContexts within the EState and deallocate associated JITed expressions.
183  * That is sufficient cleanup for situations where the EState has only been
184  * used for expression evaluation, and not to run a complete Plan.
185  *
186  * This can be called in any memory context ... so long as it's not one
187  * of the ones to be freed.
188  * ----------------
189  */
190 void
192 {
193  /*
194  * Shut down and free any remaining ExprContexts. We do this explicitly
195  * to ensure that any remaining shutdown callbacks get called (since they
196  * might need to release resources that aren't simply memory within the
197  * per-query memory context).
198  */
199  while (estate->es_exprcontexts)
200  {
201  /*
202  * XXX: seems there ought to be a faster way to implement this than
203  * repeated list_delete(), no?
204  */
206  true);
207  /* FreeExprContext removed the list link for us */
208  }
209 
210  /* release JIT context, if allocated */
211  if (estate->es_jit)
212  {
213  jit_release_context(estate->es_jit);
214  estate->es_jit = NULL;
215  }
216 
217  /* release partition directory, if allocated */
218  if (estate->es_partition_directory)
219  {
221  estate->es_partition_directory = NULL;
222  }
223 
224  /*
225  * Free the per-query memory context, thereby releasing all working
226  * memory, including the EState node itself.
227  */
229 }
230 
231 /*
232  * Internal implementation for CreateExprContext() and CreateWorkExprContext()
233  * that allows control over the AllocSet parameters.
234  */
235 static ExprContext *
236 CreateExprContextInternal(EState *estate, Size minContextSize,
237  Size initBlockSize, Size maxBlockSize)
238 {
239  ExprContext *econtext;
240  MemoryContext oldcontext;
241 
242  /* Create the ExprContext node within the per-query memory context */
243  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
244 
245  econtext = makeNode(ExprContext);
246 
247  /* Initialize fields of ExprContext */
248  econtext->ecxt_scantuple = NULL;
249  econtext->ecxt_innertuple = NULL;
250  econtext->ecxt_outertuple = NULL;
251 
252  econtext->ecxt_per_query_memory = estate->es_query_cxt;
253 
254  /*
255  * Create working memory for expression evaluation in this context.
256  */
257  econtext->ecxt_per_tuple_memory =
259  "ExprContext",
260  minContextSize,
261  initBlockSize,
262  maxBlockSize);
263 
264  econtext->ecxt_param_exec_vals = estate->es_param_exec_vals;
265  econtext->ecxt_param_list_info = estate->es_param_list_info;
266 
267  econtext->ecxt_aggvalues = NULL;
268  econtext->ecxt_aggnulls = NULL;
269 
270  econtext->caseValue_datum = (Datum) 0;
271  econtext->caseValue_isNull = true;
272 
273  econtext->domainValue_datum = (Datum) 0;
274  econtext->domainValue_isNull = true;
275 
276  econtext->ecxt_estate = estate;
277 
278  econtext->ecxt_callbacks = NULL;
279 
280  /*
281  * Link the ExprContext into the EState to ensure it is shut down when the
282  * EState is freed. Because we use lcons(), shutdowns will occur in
283  * reverse order of creation, which may not be essential but can't hurt.
284  */
285  estate->es_exprcontexts = lcons(econtext, estate->es_exprcontexts);
286 
287  MemoryContextSwitchTo(oldcontext);
288 
289  return econtext;
290 }
291 
292 /* ----------------
293  * CreateExprContext
294  *
295  * Create a context for expression evaluation within an EState.
296  *
297  * An executor run may require multiple ExprContexts (we usually make one
298  * for each Plan node, and a separate one for per-output-tuple processing
299  * such as constraint checking). Each ExprContext has its own "per-tuple"
300  * memory context.
301  *
302  * Note we make no assumption about the caller's memory context.
303  * ----------------
304  */
305 ExprContext *
307 {
309 }
310 
311 
312 /* ----------------
313  * CreateWorkExprContext
314  *
315  * Like CreateExprContext, but specifies the AllocSet sizes to be reasonable
316  * in proportion to work_mem. If the maximum block allocation size is too
317  * large, it's easy to skip right past work_mem with a single allocation.
318  * ----------------
319  */
320 ExprContext *
322 {
323  Size minContextSize = ALLOCSET_DEFAULT_MINSIZE;
324  Size initBlockSize = ALLOCSET_DEFAULT_INITSIZE;
325  Size maxBlockSize = ALLOCSET_DEFAULT_MAXSIZE;
326 
327  /* choose the maxBlockSize to be no larger than 1/16 of work_mem */
328  while (16 * maxBlockSize > work_mem * 1024L)
329  maxBlockSize >>= 1;
330 
331  if (maxBlockSize < ALLOCSET_DEFAULT_INITSIZE)
332  maxBlockSize = ALLOCSET_DEFAULT_INITSIZE;
333 
334  return CreateExprContextInternal(estate, minContextSize,
335  initBlockSize, maxBlockSize);
336 }
337 
338 /* ----------------
339  * CreateStandaloneExprContext
340  *
341  * Create a context for standalone expression evaluation.
342  *
343  * An ExprContext made this way can be used for evaluation of expressions
344  * that contain no Params, subplans, or Var references (it might work to
345  * put tuple references into the scantuple field, but it seems unwise).
346  *
347  * The ExprContext struct is allocated in the caller's current memory
348  * context, which also becomes its "per query" context.
349  *
350  * It is caller's responsibility to free the ExprContext when done,
351  * or at least ensure that any shutdown callbacks have been called
352  * (ReScanExprContext() is suitable). Otherwise, non-memory resources
353  * might be leaked.
354  * ----------------
355  */
356 ExprContext *
358 {
359  ExprContext *econtext;
360 
361  /* Create the ExprContext node within the caller's memory context */
362  econtext = makeNode(ExprContext);
363 
364  /* Initialize fields of ExprContext */
365  econtext->ecxt_scantuple = NULL;
366  econtext->ecxt_innertuple = NULL;
367  econtext->ecxt_outertuple = NULL;
368 
370 
371  /*
372  * Create working memory for expression evaluation in this context.
373  */
374  econtext->ecxt_per_tuple_memory =
376  "ExprContext",
378 
379  econtext->ecxt_param_exec_vals = NULL;
380  econtext->ecxt_param_list_info = NULL;
381 
382  econtext->ecxt_aggvalues = NULL;
383  econtext->ecxt_aggnulls = NULL;
384 
385  econtext->caseValue_datum = (Datum) 0;
386  econtext->caseValue_isNull = true;
387 
388  econtext->domainValue_datum = (Datum) 0;
389  econtext->domainValue_isNull = true;
390 
391  econtext->ecxt_estate = NULL;
392 
393  econtext->ecxt_callbacks = NULL;
394 
395  return econtext;
396 }
397 
398 /* ----------------
399  * FreeExprContext
400  *
401  * Free an expression context, including calling any remaining
402  * shutdown callbacks.
403  *
404  * Since we free the temporary context used for expression evaluation,
405  * any previously computed pass-by-reference expression result will go away!
406  *
407  * If isCommit is false, we are being called in error cleanup, and should
408  * not call callbacks but only release memory. (It might be better to call
409  * the callbacks and pass the isCommit flag to them, but that would require
410  * more invasive code changes than currently seems justified.)
411  *
412  * Note we make no assumption about the caller's memory context.
413  * ----------------
414  */
415 void
416 FreeExprContext(ExprContext *econtext, bool isCommit)
417 {
418  EState *estate;
419 
420  /* Call any registered callbacks */
421  ShutdownExprContext(econtext, isCommit);
422  /* And clean up the memory used */
424  /* Unlink self from owning EState, if any */
425  estate = econtext->ecxt_estate;
426  if (estate)
428  econtext);
429  /* And delete the ExprContext node */
430  pfree(econtext);
431 }
432 
433 /*
434  * ReScanExprContext
435  *
436  * Reset an expression context in preparation for a rescan of its
437  * plan node. This requires calling any registered shutdown callbacks,
438  * since any partially complete set-returning-functions must be canceled.
439  *
440  * Note we make no assumption about the caller's memory context.
441  */
442 void
444 {
445  /* Call any registered callbacks */
446  ShutdownExprContext(econtext, true);
447  /* And clean up the memory used */
449 }
450 
451 /*
452  * Build a per-output-tuple ExprContext for an EState.
453  *
454  * This is normally invoked via GetPerTupleExprContext() macro,
455  * not directly.
456  */
457 ExprContext *
459 {
460  if (estate->es_per_tuple_exprcontext == NULL)
462 
463  return estate->es_per_tuple_exprcontext;
464 }
465 
466 
467 /* ----------------------------------------------------------------
468  * miscellaneous node-init support functions
469  *
470  * Note: all of these are expected to be called with CurrentMemoryContext
471  * equal to the per-query memory context.
472  * ----------------------------------------------------------------
473  */
474 
475 /* ----------------
476  * ExecAssignExprContext
477  *
478  * This initializes the ps_ExprContext field. It is only necessary
479  * to do this for nodes which use ExecQual or ExecProject
480  * because those routines require an econtext. Other nodes that
481  * don't have to evaluate expressions don't need to do this.
482  * ----------------
483  */
484 void
486 {
487  planstate->ps_ExprContext = CreateExprContext(estate);
488 }
489 
490 /* ----------------
491  * ExecGetResultType
492  * ----------------
493  */
494 TupleDesc
496 {
497  return planstate->ps_ResultTupleDesc;
498 }
499 
500 /*
501  * ExecGetResultSlotOps - information about node's type of result slot
502  */
503 const TupleTableSlotOps *
504 ExecGetResultSlotOps(PlanState *planstate, bool *isfixed)
505 {
506  if (planstate->resultopsset && planstate->resultops)
507  {
508  if (isfixed)
509  *isfixed = planstate->resultopsfixed;
510  return planstate->resultops;
511  }
512 
513  if (isfixed)
514  {
515  if (planstate->resultopsset)
516  *isfixed = planstate->resultopsfixed;
517  else if (planstate->ps_ResultTupleSlot)
518  *isfixed = TTS_FIXED(planstate->ps_ResultTupleSlot);
519  else
520  *isfixed = false;
521  }
522 
523  if (!planstate->ps_ResultTupleSlot)
524  return &TTSOpsVirtual;
525 
526  return planstate->ps_ResultTupleSlot->tts_ops;
527 }
528 
529 
530 /* ----------------
531  * ExecAssignProjectionInfo
532  *
533  * forms the projection information from the node's targetlist
534  *
535  * Notes for inputDesc are same as for ExecBuildProjectionInfo: supply it
536  * for a relation-scan node, can pass NULL for upper-level nodes
537  * ----------------
538  */
539 void
541  TupleDesc inputDesc)
542 {
543  planstate->ps_ProjInfo =
545  planstate->ps_ExprContext,
546  planstate->ps_ResultTupleSlot,
547  planstate,
548  inputDesc);
549 }
550 
551 
552 /* ----------------
553  * ExecConditionalAssignProjectionInfo
554  *
555  * as ExecAssignProjectionInfo, but store NULL rather than building projection
556  * info if no projection is required
557  * ----------------
558  */
559 void
561  int varno)
562 {
563  if (tlist_matches_tupdesc(planstate,
564  planstate->plan->targetlist,
565  varno,
566  inputDesc))
567  {
568  planstate->ps_ProjInfo = NULL;
569  planstate->resultopsset = planstate->scanopsset;
570  planstate->resultopsfixed = planstate->scanopsfixed;
571  planstate->resultops = planstate->scanops;
572  }
573  else
574  {
575  if (!planstate->ps_ResultTupleSlot)
576  {
577  ExecInitResultSlot(planstate, &TTSOpsVirtual);
578  planstate->resultops = &TTSOpsVirtual;
579  planstate->resultopsfixed = true;
580  planstate->resultopsset = true;
581  }
582  ExecAssignProjectionInfo(planstate, inputDesc);
583  }
584 }
585 
586 static bool
587 tlist_matches_tupdesc(PlanState *ps, List *tlist, int varno, TupleDesc tupdesc)
588 {
589  int numattrs = tupdesc->natts;
590  int attrno;
591  ListCell *tlist_item = list_head(tlist);
592 
593  /* Check the tlist attributes */
594  for (attrno = 1; attrno <= numattrs; attrno++)
595  {
596  Form_pg_attribute att_tup = TupleDescAttr(tupdesc, attrno - 1);
597  Var *var;
598 
599  if (tlist_item == NULL)
600  return false; /* tlist too short */
601  var = (Var *) ((TargetEntry *) lfirst(tlist_item))->expr;
602  if (!var || !IsA(var, Var))
603  return false; /* tlist item not a Var */
604  /* if these Asserts fail, planner messed up */
605  Assert(var->varno == varno);
606  Assert(var->varlevelsup == 0);
607  if (var->varattno != attrno)
608  return false; /* out of order */
609  if (att_tup->attisdropped)
610  return false; /* table contains dropped columns */
611  if (att_tup->atthasmissing)
612  return false; /* table contains cols with missing values */
613 
614  /*
615  * Note: usually the Var's type should match the tupdesc exactly, but
616  * in situations involving unions of columns that have different
617  * typmods, the Var may have come from above the union and hence have
618  * typmod -1. This is a legitimate situation since the Var still
619  * describes the column, just not as exactly as the tupdesc does. We
620  * could change the planner to prevent it, but it'd then insert
621  * projection steps just to convert from specific typmod to typmod -1,
622  * which is pretty silly.
623  */
624  if (var->vartype != att_tup->atttypid ||
625  (var->vartypmod != att_tup->atttypmod &&
626  var->vartypmod != -1))
627  return false; /* type mismatch */
628 
629  tlist_item = lnext(tlist, tlist_item);
630  }
631 
632  if (tlist_item)
633  return false; /* tlist too long */
634 
635  return true;
636 }
637 
638 
639 /* ----------------------------------------------------------------
640  * Scan node support
641  * ----------------------------------------------------------------
642  */
643 
644 /* ----------------
645  * ExecAssignScanType
646  * ----------------
647  */
648 void
650 {
651  TupleTableSlot *slot = scanstate->ss_ScanTupleSlot;
652 
653  ExecSetSlotDescriptor(slot, tupDesc);
654 }
655 
656 /* ----------------
657  * ExecCreateScanSlotFromOuterPlan
658  * ----------------
659  */
660 void
662  ScanState *scanstate,
663  const TupleTableSlotOps *tts_ops)
664 {
666  TupleDesc tupDesc;
667 
668  outerPlan = outerPlanState(scanstate);
669  tupDesc = ExecGetResultType(outerPlan);
670 
671  ExecInitScanTupleSlot(estate, scanstate, tupDesc, tts_ops);
672 }
673 
674 /* ----------------------------------------------------------------
675  * ExecRelationIsTargetRelation
676  *
677  * Detect whether a relation (identified by rangetable index)
678  * is one of the target relations of the query.
679  *
680  * Note: This is currently no longer used in core. We keep it around
681  * because FDWs may wish to use it to determine if their foreign table
682  * is a target relation.
683  * ----------------------------------------------------------------
684  */
685 bool
687 {
688  return list_member_int(estate->es_plannedstmt->resultRelations, scanrelid);
689 }
690 
691 /* ----------------------------------------------------------------
692  * ExecOpenScanRelation
693  *
694  * Open the heap relation to be scanned by a base-level scan plan node.
695  * This should be called during the node's ExecInit routine.
696  * ----------------------------------------------------------------
697  */
698 Relation
699 ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags)
700 {
701  Relation rel;
702 
703  /* Open the relation. */
704  rel = ExecGetRangeTableRelation(estate, scanrelid);
705 
706  /*
707  * Complain if we're attempting a scan of an unscannable relation, except
708  * when the query won't actually be run. This is a slightly klugy place
709  * to do this, perhaps, but there is no better place.
710  */
711  if ((eflags & (EXEC_FLAG_EXPLAIN_ONLY | EXEC_FLAG_WITH_NO_DATA)) == 0 &&
712  !RelationIsScannable(rel))
713  ereport(ERROR,
714  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
715  errmsg("materialized view \"%s\" has not been populated",
717  errhint("Use the REFRESH MATERIALIZED VIEW command.")));
718 
719  return rel;
720 }
721 
722 /*
723  * ExecInitRangeTable
724  * Set up executor's range-table-related data
725  *
726  * In addition to the range table proper, initialize arrays that are
727  * indexed by rangetable index.
728  */
729 void
730 ExecInitRangeTable(EState *estate, List *rangeTable, List *permInfos)
731 {
732  /* Remember the range table List as-is */
733  estate->es_range_table = rangeTable;
734 
735  /* ... and the RTEPermissionInfo List too */
736  estate->es_rteperminfos = permInfos;
737 
738  /* Set size of associated arrays */
739  estate->es_range_table_size = list_length(rangeTable);
740 
741  /*
742  * Allocate an array to store an open Relation corresponding to each
743  * rangetable entry, and initialize entries to NULL. Relations are opened
744  * and stored here as needed.
745  */
746  estate->es_relations = (Relation *)
747  palloc0(estate->es_range_table_size * sizeof(Relation));
748 
749  /*
750  * es_result_relations and es_rowmarks are also parallel to
751  * es_range_table, but are allocated only if needed.
752  */
753  estate->es_result_relations = NULL;
754  estate->es_rowmarks = NULL;
755 }
756 
757 /*
758  * ExecGetRangeTableRelation
759  * Open the Relation for a range table entry, if not already done
760  *
761  * The Relations will be closed in ExecEndPlan().
762  */
763 Relation
765 {
766  Relation rel;
767 
768  Assert(rti > 0 && rti <= estate->es_range_table_size);
769 
770  rel = estate->es_relations[rti - 1];
771  if (rel == NULL)
772  {
773  /* First time through, so open the relation */
774  RangeTblEntry *rte = exec_rt_fetch(rti, estate);
775 
776  Assert(rte->rtekind == RTE_RELATION);
777 
778  if (!IsParallelWorker())
779  {
780  /*
781  * In a normal query, we should already have the appropriate lock,
782  * but verify that through an Assert. Since there's already an
783  * Assert inside table_open that insists on holding some lock, it
784  * seems sufficient to check this only when rellockmode is higher
785  * than the minimum.
786  */
787  rel = table_open(rte->relid, NoLock);
788  Assert(rte->rellockmode == AccessShareLock ||
789  CheckRelationLockedByMe(rel, rte->rellockmode, false));
790  }
791  else
792  {
793  /*
794  * If we are a parallel worker, we need to obtain our own local
795  * lock on the relation. This ensures sane behavior in case the
796  * parent process exits before we do.
797  */
798  rel = table_open(rte->relid, rte->rellockmode);
799  }
800 
801  estate->es_relations[rti - 1] = rel;
802  }
803 
804  return rel;
805 }
806 
807 /*
808  * ExecInitResultRelation
809  * Open relation given by the passed-in RT index and fill its
810  * ResultRelInfo node
811  *
812  * Here, we also save the ResultRelInfo in estate->es_result_relations array
813  * such that it can be accessed later using the RT index.
814  */
815 void
817  Index rti)
818 {
819  Relation resultRelationDesc;
820 
821  resultRelationDesc = ExecGetRangeTableRelation(estate, rti);
822  InitResultRelInfo(resultRelInfo,
823  resultRelationDesc,
824  rti,
825  NULL,
826  estate->es_instrument);
827 
828  if (estate->es_result_relations == NULL)
829  estate->es_result_relations = (ResultRelInfo **)
830  palloc0(estate->es_range_table_size * sizeof(ResultRelInfo *));
831  estate->es_result_relations[rti - 1] = resultRelInfo;
832 
833  /*
834  * Saving in the list allows to avoid needlessly traversing the whole
835  * array when only a few of its entries are possibly non-NULL.
836  */
838  lappend(estate->es_opened_result_relations, resultRelInfo);
839 }
840 
841 /*
842  * UpdateChangedParamSet
843  * Add changed parameters to a plan node's chgParam set
844  */
845 void
847 {
848  Bitmapset *parmset;
849 
850  /*
851  * The plan node only depends on params listed in its allParam set. Don't
852  * include anything else into its chgParam set.
853  */
854  parmset = bms_intersect(node->plan->allParam, newchg);
855  node->chgParam = bms_join(node->chgParam, parmset);
856 }
857 
858 /*
859  * executor_errposition
860  * Report an execution-time cursor position, if possible.
861  *
862  * This is expected to be used within an ereport() call. The return value
863  * is a dummy (always 0, in fact).
864  *
865  * The locations stored in parsetrees are byte offsets into the source string.
866  * We have to convert them to 1-based character indexes for reporting to
867  * clients. (We do things this way to avoid unnecessary overhead in the
868  * normal non-error case: computing character indexes would be much more
869  * expensive than storing token offsets.)
870  */
871 int
872 executor_errposition(EState *estate, int location)
873 {
874  int pos;
875 
876  /* No-op if location was not provided */
877  if (location < 0)
878  return 0;
879  /* Can't do anything if source text is not available */
880  if (estate == NULL || estate->es_sourceText == NULL)
881  return 0;
882  /* Convert offset to character number */
883  pos = pg_mbstrlen_with_len(estate->es_sourceText, location) + 1;
884  /* And pass it to the ereport mechanism */
885  return errposition(pos);
886 }
887 
888 /*
889  * Register a shutdown callback in an ExprContext.
890  *
891  * Shutdown callbacks will be called (in reverse order of registration)
892  * when the ExprContext is deleted or rescanned. This provides a hook
893  * for functions called in the context to do any cleanup needed --- it's
894  * particularly useful for functions returning sets. Note that the
895  * callback will *not* be called in the event that execution is aborted
896  * by an error.
897  */
898 void
901  Datum arg)
902 {
903  ExprContext_CB *ecxt_callback;
904 
905  /* Save the info in appropriate memory context */
906  ecxt_callback = (ExprContext_CB *)
908  sizeof(ExprContext_CB));
909 
910  ecxt_callback->function = function;
911  ecxt_callback->arg = arg;
912 
913  /* link to front of list for appropriate execution order */
914  ecxt_callback->next = econtext->ecxt_callbacks;
915  econtext->ecxt_callbacks = ecxt_callback;
916 }
917 
918 /*
919  * Deregister a shutdown callback in an ExprContext.
920  *
921  * Any list entries matching the function and arg will be removed.
922  * This can be used if it's no longer necessary to call the callback.
923  */
924 void
927  Datum arg)
928 {
929  ExprContext_CB **prev_callback;
930  ExprContext_CB *ecxt_callback;
931 
932  prev_callback = &econtext->ecxt_callbacks;
933 
934  while ((ecxt_callback = *prev_callback) != NULL)
935  {
936  if (ecxt_callback->function == function && ecxt_callback->arg == arg)
937  {
938  *prev_callback = ecxt_callback->next;
939  pfree(ecxt_callback);
940  }
941  else
942  prev_callback = &ecxt_callback->next;
943  }
944 }
945 
946 /*
947  * Call all the shutdown callbacks registered in an ExprContext.
948  *
949  * The callback list is emptied (important in case this is only a rescan
950  * reset, and not deletion of the ExprContext).
951  *
952  * If isCommit is false, just clean the callback list but don't call 'em.
953  * (See comment for FreeExprContext.)
954  */
955 static void
956 ShutdownExprContext(ExprContext *econtext, bool isCommit)
957 {
958  ExprContext_CB *ecxt_callback;
959  MemoryContext oldcontext;
960 
961  /* Fast path in normal case where there's nothing to do. */
962  if (econtext->ecxt_callbacks == NULL)
963  return;
964 
965  /*
966  * Call the callbacks in econtext's per-tuple context. This ensures that
967  * any memory they might leak will get cleaned up.
968  */
969  oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
970 
971  /*
972  * Call each callback function in reverse registration order.
973  */
974  while ((ecxt_callback = econtext->ecxt_callbacks) != NULL)
975  {
976  econtext->ecxt_callbacks = ecxt_callback->next;
977  if (isCommit)
978  ecxt_callback->function(ecxt_callback->arg);
979  pfree(ecxt_callback);
980  }
981 
982  MemoryContextSwitchTo(oldcontext);
983 }
984 
985 /*
986  * GetAttributeByName
987  * GetAttributeByNum
988  *
989  * These functions return the value of the requested attribute
990  * out of the given tuple Datum.
991  * C functions which take a tuple as an argument are expected
992  * to use these. Ex: overpaid(EMP) might call GetAttributeByNum().
993  * Note: these are actually rather slow because they do a typcache
994  * lookup on each call.
995  */
996 Datum
997 GetAttributeByName(HeapTupleHeader tuple, const char *attname, bool *isNull)
998 {
999  AttrNumber attrno;
1000  Datum result;
1001  Oid tupType;
1002  int32 tupTypmod;
1003  TupleDesc tupDesc;
1004  HeapTupleData tmptup;
1005  int i;
1006 
1007  if (attname == NULL)
1008  elog(ERROR, "invalid attribute name");
1009 
1010  if (isNull == NULL)
1011  elog(ERROR, "a NULL isNull pointer was passed");
1012 
1013  if (tuple == NULL)
1014  {
1015  /* Kinda bogus but compatible with old behavior... */
1016  *isNull = true;
1017  return (Datum) 0;
1018  }
1019 
1020  tupType = HeapTupleHeaderGetTypeId(tuple);
1021  tupTypmod = HeapTupleHeaderGetTypMod(tuple);
1022  tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
1023 
1024  attrno = InvalidAttrNumber;
1025  for (i = 0; i < tupDesc->natts; i++)
1026  {
1027  Form_pg_attribute att = TupleDescAttr(tupDesc, i);
1028 
1029  if (namestrcmp(&(att->attname), attname) == 0)
1030  {
1031  attrno = att->attnum;
1032  break;
1033  }
1034  }
1035 
1036  if (attrno == InvalidAttrNumber)
1037  elog(ERROR, "attribute \"%s\" does not exist", attname);
1038 
1039  /*
1040  * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
1041  * the fields in the struct just in case user tries to inspect system
1042  * columns.
1043  */
1044  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
1045  ItemPointerSetInvalid(&(tmptup.t_self));
1046  tmptup.t_tableOid = InvalidOid;
1047  tmptup.t_data = tuple;
1048 
1049  result = heap_getattr(&tmptup,
1050  attrno,
1051  tupDesc,
1052  isNull);
1053 
1054  ReleaseTupleDesc(tupDesc);
1055 
1056  return result;
1057 }
1058 
1059 Datum
1061  AttrNumber attrno,
1062  bool *isNull)
1063 {
1064  Datum result;
1065  Oid tupType;
1066  int32 tupTypmod;
1067  TupleDesc tupDesc;
1068  HeapTupleData tmptup;
1069 
1070  if (!AttributeNumberIsValid(attrno))
1071  elog(ERROR, "invalid attribute number %d", attrno);
1072 
1073  if (isNull == NULL)
1074  elog(ERROR, "a NULL isNull pointer was passed");
1075 
1076  if (tuple == NULL)
1077  {
1078  /* Kinda bogus but compatible with old behavior... */
1079  *isNull = true;
1080  return (Datum) 0;
1081  }
1082 
1083  tupType = HeapTupleHeaderGetTypeId(tuple);
1084  tupTypmod = HeapTupleHeaderGetTypMod(tuple);
1085  tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
1086 
1087  /*
1088  * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
1089  * the fields in the struct just in case user tries to inspect system
1090  * columns.
1091  */
1092  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
1093  ItemPointerSetInvalid(&(tmptup.t_self));
1094  tmptup.t_tableOid = InvalidOid;
1095  tmptup.t_data = tuple;
1096 
1097  result = heap_getattr(&tmptup,
1098  attrno,
1099  tupDesc,
1100  isNull);
1101 
1102  ReleaseTupleDesc(tupDesc);
1103 
1104  return result;
1105 }
1106 
1107 /*
1108  * Number of items in a tlist (including any resjunk items!)
1109  */
1110 int
1112 {
1113  /* This used to be more complex, but fjoins are dead */
1114  return list_length(targetlist);
1115 }
1116 
1117 /*
1118  * Number of items in a tlist, not including any resjunk items
1119  */
1120 int
1122 {
1123  int len = 0;
1124  ListCell *tl;
1125 
1126  foreach(tl, targetlist)
1127  {
1128  TargetEntry *curTle = lfirst_node(TargetEntry, tl);
1129 
1130  if (!curTle->resjunk)
1131  len++;
1132  }
1133  return len;
1134 }
1135 
1136 /*
1137  * Return a relInfo's tuple slot for a trigger's OLD tuples.
1138  */
1141 {
1142  if (relInfo->ri_TrigOldSlot == NULL)
1143  {
1144  Relation rel = relInfo->ri_RelationDesc;
1145  MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1146 
1147  relInfo->ri_TrigOldSlot =
1148  ExecInitExtraTupleSlot(estate,
1149  RelationGetDescr(rel),
1150  table_slot_callbacks(rel));
1151 
1152  MemoryContextSwitchTo(oldcontext);
1153  }
1154 
1155  return relInfo->ri_TrigOldSlot;
1156 }
1157 
1158 /*
1159  * Return a relInfo's tuple slot for a trigger's NEW tuples.
1160  */
1163 {
1164  if (relInfo->ri_TrigNewSlot == NULL)
1165  {
1166  Relation rel = relInfo->ri_RelationDesc;
1167  MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1168 
1169  relInfo->ri_TrigNewSlot =
1170  ExecInitExtraTupleSlot(estate,
1171  RelationGetDescr(rel),
1172  table_slot_callbacks(rel));
1173 
1174  MemoryContextSwitchTo(oldcontext);
1175  }
1176 
1177  return relInfo->ri_TrigNewSlot;
1178 }
1179 
1180 /*
1181  * Return a relInfo's tuple slot for processing returning tuples.
1182  */
1185 {
1186  if (relInfo->ri_ReturningSlot == NULL)
1187  {
1188  Relation rel = relInfo->ri_RelationDesc;
1189  MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1190 
1191  relInfo->ri_ReturningSlot =
1192  ExecInitExtraTupleSlot(estate,
1193  RelationGetDescr(rel),
1194  table_slot_callbacks(rel));
1195 
1196  MemoryContextSwitchTo(oldcontext);
1197  }
1198 
1199  return relInfo->ri_ReturningSlot;
1200 }
1201 
1202 /*
1203  * Return the map needed to convert given child result relation's tuples to
1204  * the rowtype of the query's main target ("root") relation. Note that a
1205  * NULL result is valid and means that no conversion is needed.
1206  */
1209 {
1210  /* If we didn't already do so, compute the map for this child. */
1211  if (!resultRelInfo->ri_ChildToRootMapValid)
1212  {
1213  ResultRelInfo *rootRelInfo = resultRelInfo->ri_RootResultRelInfo;
1214 
1215  if (rootRelInfo)
1216  resultRelInfo->ri_ChildToRootMap =
1218  RelationGetDescr(rootRelInfo->ri_RelationDesc));
1219  else /* this isn't a child result rel */
1220  resultRelInfo->ri_ChildToRootMap = NULL;
1221 
1222  resultRelInfo->ri_ChildToRootMapValid = true;
1223  }
1224 
1225  return resultRelInfo->ri_ChildToRootMap;
1226 }
1227 
1228 /*
1229  * Returns the map needed to convert given root result relation's tuples to
1230  * the rowtype of the given child relation. Note that a NULL result is valid
1231  * and means that no conversion is needed.
1232  */
1235 {
1236  /* Mustn't get called for a non-child result relation. */
1237  Assert(resultRelInfo->ri_RootResultRelInfo);
1238 
1239  /* If we didn't already do so, compute the map for this child. */
1240  if (!resultRelInfo->ri_RootToChildMapValid)
1241  {
1242  ResultRelInfo *rootRelInfo = resultRelInfo->ri_RootResultRelInfo;
1243  TupleDesc indesc = RelationGetDescr(rootRelInfo->ri_RelationDesc);
1244  TupleDesc outdesc = RelationGetDescr(resultRelInfo->ri_RelationDesc);
1245  Relation childrel = resultRelInfo->ri_RelationDesc;
1246  AttrMap *attrMap;
1247  MemoryContext oldcontext;
1248 
1249  /*
1250  * When this child table is not a partition (!relispartition), it may
1251  * have columns that are not present in the root table, which we ask
1252  * to ignore by passing true for missing_ok.
1253  */
1254  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1255  attrMap = build_attrmap_by_name_if_req(indesc, outdesc,
1256  !childrel->rd_rel->relispartition);
1257  if (attrMap)
1258  resultRelInfo->ri_RootToChildMap =
1259  convert_tuples_by_name_attrmap(indesc, outdesc, attrMap);
1260  MemoryContextSwitchTo(oldcontext);
1261  resultRelInfo->ri_RootToChildMapValid = true;
1262  }
1263 
1264  return resultRelInfo->ri_RootToChildMap;
1265 }
1266 
1267 /* Return a bitmap representing columns being inserted */
1268 Bitmapset *
1270 {
1271  RTEPermissionInfo *perminfo = GetResultRTEPermissionInfo(relinfo, estate);
1272 
1273  if (perminfo == NULL)
1274  return NULL;
1275 
1276  /* Map the columns to child's attribute numbers if needed. */
1277  if (relinfo->ri_RootResultRelInfo)
1278  {
1279  TupleConversionMap *map = ExecGetRootToChildMap(relinfo, estate);
1280 
1281  if (map)
1282  return execute_attr_map_cols(map->attrMap, perminfo->insertedCols);
1283  }
1284 
1285  return perminfo->insertedCols;
1286 }
1287 
1288 /* Return a bitmap representing columns being updated */
1289 Bitmapset *
1291 {
1292  RTEPermissionInfo *perminfo = GetResultRTEPermissionInfo(relinfo, estate);
1293 
1294  if (perminfo == NULL)
1295  return NULL;
1296 
1297  /* Map the columns to child's attribute numbers if needed. */
1298  if (relinfo->ri_RootResultRelInfo)
1299  {
1300  TupleConversionMap *map = ExecGetRootToChildMap(relinfo, estate);
1301 
1302  if (map)
1303  return execute_attr_map_cols(map->attrMap, perminfo->updatedCols);
1304  }
1305 
1306  return perminfo->updatedCols;
1307 }
1308 
1309 /* Return a bitmap representing generated columns being updated */
1310 Bitmapset *
1312 {
1313  /* Compute the info if we didn't already */
1314  if (relinfo->ri_GeneratedExprsU == NULL)
1315  ExecInitStoredGenerated(relinfo, estate, CMD_UPDATE);
1316  return relinfo->ri_extraUpdatedCols;
1317 }
1318 
1319 /*
1320  * Return columns being updated, including generated columns
1321  *
1322  * The bitmap is allocated in per-tuple memory context. It's up to the caller to
1323  * copy it into a different context with the appropriate lifespan, if needed.
1324  */
1325 Bitmapset *
1327 {
1328  Bitmapset *ret;
1329  MemoryContext oldcxt;
1330 
1332 
1333  ret = bms_union(ExecGetUpdatedCols(relinfo, estate),
1334  ExecGetExtraUpdatedCols(relinfo, estate));
1335 
1336  MemoryContextSwitchTo(oldcxt);
1337 
1338  return ret;
1339 }
1340 
1341 /*
1342  * GetResultRTEPermissionInfo
1343  * Looks up RTEPermissionInfo for ExecGet*Cols() routines
1344  */
1345 static RTEPermissionInfo *
1347 {
1348  Index rti;
1349  RangeTblEntry *rte;
1350  RTEPermissionInfo *perminfo = NULL;
1351 
1352  if (relinfo->ri_RootResultRelInfo)
1353  {
1354  /*
1355  * For inheritance child result relations (a partition routing target
1356  * of an INSERT or a child UPDATE target), this returns the root
1357  * parent's RTE to fetch the RTEPermissionInfo because that's the only
1358  * one that has one assigned.
1359  */
1360  rti = relinfo->ri_RootResultRelInfo->ri_RangeTableIndex;
1361  }
1362  else if (relinfo->ri_RangeTableIndex != 0)
1363  {
1364  /*
1365  * Non-child result relation should have their own RTEPermissionInfo.
1366  */
1367  rti = relinfo->ri_RangeTableIndex;
1368  }
1369  else
1370  {
1371  /*
1372  * The relation isn't in the range table and it isn't a partition
1373  * routing target. This ResultRelInfo must've been created only for
1374  * firing triggers and the relation is not being inserted into. (See
1375  * ExecGetTriggerResultRel.)
1376  */
1377  rti = 0;
1378  }
1379 
1380  if (rti > 0)
1381  {
1382  rte = exec_rt_fetch(rti, estate);
1383  perminfo = getRTEPermissionInfo(estate->es_rteperminfos, rte);
1384  }
1385 
1386  return perminfo;
1387 }
1388 
1389 /*
1390  * ExecGetResultRelCheckAsUser
1391  * Returns the user to modify passed-in result relation as
1392  *
1393  * The user is chosen by looking up the relation's or, if a child table, its
1394  * root parent's RTEPermissionInfo.
1395  */
1396 Oid
1398 {
1399  RTEPermissionInfo *perminfo = GetResultRTEPermissionInfo(relInfo, estate);
1400 
1401  /* XXX - maybe ok to return GetUserId() in this case? */
1402  if (perminfo == NULL)
1403  elog(ERROR, "no RTEPermissionInfo found for result relation with OID %u",
1404  RelationGetRelid(relInfo->ri_RelationDesc));
1405 
1406  return perminfo->checkAsUser ? perminfo->checkAsUser : GetUserId();
1407 }
AttrMap * build_attrmap_by_name_if_req(TupleDesc indesc, TupleDesc outdesc, bool missing_ok)
Definition: attmap.c:263
int16 AttrNumber
Definition: attnum.h:21
#define AttributeNumberIsValid(attributeNumber)
Definition: attnum.h:34
#define InvalidAttrNumber
Definition: attnum.h:23
Bitmapset * bms_join(Bitmapset *a, Bitmapset *b)
Definition: bitmapset.c:1230
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:251
Bitmapset * bms_intersect(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:292
signed int int32
Definition: c.h:496
#define Assert(condition)
Definition: c.h:849
unsigned int Index
Definition: c.h:605
uint32 CommandId
Definition: c.h:657
size_t Size
Definition: c.h:596
int errhint(const char *fmt,...)
Definition: elog.c:1317
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
int errposition(int cursorpos)
Definition: elog.c:1446
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#define ereport(elevel,...)
Definition: elog.h:149
ProjectionInfo * ExecBuildProjectionInfo(List *targetList, ExprContext *econtext, TupleTableSlot *slot, PlanState *parent, TupleDesc inputDesc)
Definition: execExpr.c:365
void InitResultRelInfo(ResultRelInfo *resultRelInfo, Relation resultRelationDesc, Index resultRelationIndex, ResultRelInfo *partition_root_rri, int instrument_options)
Definition: execMain.c:1201
const TupleTableSlotOps TTSOpsVirtual
Definition: execTuples.c:84
void ExecInitResultSlot(PlanState *planstate, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1866
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1898
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1918
void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc)
Definition: execTuples.c:1376
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:495
Bitmapset * ExecGetAllUpdatedCols(ResultRelInfo *relinfo, EState *estate)
Definition: execUtils.c:1326
static void ShutdownExprContext(ExprContext *econtext, bool isCommit)
Definition: execUtils.c:956
TupleTableSlot * ExecGetTriggerOldSlot(EState *estate, ResultRelInfo *relInfo)
Definition: execUtils.c:1140
void ReScanExprContext(ExprContext *econtext)
Definition: execUtils.c:443
ExprContext * CreateWorkExprContext(EState *estate)
Definition: execUtils.c:321
const TupleTableSlotOps * ExecGetResultSlotOps(PlanState *planstate, bool *isfixed)
Definition: execUtils.c:504
Bitmapset * ExecGetUpdatedCols(ResultRelInfo *relinfo, EState *estate)
Definition: execUtils.c:1290
static RTEPermissionInfo * GetResultRTEPermissionInfo(ResultRelInfo *relinfo, EState *estate)
Definition: execUtils.c:1346
void ExecInitRangeTable(EState *estate, List *rangeTable, List *permInfos)
Definition: execUtils.c:730
TupleTableSlot * ExecGetReturningSlot(EState *estate, ResultRelInfo *relInfo)
Definition: execUtils.c:1184
int executor_errposition(EState *estate, int location)
Definition: execUtils.c:872
Datum GetAttributeByNum(HeapTupleHeader tuple, AttrNumber attrno, bool *isNull)
Definition: execUtils.c:1060
void FreeExprContext(ExprContext *econtext, bool isCommit)
Definition: execUtils.c:416
static bool tlist_matches_tupdesc(PlanState *ps, List *tlist, int varno, TupleDesc tupdesc)
Definition: execUtils.c:587
void ExecInitResultRelation(EState *estate, ResultRelInfo *resultRelInfo, Index rti)
Definition: execUtils.c:816
ExprContext * CreateStandaloneExprContext(void)
Definition: execUtils.c:357
void ExecCreateScanSlotFromOuterPlan(EState *estate, ScanState *scanstate, const TupleTableSlotOps *tts_ops)
Definition: execUtils.c:661
EState * CreateExecutorState(void)
Definition: execUtils.c:88
ExprContext * CreateExprContext(EState *estate)
Definition: execUtils.c:306
TupleTableSlot * ExecGetTriggerNewSlot(EState *estate, ResultRelInfo *relInfo)
Definition: execUtils.c:1162
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:485
Relation ExecGetRangeTableRelation(EState *estate, Index rti)
Definition: execUtils.c:764
void ExecAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc)
Definition: execUtils.c:540
void UnregisterExprContextCallback(ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
Definition: execUtils.c:925
void ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc)
Definition: execUtils.c:649
void ExecConditionalAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc, int varno)
Definition: execUtils.c:560
void RegisterExprContextCallback(ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
Definition: execUtils.c:899
TupleConversionMap * ExecGetRootToChildMap(ResultRelInfo *resultRelInfo, EState *estate)
Definition: execUtils.c:1234
int ExecTargetListLength(List *targetlist)
Definition: execUtils.c:1111
void FreeExecutorState(EState *estate)
Definition: execUtils.c:191
bool ExecRelationIsTargetRelation(EState *estate, Index scanrelid)
Definition: execUtils.c:686
TupleConversionMap * ExecGetChildToRootMap(ResultRelInfo *resultRelInfo)
Definition: execUtils.c:1208
int ExecCleanTargetListLength(List *targetlist)
Definition: execUtils.c:1121
void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
Definition: execUtils.c:846
Datum GetAttributeByName(HeapTupleHeader tuple, const char *attname, bool *isNull)
Definition: execUtils.c:997
ExprContext * MakePerTupleExprContext(EState *estate)
Definition: execUtils.c:458
Bitmapset * ExecGetExtraUpdatedCols(ResultRelInfo *relinfo, EState *estate)
Definition: execUtils.c:1311
static ExprContext * CreateExprContextInternal(EState *estate, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: execUtils.c:236
Bitmapset * ExecGetInsertedCols(ResultRelInfo *relinfo, EState *estate)
Definition: execUtils.c:1269
Relation ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags)
Definition: execUtils.c:699
Oid ExecGetResultRelCheckAsUser(ResultRelInfo *relInfo, EState *estate)
Definition: execUtils.c:1397
void(* ExprContextCallbackFunction)(Datum arg)
Definition: execnodes.h:220
#define outerPlanState(node)
Definition: execnodes.h:1224
static RangeTblEntry * exec_rt_fetch(Index rti, EState *estate)
Definition: executor.h:598
#define EXEC_FLAG_WITH_NO_DATA
Definition: executor.h:71
#define GetPerTupleMemoryContext(estate)
Definition: executor.h:566
#define EXEC_FLAG_EXPLAIN_ONLY
Definition: executor.h:65
int work_mem
Definition: globals.c:130
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: htup_details.h:792
#define HeapTupleHeaderGetTypMod(tup)
Definition: htup_details.h:466
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:456
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:450
#define IsParallelWorker()
Definition: parallel.h:60
struct parser_state ps
int i
Definition: isn.c:73
static void ItemPointerSetInvalid(ItemPointerData *pointer)
Definition: itemptr.h:184
void jit_release_context(JitContext *context)
Definition: jit.c:137
List * list_delete_ptr(List *list, void *datum)
Definition: list.c:872
List * lappend(List *list, void *datum)
Definition: list.c:339
bool list_member_int(const List *list, int datum)
Definition: list.c:702
List * lcons(void *datum, List *list)
Definition: list.c:495
bool CheckRelationLockedByMe(Relation relation, LOCKMODE lockmode, bool orstronger)
Definition: lmgr.c:330
#define NoLock
Definition: lockdefs.h:34
#define AccessShareLock
Definition: lockdefs.h:36
int pg_mbstrlen_with_len(const char *mbstr, int limit)
Definition: mbutils.c:1057
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:383
void pfree(void *pointer)
Definition: mcxt.c:1521
void * palloc0(Size size)
Definition: mcxt.c:1347
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1181
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:454
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_MAXSIZE
Definition: memutils.h:159
#define ALLOCSET_DEFAULT_MINSIZE
Definition: memutils.h:157
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:160
#define ALLOCSET_DEFAULT_INITSIZE
Definition: memutils.h:158
Oid GetUserId(void)
Definition: miscinit.c:514
int namestrcmp(Name name, const char *str)
Definition: name.c:247
void ExecInitStoredGenerated(ResultRelInfo *resultRelInfo, EState *estate, CmdType cmdtype)
#define IsA(nodeptr, _type_)
Definition: nodes.h:158
@ CMD_UPDATE
Definition: nodes.h:266
#define makeNode(_type_)
Definition: nodes.h:155
RTEPermissionInfo * getRTEPermissionInfo(List *rteperminfos, RangeTblEntry *rte)
@ RTE_RELATION
Definition: parsenodes.h:1017
void DestroyPartitionDirectory(PartitionDirectory pdir)
Definition: partdesc.c:484
NameData attname
Definition: pg_attribute.h:41
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:209
void * arg
const void size_t len
#define lfirst(lc)
Definition: pg_list.h:172
#define lfirst_node(type, lc)
Definition: pg_list.h:176
static int list_length(const List *l)
Definition: pg_list.h:152
#define NIL
Definition: pg_list.h:68
static ListCell * list_head(const List *l)
Definition: pg_list.h:128
#define linitial(l)
Definition: pg_list.h:178
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:343
#define outerPlan(node)
Definition: plannodes.h:183
uintptr_t Datum
Definition: postgres.h:64
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
MemoryContextSwitchTo(old_ctx)
#define RelationGetRelid(relation)
Definition: rel.h:505
#define RelationIsScannable(relation)
Definition: rel.h:669
#define RelationGetDescr(relation)
Definition: rel.h:531
#define RelationGetRelationName(relation)
Definition: rel.h:539
@ ForwardScanDirection
Definition: sdir.h:28
#define InvalidSnapshot
Definition: snapshot.h:123
Definition: attmap.h:35
uint64 es_processed
Definition: execnodes.h:679
struct ExecRowMark ** es_rowmarks
Definition: execnodes.h:638
int es_parallel_workers_to_launch
Definition: execnodes.h:711
List * es_tuple_routing_result_relations
Definition: execnodes.h:663
int es_top_eflags
Definition: execnodes.h:684
struct JitContext * es_jit
Definition: execnodes.h:729
int es_instrument
Definition: execnodes.h:685
PlannedStmt * es_plannedstmt
Definition: execnodes.h:641
QueryEnvironment * es_queryEnv
Definition: execnodes.h:672
ResultRelInfo ** es_result_relations
Definition: execnodes.h:650
ParamExecData * es_param_exec_vals
Definition: execnodes.h:670
uint64 es_total_processed
Definition: execnodes.h:681
List * es_range_table
Definition: execnodes.h:634
List * es_rteperminfos
Definition: execnodes.h:640
List * es_exprcontexts
Definition: execnodes.h:688
ParamListInfo es_param_list_info
Definition: execnodes.h:669
bool es_finished
Definition: execnodes.h:686
List * es_insert_pending_result_relations
Definition: execnodes.h:736
MemoryContext es_query_cxt
Definition: execnodes.h:675
List * es_tupleTable
Definition: execnodes.h:677
ScanDirection es_direction
Definition: execnodes.h:631
PartitionDirectory es_partition_directory
Definition: execnodes.h:657
List * es_trig_target_relations
Definition: execnodes.h:666
int es_jit_flags
Definition: execnodes.h:728
List * es_opened_result_relations
Definition: execnodes.h:653
bool es_use_parallel_mode
Definition: execnodes.h:709
Relation * es_relations
Definition: execnodes.h:636
List * es_subplanstates
Definition: execnodes.h:690
ExprContext * es_per_tuple_exprcontext
Definition: execnodes.h:699
int es_parallel_workers_launched
Definition: execnodes.h:713
CommandId es_output_cid
Definition: execnodes.h:647
Index es_range_table_size
Definition: execnodes.h:635
List * es_insert_pending_modifytables
Definition: execnodes.h:737
const char * es_sourceText
Definition: execnodes.h:642
Snapshot es_snapshot
Definition: execnodes.h:632
List * es_auxmodifytables
Definition: execnodes.h:692
JunkFilter * es_junkFilter
Definition: execnodes.h:644
Snapshot es_crosscheck_snapshot
Definition: execnodes.h:633
struct ExprContext_CB * next
Definition: execnodes.h:224
ExprContextCallbackFunction function
Definition: execnodes.h:225
Datum domainValue_datum
Definition: execnodes.h:289
ParamListInfo ecxt_param_list_info
Definition: execnodes.h:270
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:266
TupleTableSlot * ecxt_innertuple
Definition: execnodes.h:260
ParamExecData * ecxt_param_exec_vals
Definition: execnodes.h:269
Datum * ecxt_aggvalues
Definition: execnodes.h:277
bool caseValue_isNull
Definition: execnodes.h:285
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:258
Datum caseValue_datum
Definition: execnodes.h:283
bool * ecxt_aggnulls
Definition: execnodes.h:279
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:265
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:297
bool domainValue_isNull
Definition: execnodes.h:291
struct EState * ecxt_estate
Definition: execnodes.h:294
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:262
ItemPointerData t_self
Definition: htup.h:65
uint32 t_len
Definition: htup.h:64
HeapTupleHeader t_data
Definition: htup.h:68
Oid t_tableOid
Definition: htup.h:66
Definition: pg_list.h:54
const TupleTableSlotOps * resultops
Definition: execnodes.h:1205
bool resultopsset
Definition: execnodes.h:1213
const TupleTableSlotOps * scanops
Definition: execnodes.h:1202
Plan * plan
Definition: execnodes.h:1128
TupleDesc ps_ResultTupleDesc
Definition: execnodes.h:1165
Bitmapset * chgParam
Definition: execnodes.h:1160
bool scanopsset
Definition: execnodes.h:1210
ExprContext * ps_ExprContext
Definition: execnodes.h:1167
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:1166
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:1168
bool scanopsfixed
Definition: execnodes.h:1206
bool resultopsfixed
Definition: execnodes.h:1209
Bitmapset * allParam
Definition: plannodes.h:172
List * targetlist
Definition: plannodes.h:153
List * resultRelations
Definition: plannodes.h:78
Bitmapset * insertedCols
Definition: parsenodes.h:1294
Bitmapset * updatedCols
Definition: parsenodes.h:1295
RTEKind rtekind
Definition: parsenodes.h:1047
Form_pg_class rd_rel
Definition: rel.h:111
TupleConversionMap * ri_RootToChildMap
Definition: execnodes.h:576
struct ResultRelInfo * ri_RootResultRelInfo
Definition: execnodes.h:590
Relation ri_RelationDesc
Definition: execnodes.h:459
TupleTableSlot * ri_ReturningSlot
Definition: execnodes.h:504
bool ri_RootToChildMapValid
Definition: execnodes.h:577
Bitmapset * ri_extraUpdatedCols
Definition: execnodes.h:477
Index ri_RangeTableIndex
Definition: execnodes.h:456
TupleConversionMap * ri_ChildToRootMap
Definition: execnodes.h:570
bool ri_ChildToRootMapValid
Definition: execnodes.h:571
ExprState ** ri_GeneratedExprsU
Definition: execnodes.h:537
TupleTableSlot * ri_TrigNewSlot
Definition: execnodes.h:506
TupleTableSlot * ri_TrigOldSlot
Definition: execnodes.h:505
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1578
AttrMap * attrMap
Definition: tupconvert.h:28
const TupleTableSlotOps *const tts_ops
Definition: tuptable.h:121
Definition: primnodes.h:248
AttrNumber varattno
Definition: primnodes.h:260
int varno
Definition: primnodes.h:255
Index varlevelsup
Definition: primnodes.h:280
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40
const TupleTableSlotOps * table_slot_callbacks(Relation relation)
Definition: tableam.c:58
Bitmapset * execute_attr_map_cols(AttrMap *attrMap, Bitmapset *in_cols)
Definition: tupconvert.c:252
TupleConversionMap * convert_tuples_by_name_attrmap(TupleDesc indesc, TupleDesc outdesc, AttrMap *attrMap)
Definition: tupconvert.c:124
TupleConversionMap * convert_tuples_by_name(TupleDesc indesc, TupleDesc outdesc)
Definition: tupconvert.c:102
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:122
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
#define TTS_FIXED(slot)
Definition: tuptable.h:108
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition: typcache.c:1850