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