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