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