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