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