1/*-------------------------------------------------------------------------
2 *
3 * execUtils.c
4 * miscellaneous executor utility routines
5 *
6 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/backend/executor/execUtils.c
12 *
13 *-------------------------------------------------------------------------
14 */
15/*
16 * INTERFACE ROUTINES
17 * CreateExecutorState Create/delete executor working state
18 * FreeExecutorState
19 * CreateExprContext
20 * CreateStandaloneExprContext
21 * FreeExprContext
22 * ReScanExprContext
23 *
24 * ExecAssignExprContext Common code for plan node init routines.
25 * etc
26 *
27 * ExecOpenScanRelation Common code for scan node init routines.
28 *
29 * ExecInitRangeTable Set up executor's range-table-related data.
30 *
31 * ExecGetRangeTableRelation Fetch Relation for a rangetable entry.
32 *
33 * executor_errposition Report syntactic position of an error.
34 *
35 * RegisterExprContextCallback Register function shutdown callback
36 * UnregisterExprContextCallback Deregister function shutdown callback
37 *
38 * GetAttributeByName Runtime extraction of columns from tuples.
39 * GetAttributeByNum
40 *
41 * NOTES
42 * This file has traditionally been the place to stick misc.
43 * executor support stuff that doesn't really go anyplace else.
44 */
45
46#include "postgres.h"
47
48#include "access/parallel.h"
49#include "access/relscan.h"
50#include "access/table.h"
51#include "access/tableam.h"
52#include "access/transam.h"
53#include "executor/executor.h"
54#include "jit/jit.h"
55#include "mb/pg_wchar.h"
56#include "nodes/nodeFuncs.h"
57#include "parser/parsetree.h"
58#include "partitioning/partdesc.h"
59#include "storage/lmgr.h"
60#include "utils/builtins.h"
61#include "utils/memutils.h"
62#include "utils/rel.h"
63#include "utils/typcache.h"
64
65
66static bool tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc);
67static void ShutdownExprContext(ExprContext *econtext, bool isCommit);
68
69
70/* ----------------------------------------------------------------
71 * Executor state and memory management functions
72 * ----------------------------------------------------------------
73 */
74
75/* ----------------
76 * CreateExecutorState
77 *
78 * Create and initialize an EState node, which is the root of
79 * working storage for an entire Executor invocation.
80 *
81 * Principally, this creates the per-query memory context that will be
82 * used to hold all working data that lives till the end of the query.
83 * Note that the per-query context will become a child of the caller's
84 * CurrentMemoryContext.
85 * ----------------
86 */
87EState *
88CreateExecutorState(void)
89{
90 EState *estate;
91 MemoryContext qcontext;
92 MemoryContext oldcontext;
93
94 /*
95 * Create the per-query context for this Executor run.
96 */
97 qcontext = AllocSetContextCreate(CurrentMemoryContext,
98 "ExecutorState",
99 ALLOCSET_DEFAULT_SIZES);
100
101 /*
102 * Make the EState node within the per-query context. This way, we don't
103 * need a separate pfree() operation for it at shutdown.
104 */
105 oldcontext = MemoryContextSwitchTo(qcontext);
106
107 estate = makeNode(EState);
108
109 /*
110 * Initialize all fields of the Executor State structure
111 */
112 estate->es_direction = ForwardScanDirection;
113 estate->es_snapshot = InvalidSnapshot; /* caller must initialize this */
114 estate->es_crosscheck_snapshot = InvalidSnapshot; /* no crosscheck */
115 estate->es_range_table = NIL;
116 estate->es_range_table_array = NULL;
117 estate->es_range_table_size = 0;
118 estate->es_relations = NULL;
119 estate->es_rowmarks = NULL;
120 estate->es_plannedstmt = NULL;
121
122 estate->es_junkFilter = NULL;
123
124 estate->es_output_cid = (CommandId) 0;
125
126 estate->es_result_relations = NULL;
127 estate->es_num_result_relations = 0;
128 estate->es_result_relation_info = NULL;
129
130 estate->es_root_result_relations = NULL;
131 estate->es_num_root_result_relations = 0;
132
133 estate->es_tuple_routing_result_relations = NIL;
134
135 estate->es_trig_target_relations = NIL;
136
137 estate->es_param_list_info = NULL;
138 estate->es_param_exec_vals = NULL;
139
140 estate->es_queryEnv = NULL;
141
142 estate->es_query_cxt = qcontext;
143
144 estate->es_tupleTable = NIL;
145
146 estate->es_processed = 0;
147
148 estate->es_top_eflags = 0;
149 estate->es_instrument = 0;
150 estate->es_finished = false;
151
152 estate->es_exprcontexts = NIL;
153
154 estate->es_subplanstates = NIL;
155
156 estate->es_auxmodifytables = NIL;
157
158 estate->es_per_tuple_exprcontext = NULL;
159
160 estate->es_sourceText = NULL;
161
162 estate->es_use_parallel_mode = false;
163
164 estate->es_jit_flags = 0;
165 estate->es_jit = NULL;
166
167 /*
168 * Return the executor state structure
169 */
170 MemoryContextSwitchTo(oldcontext);
171
172 return estate;
173}
174
175/* ----------------
176 * FreeExecutorState
177 *
178 * Release an EState along with all remaining working storage.
179 *
180 * Note: this is not responsible for releasing non-memory resources, such as
181 * open relations or buffer pins. But it will shut down any still-active
182 * ExprContexts within the EState and deallocate associated JITed expressions.
183 * That is sufficient cleanup for situations where the EState has only been
184 * used for expression evaluation, and not to run a complete Plan.
185 *
186 * This can be called in any memory context ... so long as it's not one
187 * of the ones to be freed.
188 * ----------------
189 */
190void
191FreeExecutorState(EState *estate)
192{
193 /*
194 * Shut down and free any remaining ExprContexts. We do this explicitly
195 * to ensure that any remaining shutdown callbacks get called (since they
196 * might need to release resources that aren't simply memory within the
197 * per-query memory context).
198 */
199 while (estate->es_exprcontexts)
200 {
201 /*
202 * XXX: seems there ought to be a faster way to implement this than
203 * repeated list_delete(), no?
204 */
205 FreeExprContext((ExprContext *) linitial(estate->es_exprcontexts),
206 true);
207 /* FreeExprContext removed the list link for us */
208 }
209
210 /* release JIT context, if allocated */
211 if (estate->es_jit)
212 {
213 jit_release_context(estate->es_jit);
214 estate->es_jit = NULL;
215 }
216
217 /* release partition directory, if allocated */
218 if (estate->es_partition_directory)
219 {
220 DestroyPartitionDirectory(estate->es_partition_directory);
221 estate->es_partition_directory = NULL;
222 }
223
224 /*
225 * Free the per-query memory context, thereby releasing all working
226 * memory, including the EState node itself.
227 */
228 MemoryContextDelete(estate->es_query_cxt);
229}
230
231/* ----------------
232 * CreateExprContext
233 *
234 * Create a context for expression evaluation within an EState.
235 *
236 * An executor run may require multiple ExprContexts (we usually make one
237 * for each Plan node, and a separate one for per-output-tuple processing
238 * such as constraint checking). Each ExprContext has its own "per-tuple"
239 * memory context.
240 *
241 * Note we make no assumption about the caller's memory context.
242 * ----------------
243 */
244ExprContext *
245CreateExprContext(EState *estate)
246{
247 ExprContext *econtext;
248 MemoryContext oldcontext;
249
250 /* Create the ExprContext node within the per-query memory context */
251 oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
252
253 econtext = makeNode(ExprContext);
254
255 /* Initialize fields of ExprContext */
256 econtext->ecxt_scantuple = NULL;
257 econtext->ecxt_innertuple = NULL;
258 econtext->ecxt_outertuple = NULL;
259
260 econtext->ecxt_per_query_memory = estate->es_query_cxt;
261
262 /*
263 * Create working memory for expression evaluation in this context.
264 */
265 econtext->ecxt_per_tuple_memory =
266 AllocSetContextCreate(estate->es_query_cxt,
267 "ExprContext",
268 ALLOCSET_DEFAULT_SIZES);
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 * CreateStandaloneExprContext
300 *
301 * Create a context for standalone expression evaluation.
302 *
303 * An ExprContext made this way can be used for evaluation of expressions
304 * that contain no Params, subplans, or Var references (it might work to
305 * put tuple references into the scantuple field, but it seems unwise).
306 *
307 * The ExprContext struct is allocated in the caller's current memory
308 * context, which also becomes its "per query" context.
309 *
310 * It is caller's responsibility to free the ExprContext when done,
311 * or at least ensure that any shutdown callbacks have been called
312 * (ReScanExprContext() is suitable). Otherwise, non-memory resources
313 * might be leaked.
314 * ----------------
315 */
316ExprContext *
317CreateStandaloneExprContext(void)
318{
319 ExprContext *econtext;
320
321 /* Create the ExprContext node within the caller's memory context */
322 econtext = makeNode(ExprContext);
323
324 /* Initialize fields of ExprContext */
325 econtext->ecxt_scantuple = NULL;
326 econtext->ecxt_innertuple = NULL;
327 econtext->ecxt_outertuple = NULL;
328
329 econtext->ecxt_per_query_memory = CurrentMemoryContext;
330
331 /*
332 * Create working memory for expression evaluation in this context.
333 */
334 econtext->ecxt_per_tuple_memory =
335 AllocSetContextCreate(CurrentMemoryContext,
336 "ExprContext",
337 ALLOCSET_DEFAULT_SIZES);
338
339 econtext->ecxt_param_exec_vals = NULL;
340 econtext->ecxt_param_list_info = NULL;
341
342 econtext->ecxt_aggvalues = NULL;
343 econtext->ecxt_aggnulls = NULL;
344
345 econtext->caseValue_datum = (Datum) 0;
346 econtext->caseValue_isNull = true;
347
348 econtext->domainValue_datum = (Datum) 0;
349 econtext->domainValue_isNull = true;
350
351 econtext->ecxt_estate = NULL;
352
353 econtext->ecxt_callbacks = NULL;
354
355 return econtext;
356}
357
358/* ----------------
359 * FreeExprContext
360 *
361 * Free an expression context, including calling any remaining
362 * shutdown callbacks.
363 *
364 * Since we free the temporary context used for expression evaluation,
365 * any previously computed pass-by-reference expression result will go away!
366 *
367 * If isCommit is false, we are being called in error cleanup, and should
368 * not call callbacks but only release memory. (It might be better to call
369 * the callbacks and pass the isCommit flag to them, but that would require
370 * more invasive code changes than currently seems justified.)
371 *
372 * Note we make no assumption about the caller's memory context.
373 * ----------------
374 */
375void
376FreeExprContext(ExprContext *econtext, bool isCommit)
377{
378 EState *estate;
379
380 /* Call any registered callbacks */
381 ShutdownExprContext(econtext, isCommit);
382 /* And clean up the memory used */
383 MemoryContextDelete(econtext->ecxt_per_tuple_memory);
384 /* Unlink self from owning EState, if any */
385 estate = econtext->ecxt_estate;
386 if (estate)
387 estate->es_exprcontexts = list_delete_ptr(estate->es_exprcontexts,
388 econtext);
389 /* And delete the ExprContext node */
390 pfree(econtext);
391}
392
393/*
394 * ReScanExprContext
395 *
396 * Reset an expression context in preparation for a rescan of its
397 * plan node. This requires calling any registered shutdown callbacks,
398 * since any partially complete set-returning-functions must be canceled.
399 *
400 * Note we make no assumption about the caller's memory context.
401 */
402void
403ReScanExprContext(ExprContext *econtext)
404{
405 /* Call any registered callbacks */
406 ShutdownExprContext(econtext, true);
407 /* And clean up the memory used */
408 MemoryContextReset(econtext->ecxt_per_tuple_memory);
409}
410
411/*
412 * Build a per-output-tuple ExprContext for an EState.
413 *
414 * This is normally invoked via GetPerTupleExprContext() macro,
415 * not directly.
416 */
417ExprContext *
418MakePerTupleExprContext(EState *estate)
419{
420 if (estate->es_per_tuple_exprcontext == NULL)
421 estate->es_per_tuple_exprcontext = CreateExprContext(estate);
422
423 return estate->es_per_tuple_exprcontext;
424}
425
426
427/* ----------------------------------------------------------------
428 * miscellaneous node-init support functions
429 *
430 * Note: all of these are expected to be called with CurrentMemoryContext
431 * equal to the per-query memory context.
432 * ----------------------------------------------------------------
433 */
434
435/* ----------------
436 * ExecAssignExprContext
437 *
438 * This initializes the ps_ExprContext field. It is only necessary
439 * to do this for nodes which use ExecQual or ExecProject
440 * because those routines require an econtext. Other nodes that
441 * don't have to evaluate expressions don't need to do this.
442 * ----------------
443 */
444void
445ExecAssignExprContext(EState *estate, PlanState *planstate)
446{
447 planstate->ps_ExprContext = CreateExprContext(estate);
448}
449
450/* ----------------
451 * ExecGetResultType
452 * ----------------
453 */
454TupleDesc
455ExecGetResultType(PlanState *planstate)
456{
457 return planstate->ps_ResultTupleDesc;
458}
459
460/*
461 * ExecGetResultSlotOps - information about node's type of result slot
462 */
463const TupleTableSlotOps *
464ExecGetResultSlotOps(PlanState *planstate, bool *isfixed)
465{
466 if (planstate->resultopsset && planstate->resultops)
467 {
468 if (isfixed)
469 *isfixed = planstate->resultopsfixed;
470 return planstate->resultops;
471 }
472
473 if (isfixed)
474 {
475 if (planstate->resultopsset)
476 *isfixed = planstate->resultopsfixed;
477 else if (planstate->ps_ResultTupleSlot)
478 *isfixed = TTS_FIXED(planstate->ps_ResultTupleSlot);
479 else
480 *isfixed = false;
481 }
482
483 if (!planstate->ps_ResultTupleSlot)
484 return &TTSOpsVirtual;
485
486 return planstate->ps_ResultTupleSlot->tts_ops;
487}
488
489
490/* ----------------
491 * ExecAssignProjectionInfo
492 *
493 * forms the projection information from the node's targetlist
494 *
495 * Notes for inputDesc are same as for ExecBuildProjectionInfo: supply it
496 * for a relation-scan node, can pass NULL for upper-level nodes
497 * ----------------
498 */
499void
500ExecAssignProjectionInfo(PlanState *planstate,
501 TupleDesc inputDesc)
502{
503 planstate->ps_ProjInfo =
504 ExecBuildProjectionInfo(planstate->plan->targetlist,
505 planstate->ps_ExprContext,
506 planstate->ps_ResultTupleSlot,
507 planstate,
508 inputDesc);
509}
510
511
512/* ----------------
513 * ExecConditionalAssignProjectionInfo
514 *
515 * as ExecAssignProjectionInfo, but store NULL rather than building projection
516 * info if no projection is required
517 * ----------------
518 */
519void
520ExecConditionalAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc,
521 Index varno)
522{
523 if (tlist_matches_tupdesc(planstate,
524 planstate->plan->targetlist,
525 varno,
526 inputDesc))
527 {
528 planstate->ps_ProjInfo = NULL;
529 planstate->resultopsset = planstate->scanopsset;
530 planstate->resultopsfixed = planstate->scanopsfixed;
531 planstate->resultops = planstate->scanops;
532 }
533 else
534 {
535 if (!planstate->ps_ResultTupleSlot)
536 {
537 ExecInitResultSlot(planstate, &TTSOpsVirtual);
538 planstate->resultops = &TTSOpsVirtual;
539 planstate->resultopsfixed = true;
540 planstate->resultopsset = true;
541 }
542 ExecAssignProjectionInfo(planstate, inputDesc);
543 }
544}
545
546static bool
547tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc)
548{
549 int numattrs = tupdesc->natts;
550 int attrno;
551 ListCell *tlist_item = list_head(tlist);
552
553 /* Check the tlist attributes */
554 for (attrno = 1; attrno <= numattrs; attrno++)
555 {
556 Form_pg_attribute att_tup = TupleDescAttr(tupdesc, attrno - 1);
557 Var *var;
558
559 if (tlist_item == NULL)
560 return false; /* tlist too short */
561 var = (Var *) ((TargetEntry *) lfirst(tlist_item))->expr;
562 if (!var || !IsA(var, Var))
563 return false; /* tlist item not a Var */
564 /* if these Asserts fail, planner messed up */
565 Assert(var->varno == varno);
566 Assert(var->varlevelsup == 0);
567 if (var->varattno != attrno)
568 return false; /* out of order */
569 if (att_tup->attisdropped)
570 return false; /* table contains dropped columns */
571 if (att_tup->atthasmissing)
572 return false; /* table contains cols with missing values */
573
574 /*
575 * Note: usually the Var's type should match the tupdesc exactly, but
576 * in situations involving unions of columns that have different
577 * typmods, the Var may have come from above the union and hence have
578 * typmod -1. This is a legitimate situation since the Var still
579 * describes the column, just not as exactly as the tupdesc does. We
580 * could change the planner to prevent it, but it'd then insert
581 * projection steps just to convert from specific typmod to typmod -1,
582 * which is pretty silly.
583 */
584 if (var->vartype != att_tup->atttypid ||
585 (var->vartypmod != att_tup->atttypmod &&
586 var->vartypmod != -1))
587 return false; /* type mismatch */
588
589 tlist_item = lnext(tlist_item);
590 }
591
592 if (tlist_item)
593 return false; /* tlist too long */
594
595 return true;
596}
597
598/* ----------------
599 * ExecFreeExprContext
600 *
601 * A plan node's ExprContext should be freed explicitly during executor
602 * shutdown because there may be shutdown callbacks to call. (Other resources
603 * made by the above routines, such as projection info, don't need to be freed
604 * explicitly because they're just memory in the per-query memory context.)
605 *
606 * However ... there is no particular need to do it during ExecEndNode,
607 * because FreeExecutorState will free any remaining ExprContexts within
608 * the EState. Letting FreeExecutorState do it allows the ExprContexts to
609 * be freed in reverse order of creation, rather than order of creation as
610 * will happen if we delete them here, which saves O(N^2) work in the list
611 * cleanup inside FreeExprContext.
612 * ----------------
613 */
614void
615ExecFreeExprContext(PlanState *planstate)
616{
617 /*
618 * Per above discussion, don't actually delete the ExprContext. We do
619 * unlink it from the plan node, though.
620 */
621 planstate->ps_ExprContext = NULL;
622}
623
624
625/* ----------------------------------------------------------------
626 * Scan node support
627 * ----------------------------------------------------------------
628 */
629
630/* ----------------
631 * ExecAssignScanType
632 * ----------------
633 */
634void
635ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc)
636{
637 TupleTableSlot *slot = scanstate->ss_ScanTupleSlot;
638
639 ExecSetSlotDescriptor(slot, tupDesc);
640}
641
642/* ----------------
643 * ExecCreateScanSlotFromOuterPlan
644 * ----------------
645 */
646void
647ExecCreateScanSlotFromOuterPlan(EState *estate,
648 ScanState *scanstate,
649 const TupleTableSlotOps *tts_ops)
650{
651 PlanState *outerPlan;
652 TupleDesc tupDesc;
653
654 outerPlan = outerPlanState(scanstate);
655 tupDesc = ExecGetResultType(outerPlan);
656
657 ExecInitScanTupleSlot(estate, scanstate, tupDesc, tts_ops);
658}
659
660/* ----------------------------------------------------------------
661 * ExecRelationIsTargetRelation
662 *
663 * Detect whether a relation (identified by rangetable index)
664 * is one of the target relations of the query.
665 *
666 * Note: This is currently no longer used in core. We keep it around
667 * because FDWs may wish to use it to determine if their foreign table
668 * is a target relation.
669 * ----------------------------------------------------------------
670 */
671bool
672ExecRelationIsTargetRelation(EState *estate, Index scanrelid)
673{
674 ResultRelInfo *resultRelInfos;
675 int i;
676
677 resultRelInfos = estate->es_result_relations;
678 for (i = 0; i < estate->es_num_result_relations; i++)
679 {
680 if (resultRelInfos[i].ri_RangeTableIndex == scanrelid)
681 return true;
682 }
683 return false;
684}
685
686/* ----------------------------------------------------------------
687 * ExecOpenScanRelation
688 *
689 * Open the heap relation to be scanned by a base-level scan plan node.
690 * This should be called during the node's ExecInit routine.
691 * ----------------------------------------------------------------
692 */
693Relation
694ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags)
695{
696 Relation rel;
697
698 /* Open the relation. */
699 rel = ExecGetRangeTableRelation(estate, scanrelid);
700
701 /*
702 * Complain if we're attempting a scan of an unscannable relation, except
703 * when the query won't actually be run. This is a slightly klugy place
704 * to do this, perhaps, but there is no better place.
705 */
706 if ((eflags & (EXEC_FLAG_EXPLAIN_ONLY | EXEC_FLAG_WITH_NO_DATA)) == 0 &&
707 !RelationIsScannable(rel))
708 ereport(ERROR,
709 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
710 errmsg("materialized view \"%s\" has not been populated",
711 RelationGetRelationName(rel)),
712 errhint("Use the REFRESH MATERIALIZED VIEW command.")));
713
714 return rel;
715}
716
717/*
718 * ExecInitRangeTable
719 * Set up executor's range-table-related data
720 *
721 * We build an array from the range table list to allow faster lookup by RTI.
722 * (The es_range_table field is now somewhat redundant, but we keep it to
723 * avoid breaking external code unnecessarily.)
724 * This is also a convenient place to set up the parallel es_relations array.
725 */
726void
727ExecInitRangeTable(EState *estate, List *rangeTable)
728{
729 Index rti;
730 ListCell *lc;
731
732 /* Remember the range table List as-is */
733 estate->es_range_table = rangeTable;
734
735 /* Set up the equivalent array representation */
736 estate->es_range_table_size = list_length(rangeTable);
737 estate->es_range_table_array = (RangeTblEntry **)
738 palloc(estate->es_range_table_size * sizeof(RangeTblEntry *));
739 rti = 0;
740 foreach(lc, rangeTable)
741 {
742 estate->es_range_table_array[rti++] = lfirst_node(RangeTblEntry, lc);
743 }
744
745 /*
746 * Allocate an array to store an open Relation corresponding to each
747 * rangetable entry, and initialize entries to NULL. Relations are opened
748 * and stored here as needed.
749 */
750 estate->es_relations = (Relation *)
751 palloc0(estate->es_range_table_size * sizeof(Relation));
752
753 /*
754 * es_rowmarks is also parallel to the es_range_table_array, but it's
755 * allocated only if needed.
756 */
757 estate->es_rowmarks = NULL;
758}
759
760/*
761 * ExecGetRangeTableRelation
762 * Open the Relation for a range table entry, if not already done
763 *
764 * The Relations will be closed again in ExecEndPlan().
765 */
766Relation
767ExecGetRangeTableRelation(EState *estate, Index rti)
768{
769 Relation rel;
770
771 Assert(rti > 0 && rti <= estate->es_range_table_size);
772
773 rel = estate->es_relations[rti - 1];
774 if (rel == NULL)
775 {
776 /* First time through, so open the relation */
777 RangeTblEntry *rte = exec_rt_fetch(rti, estate);
778
779 Assert(rte->rtekind == RTE_RELATION);
780
781 if (!IsParallelWorker())
782 {
783 /*
784 * In a normal query, we should already have the appropriate lock,
785 * but verify that through an Assert. Since there's already an
786 * Assert inside table_open that insists on holding some lock, it
787 * seems sufficient to check this only when rellockmode is higher
788 * than the minimum.
789 */
790 rel = table_open(rte->relid, NoLock);
791 Assert(rte->rellockmode == AccessShareLock ||
792 CheckRelationLockedByMe(rel, rte->rellockmode, false));
793 }
794 else
795 {
796 /*
797 * If we are a parallel worker, we need to obtain our own local
798 * lock on the relation. This ensures sane behavior in case the
799 * parent process exits before we do.
800 */
801 rel = table_open(rte->relid, rte->rellockmode);
802 }
803
804 estate->es_relations[rti - 1] = rel;
805 }
806
807 return rel;
808}
809
810/*
811 * UpdateChangedParamSet
812 * Add changed parameters to a plan node's chgParam set
813 */
814void
815UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
816{
817 Bitmapset *parmset;
818
819 /*
820 * The plan node only depends on params listed in its allParam set. Don't
821 * include anything else into its chgParam set.
822 */
823 parmset = bms_intersect(node->plan->allParam, newchg);
824
825 /*
826 * Keep node->chgParam == NULL if there's not actually any members; this
827 * allows the simplest possible tests in executor node files.
828 */
829 if (!bms_is_empty(parmset))
830 node->chgParam = bms_join(node->chgParam, parmset);
831 else
832 bms_free(parmset);
833}
834
835/*
836 * executor_errposition
837 * Report an execution-time cursor position, if possible.
838 *
839 * This is expected to be used within an ereport() call. The return value
840 * is a dummy (always 0, in fact).
841 *
842 * The locations stored in parsetrees are byte offsets into the source string.
843 * We have to convert them to 1-based character indexes for reporting to
844 * clients. (We do things this way to avoid unnecessary overhead in the
845 * normal non-error case: computing character indexes would be much more
846 * expensive than storing token offsets.)
847 */
848int
849executor_errposition(EState *estate, int location)
850{
851 int pos;
852
853 /* No-op if location was not provided */
854 if (location < 0)
855 return 0;
856 /* Can't do anything if source text is not available */
857 if (estate == NULL || estate->es_sourceText == NULL)
858 return 0;
859 /* Convert offset to character number */
860 pos = pg_mbstrlen_with_len(estate->es_sourceText, location) + 1;
861 /* And pass it to the ereport mechanism */
862 return errposition(pos);
863}
864
865/*
866 * Register a shutdown callback in an ExprContext.
867 *
868 * Shutdown callbacks will be called (in reverse order of registration)
869 * when the ExprContext is deleted or rescanned. This provides a hook
870 * for functions called in the context to do any cleanup needed --- it's
871 * particularly useful for functions returning sets. Note that the
872 * callback will *not* be called in the event that execution is aborted
873 * by an error.
874 */
875void
876RegisterExprContextCallback(ExprContext *econtext,
877 ExprContextCallbackFunction function,
878 Datum arg)
879{
880 ExprContext_CB *ecxt_callback;
881
882 /* Save the info in appropriate memory context */
883 ecxt_callback = (ExprContext_CB *)
884 MemoryContextAlloc(econtext->ecxt_per_query_memory,
885 sizeof(ExprContext_CB));
886
887 ecxt_callback->function = function;
888 ecxt_callback->arg = arg;
889
890 /* link to front of list for appropriate execution order */
891 ecxt_callback->next = econtext->ecxt_callbacks;
892 econtext->ecxt_callbacks = ecxt_callback;
893}
894
895/*
896 * Deregister a shutdown callback in an ExprContext.
897 *
898 * Any list entries matching the function and arg will be removed.
899 * This can be used if it's no longer necessary to call the callback.
900 */
901void
902UnregisterExprContextCallback(ExprContext *econtext,
903 ExprContextCallbackFunction function,
904 Datum arg)
905{
906 ExprContext_CB **prev_callback;
907 ExprContext_CB *ecxt_callback;
908
909 prev_callback = &econtext->ecxt_callbacks;
910
911 while ((ecxt_callback = *prev_callback) != NULL)
912 {
913 if (ecxt_callback->function == function && ecxt_callback->arg == arg)
914 {
915 *prev_callback = ecxt_callback->next;
916 pfree(ecxt_callback);
917 }
918 else
919 prev_callback = &ecxt_callback->next;
920 }
921}
922
923/*
924 * Call all the shutdown callbacks registered in an ExprContext.
925 *
926 * The callback list is emptied (important in case this is only a rescan
927 * reset, and not deletion of the ExprContext).
928 *
929 * If isCommit is false, just clean the callback list but don't call 'em.
930 * (See comment for FreeExprContext.)
931 */
932static void
933ShutdownExprContext(ExprContext *econtext, bool isCommit)
934{
935 ExprContext_CB *ecxt_callback;
936 MemoryContext oldcontext;
937
938 /* Fast path in normal case where there's nothing to do. */
939 if (econtext->ecxt_callbacks == NULL)
940 return;
941
942 /*
943 * Call the callbacks in econtext's per-tuple context. This ensures that
944 * any memory they might leak will get cleaned up.
945 */
946 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
947
948 /*
949 * Call each callback function in reverse registration order.
950 */
951 while ((ecxt_callback = econtext->ecxt_callbacks) != NULL)
952 {
953 econtext->ecxt_callbacks = ecxt_callback->next;
954 if (isCommit)
955 ecxt_callback->function(ecxt_callback->arg);
956 pfree(ecxt_callback);
957 }
958
959 MemoryContextSwitchTo(oldcontext);
960}
961
962/*
963 * GetAttributeByName
964 * GetAttributeByNum
965 *
966 * These functions return the value of the requested attribute
967 * out of the given tuple Datum.
968 * C functions which take a tuple as an argument are expected
969 * to use these. Ex: overpaid(EMP) might call GetAttributeByNum().
970 * Note: these are actually rather slow because they do a typcache
971 * lookup on each call.
972 */
973Datum
974GetAttributeByName(HeapTupleHeader tuple, const char *attname, bool *isNull)
975{
976 AttrNumber attrno;
977 Datum result;
978 Oid tupType;
979 int32 tupTypmod;
980 TupleDesc tupDesc;
981 HeapTupleData tmptup;
982 int i;
983
984 if (attname == NULL)
985 elog(ERROR, "invalid attribute name");
986
987 if (isNull == NULL)
988 elog(ERROR, "a NULL isNull pointer was passed");
989
990 if (tuple == NULL)
991 {
992 /* Kinda bogus but compatible with old behavior... */
993 *isNull = true;
994 return (Datum) 0;
995 }
996
997 tupType = HeapTupleHeaderGetTypeId(tuple);
998 tupTypmod = HeapTupleHeaderGetTypMod(tuple);
999 tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
1000
1001 attrno = InvalidAttrNumber;
1002 for (i = 0; i < tupDesc->natts; i++)
1003 {
1004 Form_pg_attribute att = TupleDescAttr(tupDesc, i);
1005
1006 if (namestrcmp(&(att->attname), attname) == 0)
1007 {
1008 attrno = att->attnum;
1009 break;
1010 }
1011 }
1012
1013 if (attrno == InvalidAttrNumber)
1014 elog(ERROR, "attribute \"%s\" does not exist", attname);
1015
1016 /*
1017 * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
1018 * the fields in the struct just in case user tries to inspect system
1019 * columns.
1020 */
1021 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
1022 ItemPointerSetInvalid(&(tmptup.t_self));
1023 tmptup.t_tableOid = InvalidOid;
1024 tmptup.t_data = tuple;
1025
1026 result = heap_getattr(&tmptup,
1027 attrno,
1028 tupDesc,
1029 isNull);
1030
1031 ReleaseTupleDesc(tupDesc);
1032
1033 return result;
1034}
1035
1036Datum
1037GetAttributeByNum(HeapTupleHeader tuple,
1038 AttrNumber attrno,
1039 bool *isNull)
1040{
1041 Datum result;
1042 Oid tupType;
1043 int32 tupTypmod;
1044 TupleDesc tupDesc;
1045 HeapTupleData tmptup;
1046
1047 if (!AttributeNumberIsValid(attrno))
1048 elog(ERROR, "invalid attribute number %d", attrno);
1049
1050 if (isNull == NULL)
1051 elog(ERROR, "a NULL isNull pointer was passed");
1052
1053 if (tuple == NULL)
1054 {
1055 /* Kinda bogus but compatible with old behavior... */
1056 *isNull = true;
1057 return (Datum) 0;
1058 }
1059
1060 tupType = HeapTupleHeaderGetTypeId(tuple);
1061 tupTypmod = HeapTupleHeaderGetTypMod(tuple);
1062 tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
1063
1064 /*
1065 * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
1066 * the fields in the struct just in case user tries to inspect system
1067 * columns.
1068 */
1069 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
1070 ItemPointerSetInvalid(&(tmptup.t_self));
1071 tmptup.t_tableOid = InvalidOid;
1072 tmptup.t_data = tuple;
1073
1074 result = heap_getattr(&tmptup,
1075 attrno,
1076 tupDesc,
1077 isNull);
1078
1079 ReleaseTupleDesc(tupDesc);
1080
1081 return result;
1082}
1083
1084/*
1085 * Number of items in a tlist (including any resjunk items!)
1086 */
1087int
1088ExecTargetListLength(List *targetlist)
1089{
1090 /* This used to be more complex, but fjoins are dead */
1091 return list_length(targetlist);
1092}
1093
1094/*
1095 * Number of items in a tlist, not including any resjunk items
1096 */
1097int
1098ExecCleanTargetListLength(List *targetlist)
1099{
1100 int len = 0;
1101 ListCell *tl;
1102
1103 foreach(tl, targetlist)
1104 {
1105 TargetEntry *curTle = lfirst_node(TargetEntry, tl);
1106
1107 if (!curTle->resjunk)
1108 len++;
1109 }
1110 return len;
1111}
1112
1113/*
1114 * Return a relInfo's tuple slot for a trigger's OLD tuples.
1115 */
1116TupleTableSlot *
1117ExecGetTriggerOldSlot(EState *estate, ResultRelInfo *relInfo)
1118{
1119 if (relInfo->ri_TrigOldSlot == NULL)
1120 {
1121 Relation rel = relInfo->ri_RelationDesc;
1122 MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1123
1124 relInfo->ri_TrigOldSlot =
1125 ExecInitExtraTupleSlot(estate,
1126 RelationGetDescr(rel),
1127 table_slot_callbacks(rel));
1128
1129 MemoryContextSwitchTo(oldcontext);
1130 }
1131
1132 return relInfo->ri_TrigOldSlot;
1133}
1134
1135/*
1136 * Return a relInfo's tuple slot for a trigger's NEW tuples.
1137 */
1138TupleTableSlot *
1139ExecGetTriggerNewSlot(EState *estate, ResultRelInfo *relInfo)
1140{
1141 if (relInfo->ri_TrigNewSlot == NULL)
1142 {
1143 Relation rel = relInfo->ri_RelationDesc;
1144 MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1145
1146 relInfo->ri_TrigNewSlot =
1147 ExecInitExtraTupleSlot(estate,
1148 RelationGetDescr(rel),
1149 table_slot_callbacks(rel));
1150
1151 MemoryContextSwitchTo(oldcontext);
1152 }
1153
1154 return relInfo->ri_TrigNewSlot;
1155}
1156
1157/*
1158 * Return a relInfo's tuple slot for processing returning tuples.
1159 */
1160TupleTableSlot *
1161ExecGetReturningSlot(EState *estate, ResultRelInfo *relInfo)
1162{
1163 if (relInfo->ri_ReturningSlot == NULL)
1164 {
1165 Relation rel = relInfo->ri_RelationDesc;
1166 MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1167
1168 relInfo->ri_ReturningSlot =
1169 ExecInitExtraTupleSlot(estate,
1170 RelationGetDescr(rel),
1171 table_slot_callbacks(rel));
1172
1173 MemoryContextSwitchTo(oldcontext);
1174 }
1175
1176 return relInfo->ri_ReturningSlot;
1177}
1178