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