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