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{
543 const TupleTableSlotOps *result;
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 list_member_int(estate->es_plannedstmt->resultRelations, scanrelid);
737}
738
739/* ----------------------------------------------------------------
740 * ExecOpenScanRelation
741 *
742 * Open the heap relation to be scanned by a base-level scan plan node.
743 * This should be called during the node's ExecInit routine.
744 * ----------------------------------------------------------------
745 */
747ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags)
748{
749 Relation rel;
750
751 /* Open the relation. */
752 rel = ExecGetRangeTableRelation(estate, scanrelid, false);
753
754 /*
755 * Complain if we're attempting a scan of an unscannable relation, except
756 * when the query won't actually be run. This is a slightly klugy place
757 * to do this, perhaps, but there is no better place.
758 */
759 if ((eflags & (EXEC_FLAG_EXPLAIN_ONLY | EXEC_FLAG_WITH_NO_DATA)) == 0 &&
763 errmsg("materialized view \"%s\" has not been populated",
765 errhint("Use the REFRESH MATERIALIZED VIEW command.")));
766
767 return rel;
768}
769
770/*
771 * ExecInitRangeTable
772 * Set up executor's range-table-related data
773 *
774 * In addition to the range table proper, initialize arrays that are
775 * indexed by rangetable index.
776 */
777void
780{
781 /* Remember the range table List as-is */
782 estate->es_range_table = rangeTable;
783
784 /* ... and the RTEPermissionInfo List too */
785 estate->es_rteperminfos = permInfos;
786
787 /* Set size of associated arrays */
789
790 /*
791 * Initialize the bitmapset of RT indexes (es_unpruned_relids)
792 * representing relations that will be scanned during execution. This set
793 * is initially populated by the caller and may be extended later by
794 * ExecDoInitialPruning() to include RT indexes of unpruned leaf
795 * partitions.
796 */
798
799 /*
800 * Allocate an array to store an open Relation corresponding to each
801 * rangetable entry, and initialize entries to NULL. Relations are opened
802 * and stored here as needed.
803 */
804 estate->es_relations = (Relation *)
805 palloc0(estate->es_range_table_size * sizeof(Relation));
806
807 /*
808 * es_result_relations and es_rowmarks are also parallel to
809 * es_range_table, but are allocated only if needed.
810 */
811 estate->es_result_relations = NULL;
812 estate->es_rowmarks = NULL;
813}
814
815/*
816 * ExecGetRangeTableRelation
817 * Open the Relation for a range table entry, if not already done
818 *
819 * The Relations will be closed in ExecEndPlan().
820 *
821 * If isResultRel is true, the relation is being used as a result relation.
822 * Such a relation might have been pruned, which is OK for result relations,
823 * but not for scan relations; see the details in ExecInitModifyTable(). If
824 * isResultRel is false, the caller must ensure that 'rti' refers to an
825 * unpruned relation (i.e., it is a member of estate->es_unpruned_relids)
826 * before calling this function. Attempting to open a pruned relation for
827 * scanning will result in an error.
828 */
831{
832 Relation rel;
833
834 Assert(rti > 0 && rti <= estate->es_range_table_size);
835
836 if (!isResultRel && !bms_is_member(rti, estate->es_unpruned_relids))
837 elog(ERROR, "trying to open a pruned relation");
838
839 rel = estate->es_relations[rti - 1];
840 if (rel == NULL)
841 {
842 /* First time through, so open the relation */
843 RangeTblEntry *rte = exec_rt_fetch(rti, estate);
844
845 Assert(rte->rtekind == RTE_RELATION);
846
847 if (!IsParallelWorker())
848 {
849 /*
850 * In a normal query, we should already have the appropriate lock,
851 * but verify that through an Assert. Since there's already an
852 * Assert inside table_open that insists on holding some lock, it
853 * seems sufficient to check this only when rellockmode is higher
854 * than the minimum.
855 */
856 rel = table_open(rte->relid, NoLock);
857 Assert(rte->rellockmode == AccessShareLock ||
858 CheckRelationLockedByMe(rel, rte->rellockmode, false));
859 }
860 else
861 {
862 /*
863 * If we are a parallel worker, we need to obtain our own local
864 * lock on the relation. This ensures sane behavior in case the
865 * parent process exits before we do.
866 */
867 rel = table_open(rte->relid, rte->rellockmode);
868 }
869
870 estate->es_relations[rti - 1] = rel;
871 }
872
873 return rel;
874}
875
876/*
877 * ExecInitResultRelation
878 * Open relation given by the passed-in RT index and fill its
879 * ResultRelInfo node
880 *
881 * Here, we also save the ResultRelInfo in estate->es_result_relations array
882 * such that it can be accessed later using the RT index.
883 */
884void
886 Index rti)
887{
889
891 InitResultRelInfo(resultRelInfo,
893 rti,
894 NULL,
895 estate->es_instrument);
896
897 if (estate->es_result_relations == NULL)
899 palloc0(estate->es_range_table_size * sizeof(ResultRelInfo *));
900 estate->es_result_relations[rti - 1] = resultRelInfo;
901
902 /*
903 * Saving in the list allows to avoid needlessly traversing the whole
904 * array when only a few of its entries are possibly non-NULL.
905 */
907 lappend(estate->es_opened_result_relations, resultRelInfo);
908}
909
910/*
911 * UpdateChangedParamSet
912 * Add changed parameters to a plan node's chgParam set
913 */
914void
916{
918
919 /*
920 * The plan node only depends on params listed in its allParam set. Don't
921 * include anything else into its chgParam set.
922 */
924 node->chgParam = bms_join(node->chgParam, parmset);
925}
926
927/*
928 * executor_errposition
929 * Report an execution-time cursor position, if possible.
930 *
931 * This is expected to be used within an ereport() call. The return value
932 * is a dummy (always 0, in fact).
933 *
934 * The locations stored in parsetrees are byte offsets into the source string.
935 * We have to convert them to 1-based character indexes for reporting to
936 * clients. (We do things this way to avoid unnecessary overhead in the
937 * normal non-error case: computing character indexes would be much more
938 * expensive than storing token offsets.)
939 */
940int
941executor_errposition(EState *estate, int location)
942{
943 int pos;
944
945 /* No-op if location was not provided */
946 if (location < 0)
947 return 0;
948 /* Can't do anything if source text is not available */
949 if (estate == NULL || estate->es_sourceText == NULL)
950 return 0;
951 /* Convert offset to character number */
952 pos = pg_mbstrlen_with_len(estate->es_sourceText, location) + 1;
953 /* And pass it to the ereport mechanism */
954 return errposition(pos);
955}
956
957/*
958 * Register a shutdown callback in an ExprContext.
959 *
960 * Shutdown callbacks will be called (in reverse order of registration)
961 * when the ExprContext is deleted or rescanned. This provides a hook
962 * for functions called in the context to do any cleanup needed --- it's
963 * particularly useful for functions returning sets. Note that the
964 * callback will *not* be called in the event that execution is aborted
965 * by an error.
966 */
967void
970 Datum arg)
971{
973
974 /* Save the info in appropriate memory context */
977 sizeof(ExprContext_CB));
978
980 ecxt_callback->arg = arg;
981
982 /* link to front of list for appropriate execution order */
983 ecxt_callback->next = econtext->ecxt_callbacks;
984 econtext->ecxt_callbacks = ecxt_callback;
985}
986
987/*
988 * Deregister a shutdown callback in an ExprContext.
989 *
990 * Any list entries matching the function and arg will be removed.
991 * This can be used if it's no longer necessary to call the callback.
992 */
993void
996 Datum arg)
997{
1000
1001 prev_callback = &econtext->ecxt_callbacks;
1002
1003 while ((ecxt_callback = *prev_callback) != NULL)
1004 {
1005 if (ecxt_callback->function == function && ecxt_callback->arg == arg)
1006 {
1009 }
1010 else
1012 }
1013}
1014
1015/*
1016 * Call all the shutdown callbacks registered in an ExprContext.
1017 *
1018 * The callback list is emptied (important in case this is only a rescan
1019 * reset, and not deletion of the ExprContext).
1020 *
1021 * If isCommit is false, just clean the callback list but don't call 'em.
1022 * (See comment for FreeExprContext.)
1023 */
1024static void
1026{
1028 MemoryContext oldcontext;
1029
1030 /* Fast path in normal case where there's nothing to do. */
1031 if (econtext->ecxt_callbacks == NULL)
1032 return;
1033
1034 /*
1035 * Call the callbacks in econtext's per-tuple context. This ensures that
1036 * any memory they might leak will get cleaned up.
1037 */
1038 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
1039
1040 /*
1041 * Call each callback function in reverse registration order.
1042 */
1043 while ((ecxt_callback = econtext->ecxt_callbacks) != NULL)
1044 {
1045 econtext->ecxt_callbacks = ecxt_callback->next;
1046 if (isCommit)
1049 }
1050
1051 MemoryContextSwitchTo(oldcontext);
1052}
1053
1054/*
1055 * GetAttributeByName
1056 * GetAttributeByNum
1057 *
1058 * These functions return the value of the requested attribute
1059 * out of the given tuple Datum.
1060 * C functions which take a tuple as an argument are expected
1061 * to use these. Ex: overpaid(EMP) might call GetAttributeByNum().
1062 * Note: these are actually rather slow because they do a typcache
1063 * lookup on each call.
1064 */
1065Datum
1066GetAttributeByName(HeapTupleHeader tuple, const char *attname, bool *isNull)
1067{
1069 Datum result;
1070 Oid tupType;
1072 TupleDesc tupDesc;
1074 int i;
1075
1076 if (attname == NULL)
1077 elog(ERROR, "invalid attribute name");
1078
1079 if (isNull == NULL)
1080 elog(ERROR, "a NULL isNull pointer was passed");
1081
1082 if (tuple == NULL)
1083 {
1084 /* Kinda bogus but compatible with old behavior... */
1085 *isNull = true;
1086 return (Datum) 0;
1087 }
1088
1092
1094 for (i = 0; i < tupDesc->natts; i++)
1095 {
1097
1098 if (namestrcmp(&(att->attname), attname) == 0)
1099 {
1100 attrno = att->attnum;
1101 break;
1102 }
1103 }
1104
1106 elog(ERROR, "attribute \"%s\" does not exist", attname);
1107
1108 /*
1109 * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
1110 * the fields in the struct just in case user tries to inspect system
1111 * columns.
1112 */
1114 ItemPointerSetInvalid(&(tmptup.t_self));
1115 tmptup.t_tableOid = InvalidOid;
1116 tmptup.t_data = tuple;
1117
1118 result = heap_getattr(&tmptup,
1119 attrno,
1120 tupDesc,
1121 isNull);
1122
1123 ReleaseTupleDesc(tupDesc);
1124
1125 return result;
1126}
1127
1128Datum
1131 bool *isNull)
1132{
1133 Datum result;
1134 Oid tupType;
1136 TupleDesc tupDesc;
1138
1140 elog(ERROR, "invalid attribute number %d", attrno);
1141
1142 if (isNull == NULL)
1143 elog(ERROR, "a NULL isNull pointer was passed");
1144
1145 if (tuple == NULL)
1146 {
1147 /* Kinda bogus but compatible with old behavior... */
1148 *isNull = true;
1149 return (Datum) 0;
1150 }
1151
1155
1156 /*
1157 * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
1158 * the fields in the struct just in case user tries to inspect system
1159 * columns.
1160 */
1162 ItemPointerSetInvalid(&(tmptup.t_self));
1163 tmptup.t_tableOid = InvalidOid;
1164 tmptup.t_data = tuple;
1165
1166 result = heap_getattr(&tmptup,
1167 attrno,
1168 tupDesc,
1169 isNull);
1170
1171 ReleaseTupleDesc(tupDesc);
1172
1173 return result;
1174}
1175
1176/*
1177 * Number of items in a tlist (including any resjunk items!)
1178 */
1179int
1181{
1182 /* This used to be more complex, but fjoins are dead */
1183 return list_length(targetlist);
1184}
1185
1186/*
1187 * Number of items in a tlist, not including any resjunk items
1188 */
1189int
1191{
1192 int len = 0;
1193 ListCell *tl;
1194
1195 foreach(tl, targetlist)
1196 {
1198
1199 if (!curTle->resjunk)
1200 len++;
1201 }
1202 return len;
1203}
1204
1205/*
1206 * Return a relInfo's tuple slot for a trigger's OLD tuples.
1207 */
1210{
1211 if (relInfo->ri_TrigOldSlot == NULL)
1212 {
1213 Relation rel = relInfo->ri_RelationDesc;
1214 MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1215
1216 relInfo->ri_TrigOldSlot =
1218 RelationGetDescr(rel),
1220
1221 MemoryContextSwitchTo(oldcontext);
1222 }
1223
1224 return relInfo->ri_TrigOldSlot;
1225}
1226
1227/*
1228 * Return a relInfo's tuple slot for a trigger's NEW tuples.
1229 */
1232{
1233 if (relInfo->ri_TrigNewSlot == NULL)
1234 {
1235 Relation rel = relInfo->ri_RelationDesc;
1236 MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1237
1238 relInfo->ri_TrigNewSlot =
1240 RelationGetDescr(rel),
1242
1243 MemoryContextSwitchTo(oldcontext);
1244 }
1245
1246 return relInfo->ri_TrigNewSlot;
1247}
1248
1249/*
1250 * Return a relInfo's tuple slot for processing returning tuples.
1251 */
1254{
1255 if (relInfo->ri_ReturningSlot == NULL)
1256 {
1257 Relation rel = relInfo->ri_RelationDesc;
1258 MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1259
1260 relInfo->ri_ReturningSlot =
1262 RelationGetDescr(rel),
1264
1265 MemoryContextSwitchTo(oldcontext);
1266 }
1267
1268 return relInfo->ri_ReturningSlot;
1269}
1270
1271/*
1272 * Return a relInfo's all-NULL tuple slot for processing returning tuples.
1273 *
1274 * Note: this slot is intentionally filled with NULLs in every column, and
1275 * should be considered read-only --- the caller must not update it.
1276 */
1279{
1280 if (relInfo->ri_AllNullSlot == NULL)
1281 {
1282 Relation rel = relInfo->ri_RelationDesc;
1283 MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1284 TupleTableSlot *slot;
1285
1286 slot = ExecInitExtraTupleSlot(estate,
1287 RelationGetDescr(rel),
1290
1291 relInfo->ri_AllNullSlot = slot;
1292
1293 MemoryContextSwitchTo(oldcontext);
1294 }
1295
1296 return relInfo->ri_AllNullSlot;
1297}
1298
1299/*
1300 * Return the map needed to convert given child result relation's tuples to
1301 * the rowtype of the query's main target ("root") relation. Note that a
1302 * NULL result is valid and means that no conversion is needed.
1303 */
1306{
1307 /* If we didn't already do so, compute the map for this child. */
1308 if (!resultRelInfo->ri_ChildToRootMapValid)
1309 {
1311
1312 if (rootRelInfo)
1313 resultRelInfo->ri_ChildToRootMap =
1315 RelationGetDescr(rootRelInfo->ri_RelationDesc));
1316 else /* this isn't a child result rel */
1317 resultRelInfo->ri_ChildToRootMap = NULL;
1318
1319 resultRelInfo->ri_ChildToRootMapValid = true;
1320 }
1321
1322 return resultRelInfo->ri_ChildToRootMap;
1323}
1324
1325/*
1326 * Returns the map needed to convert given root result relation's tuples to
1327 * the rowtype of the given child relation. Note that a NULL result is valid
1328 * and means that no conversion is needed.
1329 */
1332{
1333 /* Mustn't get called for a non-child result relation. */
1334 Assert(resultRelInfo->ri_RootResultRelInfo);
1335
1336 /* If we didn't already do so, compute the map for this child. */
1337 if (!resultRelInfo->ri_RootToChildMapValid)
1338 {
1340 TupleDesc indesc = RelationGetDescr(rootRelInfo->ri_RelationDesc);
1341 TupleDesc outdesc = RelationGetDescr(resultRelInfo->ri_RelationDesc);
1342 Relation childrel = resultRelInfo->ri_RelationDesc;
1343 AttrMap *attrMap;
1344 MemoryContext oldcontext;
1345
1346 /*
1347 * When this child table is not a partition (!relispartition), it may
1348 * have columns that are not present in the root table, which we ask
1349 * to ignore by passing true for missing_ok.
1350 */
1351 oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1352 attrMap = build_attrmap_by_name_if_req(indesc, outdesc,
1353 !childrel->rd_rel->relispartition);
1354 if (attrMap)
1355 resultRelInfo->ri_RootToChildMap =
1356 convert_tuples_by_name_attrmap(indesc, outdesc, attrMap);
1357 MemoryContextSwitchTo(oldcontext);
1358 resultRelInfo->ri_RootToChildMapValid = true;
1359 }
1360
1361 return resultRelInfo->ri_RootToChildMap;
1362}
1363
1364/* Return a bitmap representing columns being inserted */
1365Bitmapset *
1367{
1369
1370 if (perminfo == NULL)
1371 return NULL;
1372
1373 /* Map the columns to child's attribute numbers if needed. */
1374 if (relinfo->ri_RootResultRelInfo)
1375 {
1377
1378 if (map)
1379 return execute_attr_map_cols(map->attrMap, perminfo->insertedCols);
1380 }
1381
1382 return perminfo->insertedCols;
1383}
1384
1385/* Return a bitmap representing columns being updated */
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->updatedCols);
1401 }
1402
1403 return perminfo->updatedCols;
1404}
1405
1406/* Return a bitmap representing generated columns being updated */
1407Bitmapset *
1409{
1410 /* Compute the info if we didn't already */
1411 if (!relinfo->ri_extraUpdatedCols_valid)
1413 return relinfo->ri_extraUpdatedCols;
1414}
1415
1416/*
1417 * Return columns being updated, including generated columns
1418 *
1419 * The bitmap is allocated in per-tuple memory context. It's up to the caller to
1420 * copy it into a different context with the appropriate lifespan, if needed.
1421 */
1422Bitmapset *
1424{
1425 Bitmapset *ret;
1427
1429
1430 ret = bms_union(ExecGetUpdatedCols(relinfo, estate),
1432
1434
1435 return ret;
1436}
1437
1438/*
1439 * GetResultRTEPermissionInfo
1440 * Looks up RTEPermissionInfo for ExecGet*Cols() routines
1441 */
1442static RTEPermissionInfo *
1444{
1445 Index rti;
1448
1449 if (relinfo->ri_RootResultRelInfo)
1450 {
1451 /*
1452 * For inheritance child result relations (a partition routing target
1453 * of an INSERT or a child UPDATE target), this returns the root
1454 * parent's RTE to fetch the RTEPermissionInfo because that's the only
1455 * one that has one assigned.
1456 */
1457 rti = relinfo->ri_RootResultRelInfo->ri_RangeTableIndex;
1458 }
1459 else if (relinfo->ri_RangeTableIndex != 0)
1460 {
1461 /*
1462 * Non-child result relation should have their own RTEPermissionInfo.
1463 */
1464 rti = relinfo->ri_RangeTableIndex;
1465 }
1466 else
1467 {
1468 /*
1469 * The relation isn't in the range table and it isn't a partition
1470 * routing target. This ResultRelInfo must've been created only for
1471 * firing triggers and the relation is not being inserted into. (See
1472 * ExecGetTriggerResultRel.)
1473 */
1474 rti = 0;
1475 }
1476
1477 if (rti > 0)
1478 {
1479 rte = exec_rt_fetch(rti, estate);
1481 }
1482
1483 return perminfo;
1484}
1485
1486/*
1487 * ExecGetResultRelCheckAsUser
1488 * Returns the user to modify passed-in result relation as
1489 *
1490 * The user is chosen by looking up the relation's or, if a child table, its
1491 * root parent's RTEPermissionInfo.
1492 */
1493Oid
1495{
1497
1498 /* XXX - maybe ok to return GetUserId() in this case? */
1499 if (perminfo == NULL)
1500 elog(ERROR, "no RTEPermissionInfo found for result relation with OID %u",
1501 RelationGetRelid(relInfo->ri_RelationDesc));
1502
1503 return perminfo->checkAsUser ? perminfo->checkAsUser : GetUserId();
1504}
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:1093
#define Max(x, y)
Definition c.h:1087
#define Assert(condition)
Definition c.h:945
int32_t int32
Definition c.h:614
unsigned int Index
Definition c.h:700
uint32 CommandId
Definition c.h:752
size_t Size
Definition c.h:691
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:39
#define elog(elevel,...)
Definition elog.h:226
int errposition(int cursorpos)
#define ereport(elevel,...)
Definition elog.h:150
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:1262
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:830
TupleConversionMap * ExecGetRootToChildMap(ResultRelInfo *resultRelInfo, EState *estate)
Definition execUtils.c:1331
Bitmapset * ExecGetExtraUpdatedCols(ResultRelInfo *relinfo, EState *estate)
Definition execUtils.c:1408
static void ShutdownExprContext(ExprContext *econtext, bool isCommit)
Definition execUtils.c:1025
Bitmapset * ExecGetInsertedCols(ResultRelInfo *relinfo, EState *estate)
Definition execUtils.c:1366
TupleTableSlot * ExecGetTriggerNewSlot(EState *estate, ResultRelInfo *relInfo)
Definition execUtils.c:1231
void ReScanExprContext(ExprContext *econtext)
Definition execUtils.c:448
ExprContext * CreateExprContext(EState *estate)
Definition execUtils.c:312
static RTEPermissionInfo * GetResultRTEPermissionInfo(ResultRelInfo *relinfo, EState *estate)
Definition execUtils.c:1443
TupleConversionMap * ExecGetChildToRootMap(ResultRelInfo *resultRelInfo)
Definition execUtils.c:1305
ExprContext * CreateStandaloneExprContext(void)
Definition execUtils.c:362
TupleTableSlot * ExecGetTriggerOldSlot(EState *estate, ResultRelInfo *relInfo)
Definition execUtils.c:1209
int executor_errposition(EState *estate, int location)
Definition execUtils.c:941
Datum GetAttributeByNum(HeapTupleHeader tuple, AttrNumber attrno, bool *isNull)
Definition execUtils.c:1129
void FreeExprContext(ExprContext *econtext, bool isCommit)
Definition execUtils.c:421
void ExecInitRangeTable(EState *estate, List *rangeTable, List *permInfos, Bitmapset *unpruned_relids)
Definition execUtils.c:778
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:1387
const TupleTableSlotOps * ExecGetCommonSlotOps(PlanState **planstates, int nplans)
Definition execUtils.c:541
void ExecInitResultRelation(EState *estate, ResultRelInfo *resultRelInfo, Index rti)
Definition execUtils.c:885
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:994
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:968
int ExecTargetListLength(List *targetlist)
Definition execUtils.c:1180
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:1278
int ExecCleanTargetListLength(List *targetlist)
Definition execUtils.c:1190
ExprContext * CreateWorkExprContext(EState *estate)
Definition execUtils.c:327
void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
Definition execUtils.c:915
const TupleTableSlotOps * ExecGetResultSlotOps(PlanState *planstate, bool *isfixed)
Definition execUtils.c:509
Datum GetAttributeByName(HeapTupleHeader tuple, const char *attname, bool *isNull)
Definition execUtils.c:1066
Bitmapset * ExecGetAllUpdatedCols(ResultRelInfo *relinfo, EState *estate)
Definition execUtils.c:1423
TupleTableSlot * ExecGetReturningSlot(EState *estate, ResultRelInfo *relInfo)
Definition execUtils.c:1253
Relation ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags)
Definition execUtils.c:747
Oid ExecGetResultRelCheckAsUser(ResultRelInfo *relInfo, EState *estate)
Definition execUtils.c:1494
EState * CreateExecutorState(void)
Definition execUtils.c:90
#define outerPlanState(node)
Definition execnodes.h:1273
#define innerPlanState(node)
Definition execnodes.h:1272
#define EXEC_FLAG_WITH_NO_DATA
Definition executor.h:73
static RangeTblEntry * exec_rt_fetch(Index rti, EState *estate)
Definition executor.h:701
#define GetPerTupleMemoryContext(estate)
Definition executor.h:665
#define EXEC_FLAG_EXPLAIN_ONLY
Definition executor.h:67
void(* ExprContextCallbackFunction)(Datum arg)
Definition fmgr.h:26
int work_mem
Definition globals.c:131
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 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: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:343
#define outerPlan(node)
Definition plannodes.h:265
uint64_t Datum
Definition postgres.h:70
#define InvalidOid
unsigned int Oid
static int fb(int x)
#define RelationGetRelid(relation)
Definition rel.h:514
#define RelationIsScannable(relation)
Definition rel.h:678
#define RelationGetDescr(relation)
Definition rel.h:540
#define RelationGetRelationName(relation)
Definition rel.h:548
@ ForwardScanDirection
Definition sdir.h:28
#define InvalidSnapshot
Definition snapshot.h:119
uint64 es_processed
Definition execnodes.h:726
List * es_part_prune_infos
Definition execnodes.h:682
int es_parallel_workers_to_launch
Definition execnodes.h:758
List * es_tuple_routing_result_relations
Definition execnodes.h:710
int es_top_eflags
Definition execnodes.h:731
struct JitContext * es_jit
Definition execnodes.h:776
int es_instrument
Definition execnodes.h:732
PlannedStmt * es_plannedstmt
Definition execnodes.h:681
QueryEnvironment * es_queryEnv
Definition execnodes.h:719
ResultRelInfo ** es_result_relations
Definition execnodes.h:697
ParamExecData * es_param_exec_vals
Definition execnodes.h:717
uint64 es_total_processed
Definition execnodes.h:728
List * es_range_table
Definition execnodes.h:674
List * es_rteperminfos
Definition execnodes.h:680
Bitmapset * es_unpruned_relids
Definition execnodes.h:685
List * es_part_prune_states
Definition execnodes.h:683
List * es_exprcontexts
Definition execnodes.h:735
ParamListInfo es_param_list_info
Definition execnodes.h:716
ExecRowMark ** es_rowmarks
Definition execnodes.h:678
bool es_finished
Definition execnodes.h:733
List * es_insert_pending_result_relations
Definition execnodes.h:783
MemoryContext es_query_cxt
Definition execnodes.h:722
List * es_tupleTable
Definition execnodes.h:724
ScanDirection es_direction
Definition execnodes.h:671
PartitionDirectory es_partition_directory
Definition execnodes.h:704
List * es_trig_target_relations
Definition execnodes.h:713
int es_jit_flags
Definition execnodes.h:775
List * es_opened_result_relations
Definition execnodes.h:700
bool es_use_parallel_mode
Definition execnodes.h:756
Relation * es_relations
Definition execnodes.h:676
List * es_subplanstates
Definition execnodes.h:737
ExprContext * es_per_tuple_exprcontext
Definition execnodes.h:746
int es_parallel_workers_launched
Definition execnodes.h:760
CommandId es_output_cid
Definition execnodes.h:694
Index es_range_table_size
Definition execnodes.h:675
List * es_insert_pending_modifytables
Definition execnodes.h:784
const char * es_sourceText
Definition execnodes.h:689
Snapshot es_snapshot
Definition execnodes.h:672
List * es_auxmodifytables
Definition execnodes.h:739
JunkFilter * es_junkFilter
Definition execnodes.h:691
List * es_part_prune_results
Definition execnodes.h:684
Snapshot es_crosscheck_snapshot
Definition execnodes.h:673
struct ExprContext_CB * next
Definition execnodes.h:250
ExprContextCallbackFunction function
Definition execnodes.h:251
Datum domainValue_datum
Definition execnodes.h:315
ParamListInfo ecxt_param_list_info
Definition execnodes.h:296
MemoryContext ecxt_per_tuple_memory
Definition execnodes.h:292
TupleTableSlot * ecxt_innertuple
Definition execnodes.h:286
ParamExecData * ecxt_param_exec_vals
Definition execnodes.h:295
Datum * ecxt_aggvalues
Definition execnodes.h:303
bool caseValue_isNull
Definition execnodes.h:311
TupleTableSlot * ecxt_scantuple
Definition execnodes.h:284
Datum caseValue_datum
Definition execnodes.h:309
bool * ecxt_aggnulls
Definition execnodes.h:305
MemoryContext ecxt_per_query_memory
Definition execnodes.h:291
ExprContext_CB * ecxt_callbacks
Definition execnodes.h:329
bool domainValue_isNull
Definition execnodes.h:317
struct EState * ecxt_estate
Definition execnodes.h:326
TupleTableSlot * ecxt_outertuple
Definition execnodes.h:288
Definition pg_list.h:54
const TupleTableSlotOps * resultops
Definition execnodes.h:1254
bool resultopsset
Definition execnodes.h:1262
const TupleTableSlotOps * scanops
Definition execnodes.h:1251
Plan * plan
Definition execnodes.h:1177
TupleDesc ps_ResultTupleDesc
Definition execnodes.h:1214
Bitmapset * chgParam
Definition execnodes.h:1209
bool scanopsset
Definition execnodes.h:1259
ExprContext * ps_ExprContext
Definition execnodes.h:1216
TupleTableSlot * ps_ResultTupleSlot
Definition execnodes.h:1215
ProjectionInfo * ps_ProjInfo
Definition execnodes.h:1217
bool scanopsfixed
Definition execnodes.h:1255
bool resultopsfixed
Definition execnodes.h:1258
Bitmapset * allParam
Definition plannodes.h:254
List * targetlist
Definition plannodes.h:233
List * resultRelations
Definition plannodes.h:122
TupleConversionMap * ri_RootToChildMap
Definition execnodes.h:618
struct ResultRelInfo * ri_RootResultRelInfo
Definition execnodes.h:630
Relation ri_RelationDesc
Definition execnodes.h:492
bool ri_RootToChildMapValid
Definition execnodes.h:619
TupleConversionMap * ri_ChildToRootMap
Definition execnodes.h:612
bool ri_ChildToRootMapValid
Definition execnodes.h:613
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:238
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