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