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