1 /*-------------------------------------------------------------------------
4 * miscellaneous executor utility routines
6 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * src/backend/executor/execUtils.c
13 *-------------------------------------------------------------------------
17 * CreateExecutorState Create/delete executor working state
20 * CreateStandaloneExprContext
24 * ExecAssignExprContext Common code for plan node init routines.
27 * ExecOpenScanRelation Common code for scan node init routines.
29 * ExecInitRangeTable Set up executor's range-table-related data.
31 * ExecGetRangeTableRelation Fetch Relation for a rangetable entry.
33 * executor_errposition Report syntactic position of an error.
35 * RegisterExprContextCallback Register function shutdown callback
36 * UnregisterExprContextCallback Deregister function shutdown callback
38 * GetAttributeByName Runtime extraction of columns from tuples.
42 * This file has traditionally been the place to stick misc.
43 * executor support stuff that doesn't really go anyplace else.
48 #include "access/parallel.h"
49 #include "access/relscan.h"
50 #include "access/table.h"
51 #include "access/tableam.h"
52 #include "access/transam.h"
53 #include "executor/executor.h"
54 #include "executor/execPartition.h"
56 #include "mb/pg_wchar.h"
57 #include "miscadmin.h"
58 #include "nodes/nodeFuncs.h"
59 #include "parser/parsetree.h"
60 #include "partitioning/partdesc.h"
61 #include "storage/lmgr.h"
62 #include "utils/builtins.h"
63 #include "utils/memutils.h"
64 #include "utils/rel.h"
65 #include "utils/typcache.h"
68 static bool tlist_matches_tupdesc(PlanState
*ps
, List
*tlist
, int varno
, TupleDesc tupdesc
);
69 static void ShutdownExprContext(ExprContext
*econtext
, bool isCommit
);
72 /* ----------------------------------------------------------------
73 * Executor state and memory management functions
74 * ----------------------------------------------------------------
80 * Create and initialize an EState node, which is the root of
81 * working storage for an entire Executor invocation.
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.
90 CreateExecutorState(void)
93 MemoryContext qcontext
;
94 MemoryContext oldcontext
;
97 * Create the per-query context for this Executor run.
99 qcontext
= AllocSetContextCreate(CurrentMemoryContext
,
101 ALLOCSET_DEFAULT_SIZES
);
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.
107 oldcontext
= MemoryContextSwitchTo(qcontext
);
109 estate
= makeNode(EState
);
112 * Initialize all fields of the Executor State structure
114 estate
->es_direction
= ForwardScanDirection
;
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_plannedstmt
= NULL
;
123 estate
->es_junkFilter
= NULL
;
125 estate
->es_output_cid
= (CommandId
) 0;
127 estate
->es_result_relations
= NULL
;
128 estate
->es_opened_result_relations
= NIL
;
129 estate
->es_tuple_routing_result_relations
= NIL
;
130 estate
->es_trig_target_relations
= NIL
;
132 estate
->es_param_list_info
= NULL
;
133 estate
->es_param_exec_vals
= NULL
;
135 estate
->es_queryEnv
= NULL
;
137 estate
->es_query_cxt
= qcontext
;
139 estate
->es_tupleTable
= NIL
;
141 estate
->es_processed
= 0;
143 estate
->es_top_eflags
= 0;
144 estate
->es_instrument
= 0;
145 estate
->es_finished
= false;
147 estate
->es_exprcontexts
= NIL
;
149 estate
->es_subplanstates
= NIL
;
151 estate
->es_auxmodifytables
= NIL
;
153 estate
->es_per_tuple_exprcontext
= NULL
;
155 estate
->es_sourceText
= NULL
;
157 estate
->es_use_parallel_mode
= false;
159 estate
->es_jit_flags
= 0;
160 estate
->es_jit
= NULL
;
163 * Return the executor state structure
165 MemoryContextSwitchTo(oldcontext
);
173 * Release an EState along with all remaining working storage.
175 * Note: this is not responsible for releasing non-memory resources, such as
176 * open relations or buffer pins. But it will shut down any still-active
177 * ExprContexts within the EState and deallocate associated JITed expressions.
178 * That is sufficient cleanup for situations where the EState has only been
179 * used for expression evaluation, and not to run a complete Plan.
181 * This can be called in any memory context ... so long as it's not one
182 * of the ones to be freed.
186 FreeExecutorState(EState
*estate
)
189 * Shut down and free any remaining ExprContexts. We do this explicitly
190 * to ensure that any remaining shutdown callbacks get called (since they
191 * might need to release resources that aren't simply memory within the
192 * per-query memory context).
194 while (estate
->es_exprcontexts
)
197 * XXX: seems there ought to be a faster way to implement this than
198 * repeated list_delete(), no?
200 FreeExprContext((ExprContext
*) linitial(estate
->es_exprcontexts
),
202 /* FreeExprContext removed the list link for us */
205 /* release JIT context, if allocated */
208 jit_release_context(estate
->es_jit
);
209 estate
->es_jit
= NULL
;
212 /* release partition directory, if allocated */
213 if (estate
->es_partition_directory
)
215 DestroyPartitionDirectory(estate
->es_partition_directory
);
216 estate
->es_partition_directory
= NULL
;
220 * Free the per-query memory context, thereby releasing all working
221 * memory, including the EState node itself.
223 MemoryContextDelete(estate
->es_query_cxt
);
227 * Internal implementation for CreateExprContext() and CreateWorkExprContext()
228 * that allows control over the AllocSet parameters.
231 CreateExprContextInternal(EState
*estate
, Size minContextSize
,
232 Size initBlockSize
, Size maxBlockSize
)
234 ExprContext
*econtext
;
235 MemoryContext oldcontext
;
237 /* Create the ExprContext node within the per-query memory context */
238 oldcontext
= MemoryContextSwitchTo(estate
->es_query_cxt
);
240 econtext
= makeNode(ExprContext
);
242 /* Initialize fields of ExprContext */
243 econtext
->ecxt_scantuple
= NULL
;
244 econtext
->ecxt_innertuple
= NULL
;
245 econtext
->ecxt_outertuple
= NULL
;
247 econtext
->ecxt_per_query_memory
= estate
->es_query_cxt
;
250 * Create working memory for expression evaluation in this context.
252 econtext
->ecxt_per_tuple_memory
=
253 AllocSetContextCreate(estate
->es_query_cxt
,
259 econtext
->ecxt_param_exec_vals
= estate
->es_param_exec_vals
;
260 econtext
->ecxt_param_list_info
= estate
->es_param_list_info
;
262 econtext
->ecxt_aggvalues
= NULL
;
263 econtext
->ecxt_aggnulls
= NULL
;
265 econtext
->caseValue_datum
= (Datum
) 0;
266 econtext
->caseValue_isNull
= true;
268 econtext
->domainValue_datum
= (Datum
) 0;
269 econtext
->domainValue_isNull
= true;
271 econtext
->ecxt_estate
= estate
;
273 econtext
->ecxt_callbacks
= NULL
;
276 * Link the ExprContext into the EState to ensure it is shut down when the
277 * EState is freed. Because we use lcons(), shutdowns will occur in
278 * reverse order of creation, which may not be essential but can't hurt.
280 estate
->es_exprcontexts
= lcons(econtext
, estate
->es_exprcontexts
);
282 MemoryContextSwitchTo(oldcontext
);
290 * Create a context for expression evaluation within an EState.
292 * An executor run may require multiple ExprContexts (we usually make one
293 * for each Plan node, and a separate one for per-output-tuple processing
294 * such as constraint checking). Each ExprContext has its own "per-tuple"
297 * Note we make no assumption about the caller's memory context.
301 CreateExprContext(EState
*estate
)
303 return CreateExprContextInternal(estate
, ALLOCSET_DEFAULT_SIZES
);
308 * CreateWorkExprContext
310 * Like CreateExprContext, but specifies the AllocSet sizes to be reasonable
311 * in proportion to work_mem. If the maximum block allocation size is too
312 * large, it's easy to skip right past work_mem with a single allocation.
316 CreateWorkExprContext(EState
*estate
)
318 Size minContextSize
= ALLOCSET_DEFAULT_MINSIZE
;
319 Size initBlockSize
= ALLOCSET_DEFAULT_INITSIZE
;
320 Size maxBlockSize
= ALLOCSET_DEFAULT_MAXSIZE
;
322 /* choose the maxBlockSize to be no larger than 1/16 of work_mem */
323 while (16 * maxBlockSize
> work_mem
* 1024L)
326 if (maxBlockSize
< ALLOCSET_DEFAULT_INITSIZE
)
327 maxBlockSize
= ALLOCSET_DEFAULT_INITSIZE
;
329 return CreateExprContextInternal(estate
, minContextSize
,
330 initBlockSize
, maxBlockSize
);
334 * CreateStandaloneExprContext
336 * Create a context for standalone expression evaluation.
338 * An ExprContext made this way can be used for evaluation of expressions
339 * that contain no Params, subplans, or Var references (it might work to
340 * put tuple references into the scantuple field, but it seems unwise).
342 * The ExprContext struct is allocated in the caller's current memory
343 * context, which also becomes its "per query" context.
345 * It is caller's responsibility to free the ExprContext when done,
346 * or at least ensure that any shutdown callbacks have been called
347 * (ReScanExprContext() is suitable). Otherwise, non-memory resources
352 CreateStandaloneExprContext(void)
354 ExprContext
*econtext
;
356 /* Create the ExprContext node within the caller's memory context */
357 econtext
= makeNode(ExprContext
);
359 /* Initialize fields of ExprContext */
360 econtext
->ecxt_scantuple
= NULL
;
361 econtext
->ecxt_innertuple
= NULL
;
362 econtext
->ecxt_outertuple
= NULL
;
364 econtext
->ecxt_per_query_memory
= CurrentMemoryContext
;
367 * Create working memory for expression evaluation in this context.
369 econtext
->ecxt_per_tuple_memory
=
370 AllocSetContextCreate(CurrentMemoryContext
,
372 ALLOCSET_DEFAULT_SIZES
);
374 econtext
->ecxt_param_exec_vals
= NULL
;
375 econtext
->ecxt_param_list_info
= NULL
;
377 econtext
->ecxt_aggvalues
= NULL
;
378 econtext
->ecxt_aggnulls
= NULL
;
380 econtext
->caseValue_datum
= (Datum
) 0;
381 econtext
->caseValue_isNull
= true;
383 econtext
->domainValue_datum
= (Datum
) 0;
384 econtext
->domainValue_isNull
= true;
386 econtext
->ecxt_estate
= NULL
;
388 econtext
->ecxt_callbacks
= NULL
;
396 * Free an expression context, including calling any remaining
397 * shutdown callbacks.
399 * Since we free the temporary context used for expression evaluation,
400 * any previously computed pass-by-reference expression result will go away!
402 * If isCommit is false, we are being called in error cleanup, and should
403 * not call callbacks but only release memory. (It might be better to call
404 * the callbacks and pass the isCommit flag to them, but that would require
405 * more invasive code changes than currently seems justified.)
407 * Note we make no assumption about the caller's memory context.
411 FreeExprContext(ExprContext
*econtext
, bool isCommit
)
415 /* Call any registered callbacks */
416 ShutdownExprContext(econtext
, isCommit
);
417 /* And clean up the memory used */
418 MemoryContextDelete(econtext
->ecxt_per_tuple_memory
);
419 /* Unlink self from owning EState, if any */
420 estate
= econtext
->ecxt_estate
;
422 estate
->es_exprcontexts
= list_delete_ptr(estate
->es_exprcontexts
,
424 /* And delete the ExprContext node */
431 * Reset an expression context in preparation for a rescan of its
432 * plan node. This requires calling any registered shutdown callbacks,
433 * since any partially complete set-returning-functions must be canceled.
435 * Note we make no assumption about the caller's memory context.
438 ReScanExprContext(ExprContext
*econtext
)
440 /* Call any registered callbacks */
441 ShutdownExprContext(econtext
, true);
442 /* And clean up the memory used */
443 MemoryContextReset(econtext
->ecxt_per_tuple_memory
);
447 * Build a per-output-tuple ExprContext for an EState.
449 * This is normally invoked via GetPerTupleExprContext() macro,
453 MakePerTupleExprContext(EState
*estate
)
455 if (estate
->es_per_tuple_exprcontext
== NULL
)
456 estate
->es_per_tuple_exprcontext
= CreateExprContext(estate
);
458 return estate
->es_per_tuple_exprcontext
;
462 /* ----------------------------------------------------------------
463 * miscellaneous node-init support functions
465 * Note: all of these are expected to be called with CurrentMemoryContext
466 * equal to the per-query memory context.
467 * ----------------------------------------------------------------
471 * ExecAssignExprContext
473 * This initializes the ps_ExprContext field. It is only necessary
474 * to do this for nodes which use ExecQual or ExecProject
475 * because those routines require an econtext. Other nodes that
476 * don't have to evaluate expressions don't need to do this.
480 ExecAssignExprContext(EState
*estate
, PlanState
*planstate
)
482 planstate
->ps_ExprContext
= CreateExprContext(estate
);
490 ExecGetResultType(PlanState
*planstate
)
492 return planstate
->ps_ResultTupleDesc
;
496 * ExecGetResultSlotOps - information about node's type of result slot
498 const TupleTableSlotOps
*
499 ExecGetResultSlotOps(PlanState
*planstate
, bool *isfixed
)
501 if (planstate
->resultopsset
&& planstate
->resultops
)
504 *isfixed
= planstate
->resultopsfixed
;
505 return planstate
->resultops
;
510 if (planstate
->resultopsset
)
511 *isfixed
= planstate
->resultopsfixed
;
512 else if (planstate
->ps_ResultTupleSlot
)
513 *isfixed
= TTS_FIXED(planstate
->ps_ResultTupleSlot
);
518 if (!planstate
->ps_ResultTupleSlot
)
519 return &TTSOpsVirtual
;
521 return planstate
->ps_ResultTupleSlot
->tts_ops
;
526 * ExecAssignProjectionInfo
528 * forms the projection information from the node's targetlist
530 * Notes for inputDesc are same as for ExecBuildProjectionInfo: supply it
531 * for a relation-scan node, can pass NULL for upper-level nodes
535 ExecAssignProjectionInfo(PlanState
*planstate
,
538 planstate
->ps_ProjInfo
=
539 ExecBuildProjectionInfo(planstate
->plan
->targetlist
,
540 planstate
->ps_ExprContext
,
541 planstate
->ps_ResultTupleSlot
,
548 * ExecConditionalAssignProjectionInfo
550 * as ExecAssignProjectionInfo, but store NULL rather than building projection
551 * info if no projection is required
555 ExecConditionalAssignProjectionInfo(PlanState
*planstate
, TupleDesc inputDesc
,
558 if (tlist_matches_tupdesc(planstate
,
559 planstate
->plan
->targetlist
,
563 planstate
->ps_ProjInfo
= NULL
;
564 planstate
->resultopsset
= planstate
->scanopsset
;
565 planstate
->resultopsfixed
= planstate
->scanopsfixed
;
566 planstate
->resultops
= planstate
->scanops
;
570 if (!planstate
->ps_ResultTupleSlot
)
572 ExecInitResultSlot(planstate
, &TTSOpsVirtual
);
573 planstate
->resultops
= &TTSOpsVirtual
;
574 planstate
->resultopsfixed
= true;
575 planstate
->resultopsset
= true;
577 ExecAssignProjectionInfo(planstate
, inputDesc
);
582 tlist_matches_tupdesc(PlanState
*ps
, List
*tlist
, int varno
, TupleDesc tupdesc
)
584 int numattrs
= tupdesc
->natts
;
586 ListCell
*tlist_item
= list_head(tlist
);
588 /* Check the tlist attributes */
589 for (attrno
= 1; attrno
<= numattrs
; attrno
++)
591 Form_pg_attribute att_tup
= TupleDescAttr(tupdesc
, attrno
- 1);
594 if (tlist_item
== NULL
)
595 return false; /* tlist too short */
596 var
= (Var
*) ((TargetEntry
*) lfirst(tlist_item
))->expr
;
597 if (!var
|| !IsA(var
, Var
))
598 return false; /* tlist item not a Var */
599 /* if these Asserts fail, planner messed up */
600 Assert(var
->varno
== varno
);
601 Assert(var
->varlevelsup
== 0);
602 if (var
->varattno
!= attrno
)
603 return false; /* out of order */
604 if (att_tup
->attisdropped
)
605 return false; /* table contains dropped columns */
606 if (att_tup
->atthasmissing
)
607 return false; /* table contains cols with missing values */
610 * Note: usually the Var's type should match the tupdesc exactly, but
611 * in situations involving unions of columns that have different
612 * typmods, the Var may have come from above the union and hence have
613 * typmod -1. This is a legitimate situation since the Var still
614 * describes the column, just not as exactly as the tupdesc does. We
615 * could change the planner to prevent it, but it'd then insert
616 * projection steps just to convert from specific typmod to typmod -1,
617 * which is pretty silly.
619 if (var
->vartype
!= att_tup
->atttypid
||
620 (var
->vartypmod
!= att_tup
->atttypmod
&&
621 var
->vartypmod
!= -1))
622 return false; /* type mismatch */
624 tlist_item
= lnext(tlist
, tlist_item
);
628 return false; /* tlist too long */
634 * ExecFreeExprContext
636 * A plan node's ExprContext should be freed explicitly during executor
637 * shutdown because there may be shutdown callbacks to call. (Other resources
638 * made by the above routines, such as projection info, don't need to be freed
639 * explicitly because they're just memory in the per-query memory context.)
641 * However ... there is no particular need to do it during ExecEndNode,
642 * because FreeExecutorState will free any remaining ExprContexts within
643 * the EState. Letting FreeExecutorState do it allows the ExprContexts to
644 * be freed in reverse order of creation, rather than order of creation as
645 * will happen if we delete them here, which saves O(N^2) work in the list
646 * cleanup inside FreeExprContext.
650 ExecFreeExprContext(PlanState
*planstate
)
653 * Per above discussion, don't actually delete the ExprContext. We do
654 * unlink it from the plan node, though.
656 planstate
->ps_ExprContext
= NULL
;
660 /* ----------------------------------------------------------------
662 * ----------------------------------------------------------------
670 ExecAssignScanType(ScanState
*scanstate
, TupleDesc tupDesc
)
672 TupleTableSlot
*slot
= scanstate
->ss_ScanTupleSlot
;
674 ExecSetSlotDescriptor(slot
, tupDesc
);
678 * ExecCreateScanSlotFromOuterPlan
682 ExecCreateScanSlotFromOuterPlan(EState
*estate
,
683 ScanState
*scanstate
,
684 const TupleTableSlotOps
*tts_ops
)
686 PlanState
*outerPlan
;
689 outerPlan
= outerPlanState(scanstate
);
690 tupDesc
= ExecGetResultType(outerPlan
);
692 ExecInitScanTupleSlot(estate
, scanstate
, tupDesc
, tts_ops
);
695 /* ----------------------------------------------------------------
696 * ExecRelationIsTargetRelation
698 * Detect whether a relation (identified by rangetable index)
699 * is one of the target relations of the query.
701 * Note: This is currently no longer used in core. We keep it around
702 * because FDWs may wish to use it to determine if their foreign table
703 * is a target relation.
704 * ----------------------------------------------------------------
707 ExecRelationIsTargetRelation(EState
*estate
, Index scanrelid
)
709 return list_member_int(estate
->es_plannedstmt
->resultRelations
, scanrelid
);
712 /* ----------------------------------------------------------------
713 * ExecOpenScanRelation
715 * Open the heap relation to be scanned by a base-level scan plan node.
716 * This should be called during the node's ExecInit routine.
717 * ----------------------------------------------------------------
720 ExecOpenScanRelation(EState
*estate
, Index scanrelid
, int eflags
)
724 /* Open the relation. */
725 rel
= ExecGetRangeTableRelation(estate
, scanrelid
);
728 * Complain if we're attempting a scan of an unscannable relation, except
729 * when the query won't actually be run. This is a slightly klugy place
730 * to do this, perhaps, but there is no better place.
732 if ((eflags
& (EXEC_FLAG_EXPLAIN_ONLY
| EXEC_FLAG_WITH_NO_DATA
)) == 0 &&
733 !RelationIsScannable(rel
))
735 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE
),
736 errmsg("materialized view \"%s\" has not been populated",
737 RelationGetRelationName(rel
)),
738 errhint("Use the REFRESH MATERIALIZED VIEW command.")));
745 * Set up executor's range-table-related data
747 * In addition to the range table proper, initialize arrays that are
748 * indexed by rangetable index.
751 ExecInitRangeTable(EState
*estate
, List
*rangeTable
)
753 /* Remember the range table List as-is */
754 estate
->es_range_table
= rangeTable
;
756 /* Set size of associated arrays */
757 estate
->es_range_table_size
= list_length(rangeTable
);
760 * Allocate an array to store an open Relation corresponding to each
761 * rangetable entry, and initialize entries to NULL. Relations are opened
762 * and stored here as needed.
764 estate
->es_relations
= (Relation
*)
765 palloc0(estate
->es_range_table_size
* sizeof(Relation
));
768 * es_result_relations and es_rowmarks are also parallel to
769 * es_range_table, but are allocated only if needed.
771 estate
->es_result_relations
= NULL
;
772 estate
->es_rowmarks
= NULL
;
776 * ExecGetRangeTableRelation
777 * Open the Relation for a range table entry, if not already done
779 * The Relations will be closed again in ExecEndPlan().
782 ExecGetRangeTableRelation(EState
*estate
, Index rti
)
786 Assert(rti
> 0 && rti
<= estate
->es_range_table_size
);
788 rel
= estate
->es_relations
[rti
- 1];
791 /* First time through, so open the relation */
792 RangeTblEntry
*rte
= exec_rt_fetch(rti
, estate
);
794 Assert(rte
->rtekind
== RTE_RELATION
);
796 if (!IsParallelWorker())
799 * In a normal query, we should already have the appropriate lock,
800 * but verify that through an Assert. Since there's already an
801 * Assert inside table_open that insists on holding some lock, it
802 * seems sufficient to check this only when rellockmode is higher
805 rel
= table_open(rte
->relid
, NoLock
);
806 Assert(rte
->rellockmode
== AccessShareLock
||
807 CheckRelationLockedByMe(rel
, rte
->rellockmode
, false));
812 * If we are a parallel worker, we need to obtain our own local
813 * lock on the relation. This ensures sane behavior in case the
814 * parent process exits before we do.
816 rel
= table_open(rte
->relid
, rte
->rellockmode
);
819 estate
->es_relations
[rti
- 1] = rel
;
826 * ExecInitResultRelation
827 * Open relation given by the passed-in RT index and fill its
830 * Here, we also save the ResultRelInfo in estate->es_result_relations array
831 * such that it can be accessed later using the RT index.
834 ExecInitResultRelation(EState
*estate
, ResultRelInfo
*resultRelInfo
,
837 Relation resultRelationDesc
;
839 resultRelationDesc
= ExecGetRangeTableRelation(estate
, rti
);
840 InitResultRelInfo(resultRelInfo
,
844 estate
->es_instrument
);
846 if (estate
->es_result_relations
== NULL
)
847 estate
->es_result_relations
= (ResultRelInfo
**)
848 palloc0(estate
->es_range_table_size
* sizeof(ResultRelInfo
*));
849 estate
->es_result_relations
[rti
- 1] = resultRelInfo
;
852 * Saving in the list allows to avoid needlessly traversing the whole
853 * array when only a few of its entries are possibly non-NULL.
855 estate
->es_opened_result_relations
=
856 lappend(estate
->es_opened_result_relations
, resultRelInfo
);
860 * UpdateChangedParamSet
861 * Add changed parameters to a plan node's chgParam set
864 UpdateChangedParamSet(PlanState
*node
, Bitmapset
*newchg
)
869 * The plan node only depends on params listed in its allParam set. Don't
870 * include anything else into its chgParam set.
872 parmset
= bms_intersect(node
->plan
->allParam
, newchg
);
875 * Keep node->chgParam == NULL if there's not actually any members; this
876 * allows the simplest possible tests in executor node files.
878 if (!bms_is_empty(parmset
))
879 node
->chgParam
= bms_join(node
->chgParam
, parmset
);
885 * executor_errposition
886 * Report an execution-time cursor position, if possible.
888 * This is expected to be used within an ereport() call. The return value
889 * is a dummy (always 0, in fact).
891 * The locations stored in parsetrees are byte offsets into the source string.
892 * We have to convert them to 1-based character indexes for reporting to
893 * clients. (We do things this way to avoid unnecessary overhead in the
894 * normal non-error case: computing character indexes would be much more
895 * expensive than storing token offsets.)
898 executor_errposition(EState
*estate
, int location
)
902 /* No-op if location was not provided */
905 /* Can't do anything if source text is not available */
906 if (estate
== NULL
|| estate
->es_sourceText
== NULL
)
908 /* Convert offset to character number */
909 pos
= pg_mbstrlen_with_len(estate
->es_sourceText
, location
) + 1;
910 /* And pass it to the ereport mechanism */
911 return errposition(pos
);
915 * Register a shutdown callback in an ExprContext.
917 * Shutdown callbacks will be called (in reverse order of registration)
918 * when the ExprContext is deleted or rescanned. This provides a hook
919 * for functions called in the context to do any cleanup needed --- it's
920 * particularly useful for functions returning sets. Note that the
921 * callback will *not* be called in the event that execution is aborted
925 RegisterExprContextCallback(ExprContext
*econtext
,
926 ExprContextCallbackFunction function
,
929 ExprContext_CB
*ecxt_callback
;
931 /* Save the info in appropriate memory context */
932 ecxt_callback
= (ExprContext_CB
*)
933 MemoryContextAlloc(econtext
->ecxt_per_query_memory
,
934 sizeof(ExprContext_CB
));
936 ecxt_callback
->function
= function
;
937 ecxt_callback
->arg
= arg
;
939 /* link to front of list for appropriate execution order */
940 ecxt_callback
->next
= econtext
->ecxt_callbacks
;
941 econtext
->ecxt_callbacks
= ecxt_callback
;
945 * Deregister a shutdown callback in an ExprContext.
947 * Any list entries matching the function and arg will be removed.
948 * This can be used if it's no longer necessary to call the callback.
951 UnregisterExprContextCallback(ExprContext
*econtext
,
952 ExprContextCallbackFunction function
,
955 ExprContext_CB
**prev_callback
;
956 ExprContext_CB
*ecxt_callback
;
958 prev_callback
= &econtext
->ecxt_callbacks
;
960 while ((ecxt_callback
= *prev_callback
) != NULL
)
962 if (ecxt_callback
->function
== function
&& ecxt_callback
->arg
== arg
)
964 *prev_callback
= ecxt_callback
->next
;
965 pfree(ecxt_callback
);
968 prev_callback
= &ecxt_callback
->next
;
973 * Call all the shutdown callbacks registered in an ExprContext.
975 * The callback list is emptied (important in case this is only a rescan
976 * reset, and not deletion of the ExprContext).
978 * If isCommit is false, just clean the callback list but don't call 'em.
979 * (See comment for FreeExprContext.)
982 ShutdownExprContext(ExprContext
*econtext
, bool isCommit
)
984 ExprContext_CB
*ecxt_callback
;
985 MemoryContext oldcontext
;
987 /* Fast path in normal case where there's nothing to do. */
988 if (econtext
->ecxt_callbacks
== NULL
)
992 * Call the callbacks in econtext's per-tuple context. This ensures that
993 * any memory they might leak will get cleaned up.
995 oldcontext
= MemoryContextSwitchTo(econtext
->ecxt_per_tuple_memory
);
998 * Call each callback function in reverse registration order.
1000 while ((ecxt_callback
= econtext
->ecxt_callbacks
) != NULL
)
1002 econtext
->ecxt_callbacks
= ecxt_callback
->next
;
1004 ecxt_callback
->function(ecxt_callback
->arg
);
1005 pfree(ecxt_callback
);
1008 MemoryContextSwitchTo(oldcontext
);
1012 * GetAttributeByName
1015 * These functions return the value of the requested attribute
1016 * out of the given tuple Datum.
1017 * C functions which take a tuple as an argument are expected
1018 * to use these. Ex: overpaid(EMP) might call GetAttributeByNum().
1019 * Note: these are actually rather slow because they do a typcache
1020 * lookup on each call.
1023 GetAttributeByName(HeapTupleHeader tuple
, const char *attname
, bool *isNull
)
1030 HeapTupleData tmptup
;
1033 if (attname
== NULL
)
1034 elog(ERROR
, "invalid attribute name");
1037 elog(ERROR
, "a NULL isNull pointer was passed");
1041 /* Kinda bogus but compatible with old behavior... */
1046 tupType
= HeapTupleHeaderGetTypeId(tuple
);
1047 tupTypmod
= HeapTupleHeaderGetTypMod(tuple
);
1048 tupDesc
= lookup_rowtype_tupdesc(tupType
, tupTypmod
);
1050 attrno
= InvalidAttrNumber
;
1051 for (i
= 0; i
< tupDesc
->natts
; i
++)
1053 Form_pg_attribute att
= TupleDescAttr(tupDesc
, i
);
1055 if (namestrcmp(&(att
->attname
), attname
) == 0)
1057 attrno
= att
->attnum
;
1062 if (attrno
== InvalidAttrNumber
)
1063 elog(ERROR
, "attribute \"%s\" does not exist", attname
);
1066 * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
1067 * the fields in the struct just in case user tries to inspect system
1070 tmptup
.t_len
= HeapTupleHeaderGetDatumLength(tuple
);
1071 ItemPointerSetInvalid(&(tmptup
.t_self
));
1072 tmptup
.t_tableOid
= InvalidOid
;
1073 tmptup
.t_data
= tuple
;
1075 result
= heap_getattr(&tmptup
,
1080 ReleaseTupleDesc(tupDesc
);
1086 GetAttributeByNum(HeapTupleHeader tuple
,
1094 HeapTupleData tmptup
;
1096 if (!AttributeNumberIsValid(attrno
))
1097 elog(ERROR
, "invalid attribute number %d", attrno
);
1100 elog(ERROR
, "a NULL isNull pointer was passed");
1104 /* Kinda bogus but compatible with old behavior... */
1109 tupType
= HeapTupleHeaderGetTypeId(tuple
);
1110 tupTypmod
= HeapTupleHeaderGetTypMod(tuple
);
1111 tupDesc
= lookup_rowtype_tupdesc(tupType
, tupTypmod
);
1114 * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
1115 * the fields in the struct just in case user tries to inspect system
1118 tmptup
.t_len
= HeapTupleHeaderGetDatumLength(tuple
);
1119 ItemPointerSetInvalid(&(tmptup
.t_self
));
1120 tmptup
.t_tableOid
= InvalidOid
;
1121 tmptup
.t_data
= tuple
;
1123 result
= heap_getattr(&tmptup
,
1128 ReleaseTupleDesc(tupDesc
);
1134 * Number of items in a tlist (including any resjunk items!)
1137 ExecTargetListLength(List
*targetlist
)
1139 /* This used to be more complex, but fjoins are dead */
1140 return list_length(targetlist
);
1144 * Number of items in a tlist, not including any resjunk items
1147 ExecCleanTargetListLength(List
*targetlist
)
1152 foreach(tl
, targetlist
)
1154 TargetEntry
*curTle
= lfirst_node(TargetEntry
, tl
);
1156 if (!curTle
->resjunk
)
1163 * Return a relInfo's tuple slot for a trigger's OLD tuples.
1166 ExecGetTriggerOldSlot(EState
*estate
, ResultRelInfo
*relInfo
)
1168 if (relInfo
->ri_TrigOldSlot
== NULL
)
1170 Relation rel
= relInfo
->ri_RelationDesc
;
1171 MemoryContext oldcontext
= MemoryContextSwitchTo(estate
->es_query_cxt
);
1173 relInfo
->ri_TrigOldSlot
=
1174 ExecInitExtraTupleSlot(estate
,
1175 RelationGetDescr(rel
),
1176 table_slot_callbacks(rel
));
1178 MemoryContextSwitchTo(oldcontext
);
1181 return relInfo
->ri_TrigOldSlot
;
1185 * Return a relInfo's tuple slot for a trigger's NEW tuples.
1188 ExecGetTriggerNewSlot(EState
*estate
, ResultRelInfo
*relInfo
)
1190 if (relInfo
->ri_TrigNewSlot
== NULL
)
1192 Relation rel
= relInfo
->ri_RelationDesc
;
1193 MemoryContext oldcontext
= MemoryContextSwitchTo(estate
->es_query_cxt
);
1195 relInfo
->ri_TrigNewSlot
=
1196 ExecInitExtraTupleSlot(estate
,
1197 RelationGetDescr(rel
),
1198 table_slot_callbacks(rel
));
1200 MemoryContextSwitchTo(oldcontext
);
1203 return relInfo
->ri_TrigNewSlot
;
1207 * Return a relInfo's tuple slot for processing returning tuples.
1210 ExecGetReturningSlot(EState
*estate
, ResultRelInfo
*relInfo
)
1212 if (relInfo
->ri_ReturningSlot
== NULL
)
1214 Relation rel
= relInfo
->ri_RelationDesc
;
1215 MemoryContext oldcontext
= MemoryContextSwitchTo(estate
->es_query_cxt
);
1217 relInfo
->ri_ReturningSlot
=
1218 ExecInitExtraTupleSlot(estate
,
1219 RelationGetDescr(rel
),
1220 table_slot_callbacks(rel
));
1222 MemoryContextSwitchTo(oldcontext
);
1225 return relInfo
->ri_ReturningSlot
;
1229 * Return the map needed to convert given child result relation's tuples to
1230 * the rowtype of the query's main target ("root") relation. Note that a
1231 * NULL result is valid and means that no conversion is needed.
1233 TupleConversionMap
*
1234 ExecGetChildToRootMap(ResultRelInfo
*resultRelInfo
)
1236 /* If we didn't already do so, compute the map for this child. */
1237 if (!resultRelInfo
->ri_ChildToRootMapValid
)
1239 ResultRelInfo
*rootRelInfo
= resultRelInfo
->ri_RootResultRelInfo
;
1242 resultRelInfo
->ri_ChildToRootMap
=
1243 convert_tuples_by_name(RelationGetDescr(resultRelInfo
->ri_RelationDesc
),
1244 RelationGetDescr(rootRelInfo
->ri_RelationDesc
));
1245 else /* this isn't a child result rel */
1246 resultRelInfo
->ri_ChildToRootMap
= NULL
;
1248 resultRelInfo
->ri_ChildToRootMapValid
= true;
1251 return resultRelInfo
->ri_ChildToRootMap
;
1254 /* Return a bitmap representing columns being inserted */
1256 ExecGetInsertedCols(ResultRelInfo
*relinfo
, EState
*estate
)
1259 * The columns are stored in the range table entry. If this ResultRelInfo
1260 * represents a partition routing target, and doesn't have an entry of its
1261 * own in the range table, fetch the parent's RTE and map the columns to
1262 * the order they are in the partition.
1264 if (relinfo
->ri_RangeTableIndex
!= 0)
1266 RangeTblEntry
*rte
= exec_rt_fetch(relinfo
->ri_RangeTableIndex
, estate
);
1268 return rte
->insertedCols
;
1270 else if (relinfo
->ri_RootResultRelInfo
)
1272 ResultRelInfo
*rootRelInfo
= relinfo
->ri_RootResultRelInfo
;
1273 RangeTblEntry
*rte
= exec_rt_fetch(rootRelInfo
->ri_RangeTableIndex
, estate
);
1275 if (relinfo
->ri_RootToPartitionMap
!= NULL
)
1276 return execute_attr_map_cols(relinfo
->ri_RootToPartitionMap
->attrMap
,
1279 return rte
->insertedCols
;
1284 * The relation isn't in the range table and it isn't a partition
1285 * routing target. This ResultRelInfo must've been created only for
1286 * firing triggers and the relation is not being inserted into. (See
1287 * ExecGetTriggerResultRel.)
1293 /* Return a bitmap representing columns being updated */
1295 ExecGetUpdatedCols(ResultRelInfo
*relinfo
, EState
*estate
)
1297 /* see ExecGetInsertedCols() */
1298 if (relinfo
->ri_RangeTableIndex
!= 0)
1300 RangeTblEntry
*rte
= exec_rt_fetch(relinfo
->ri_RangeTableIndex
, estate
);
1302 return rte
->updatedCols
;
1304 else if (relinfo
->ri_RootResultRelInfo
)
1306 ResultRelInfo
*rootRelInfo
= relinfo
->ri_RootResultRelInfo
;
1307 RangeTblEntry
*rte
= exec_rt_fetch(rootRelInfo
->ri_RangeTableIndex
, estate
);
1309 if (relinfo
->ri_RootToPartitionMap
!= NULL
)
1310 return execute_attr_map_cols(relinfo
->ri_RootToPartitionMap
->attrMap
,
1313 return rte
->updatedCols
;
1319 /* Return a bitmap representing generated columns being updated */
1321 ExecGetExtraUpdatedCols(ResultRelInfo
*relinfo
, EState
*estate
)
1323 /* see ExecGetInsertedCols() */
1324 if (relinfo
->ri_RangeTableIndex
!= 0)
1326 RangeTblEntry
*rte
= exec_rt_fetch(relinfo
->ri_RangeTableIndex
, estate
);
1328 return rte
->extraUpdatedCols
;
1330 else if (relinfo
->ri_RootResultRelInfo
)
1332 ResultRelInfo
*rootRelInfo
= relinfo
->ri_RootResultRelInfo
;
1333 RangeTblEntry
*rte
= exec_rt_fetch(rootRelInfo
->ri_RangeTableIndex
, estate
);
1335 if (relinfo
->ri_RootToPartitionMap
!= NULL
)
1336 return execute_attr_map_cols(relinfo
->ri_RootToPartitionMap
->attrMap
,
1337 rte
->extraUpdatedCols
);
1339 return rte
->extraUpdatedCols
;
1345 /* Return columns being updated, including generated columns */
1347 ExecGetAllUpdatedCols(ResultRelInfo
*relinfo
, EState
*estate
)
1349 return bms_union(ExecGetUpdatedCols(relinfo
, estate
),
1350 ExecGetExtraUpdatedCols(relinfo
, estate
));