1 /*-------------------------------------------------------------------------
2  *
3  * execQual.c
4  *	  Routines to evaluate qualification and targetlist expressions
5  *
6  * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *	  src/backend/executor/execQual.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 /*
16  *	 INTERFACE ROUTINES
17  *		ExecEvalExpr	- (now a macro) evaluate an expression, return a datum
18  *		ExecEvalExprSwitchContext - same, but switch into eval memory context
19  *		ExecQual		- return true/false if qualification is satisfied
20  *		ExecProject		- form a new tuple by projecting the given tuple
21  *
22  *	 NOTES
23  *		The more heavily used ExecEvalExpr routines, such as ExecEvalScalarVar,
24  *		are hotspots. Making these faster will speed up the entire system.
25  *
26  *		ExecProject() is used to make tuple projections.  Rather then
27  *		trying to speed it up, the execution plan should be pre-processed
28  *		to facilitate attribute sharing between nodes wherever possible,
29  *		instead of doing needless copying.  -cim 5/31/91
30  *
31  *		During expression evaluation, we check_stack_depth only in
32  *		ExecMakeFunctionResult (and substitute routines) rather than at every
33  *		single node.  This is a compromise that trades off precision of the
34  *		stack limit setting to gain speed.
35  */
36 
37 #include "postgres.h"
38 
39 #include "access/htup_details.h"
40 #include "access/nbtree.h"
41 #include "access/tupconvert.h"
42 #include "catalog/objectaccess.h"
43 #include "catalog/pg_type.h"
44 #include "executor/execdebug.h"
45 #include "executor/nodeSubplan.h"
46 #include "funcapi.h"
47 #include "miscadmin.h"
48 #include "nodes/makefuncs.h"
49 #include "nodes/nodeFuncs.h"
50 #include "optimizer/planner.h"
51 #include "parser/parse_coerce.h"
52 #include "parser/parsetree.h"
53 #include "pgstat.h"
54 #include "utils/acl.h"
55 #include "utils/builtins.h"
56 #include "utils/lsyscache.h"
57 #include "utils/memutils.h"
58 #include "utils/typcache.h"
59 #include "utils/xml.h"
60 
61 
62 /* static function decls */
63 static Datum ExecEvalArrayRef(ArrayRefExprState *astate,
64 				 ExprContext *econtext,
65 				 bool *isNull, ExprDoneCond *isDone);
66 static bool isAssignmentIndirectionExpr(ExprState *exprstate);
67 static Datum ExecEvalAggref(AggrefExprState *aggref,
68 			   ExprContext *econtext,
69 			   bool *isNull, ExprDoneCond *isDone);
70 static Datum ExecEvalWindowFunc(WindowFuncExprState *wfunc,
71 				   ExprContext *econtext,
72 				   bool *isNull, ExprDoneCond *isDone);
73 static Datum ExecEvalScalarVar(ExprState *exprstate, ExprContext *econtext,
74 				  bool *isNull, ExprDoneCond *isDone);
75 static Datum ExecEvalScalarVarFast(ExprState *exprstate, ExprContext *econtext,
76 					  bool *isNull, ExprDoneCond *isDone);
77 static Datum ExecEvalWholeRowVar(WholeRowVarExprState *wrvstate,
78 					ExprContext *econtext,
79 					bool *isNull, ExprDoneCond *isDone);
80 static Datum ExecEvalWholeRowFast(WholeRowVarExprState *wrvstate,
81 					 ExprContext *econtext,
82 					 bool *isNull, ExprDoneCond *isDone);
83 static Datum ExecEvalWholeRowSlow(WholeRowVarExprState *wrvstate,
84 					 ExprContext *econtext,
85 					 bool *isNull, ExprDoneCond *isDone);
86 static Datum ExecEvalConst(ExprState *exprstate, ExprContext *econtext,
87 			  bool *isNull, ExprDoneCond *isDone);
88 static Datum ExecEvalParamExec(ExprState *exprstate, ExprContext *econtext,
89 				  bool *isNull, ExprDoneCond *isDone);
90 static Datum ExecEvalParamExtern(ExprState *exprstate, ExprContext *econtext,
91 					bool *isNull, ExprDoneCond *isDone);
92 static void init_fcache(Oid foid, Oid input_collation, FuncExprState *fcache,
93 			MemoryContext fcacheCxt, bool needDescForSets);
94 static void ShutdownFuncExpr(Datum arg);
95 static TupleDesc get_cached_rowtype(Oid type_id, int32 typmod,
96 				   TupleDesc *cache_field, ExprContext *econtext);
97 static void ShutdownTupleDescRef(Datum arg);
98 static ExprDoneCond ExecEvalFuncArgs(FunctionCallInfo fcinfo,
99 				 List *argList, ExprContext *econtext);
100 static void ExecPrepareTuplestoreResult(FuncExprState *fcache,
101 							ExprContext *econtext,
102 							Tuplestorestate *resultStore,
103 							TupleDesc resultDesc);
104 static void tupledesc_match(TupleDesc dst_tupdesc, TupleDesc src_tupdesc);
105 static Datum ExecMakeFunctionResult(FuncExprState *fcache,
106 					   ExprContext *econtext,
107 					   bool *isNull,
108 					   ExprDoneCond *isDone);
109 static Datum ExecMakeFunctionResultNoSets(FuncExprState *fcache,
110 							 ExprContext *econtext,
111 							 bool *isNull, ExprDoneCond *isDone);
112 static Datum ExecEvalFunc(FuncExprState *fcache, ExprContext *econtext,
113 			 bool *isNull, ExprDoneCond *isDone);
114 static Datum ExecEvalOper(FuncExprState *fcache, ExprContext *econtext,
115 			 bool *isNull, ExprDoneCond *isDone);
116 static Datum ExecEvalDistinct(FuncExprState *fcache, ExprContext *econtext,
117 				 bool *isNull, ExprDoneCond *isDone);
118 static Datum ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate,
119 					  ExprContext *econtext,
120 					  bool *isNull, ExprDoneCond *isDone);
121 static Datum ExecEvalNot(BoolExprState *notclause, ExprContext *econtext,
122 			bool *isNull, ExprDoneCond *isDone);
123 static Datum ExecEvalOr(BoolExprState *orExpr, ExprContext *econtext,
124 		   bool *isNull, ExprDoneCond *isDone);
125 static Datum ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
126 			bool *isNull, ExprDoneCond *isDone);
127 static Datum ExecEvalConvertRowtype(ConvertRowtypeExprState *cstate,
128 					   ExprContext *econtext,
129 					   bool *isNull, ExprDoneCond *isDone);
130 static Datum ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
131 			 bool *isNull, ExprDoneCond *isDone);
132 static Datum ExecEvalCaseTestExpr(ExprState *exprstate,
133 					 ExprContext *econtext,
134 					 bool *isNull, ExprDoneCond *isDone);
135 static Datum ExecEvalArray(ArrayExprState *astate,
136 			  ExprContext *econtext,
137 			  bool *isNull, ExprDoneCond *isDone);
138 static Datum ExecEvalRow(RowExprState *rstate,
139 			ExprContext *econtext,
140 			bool *isNull, ExprDoneCond *isDone);
141 static Datum ExecEvalRowCompare(RowCompareExprState *rstate,
142 				   ExprContext *econtext,
143 				   bool *isNull, ExprDoneCond *isDone);
144 static Datum ExecEvalCoalesce(CoalesceExprState *coalesceExpr,
145 				 ExprContext *econtext,
146 				 bool *isNull, ExprDoneCond *isDone);
147 static Datum ExecEvalMinMax(MinMaxExprState *minmaxExpr,
148 			   ExprContext *econtext,
149 			   bool *isNull, ExprDoneCond *isDone);
150 static Datum ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
151 			bool *isNull, ExprDoneCond *isDone);
152 static Datum ExecEvalNullIf(FuncExprState *nullIfExpr,
153 			   ExprContext *econtext,
154 			   bool *isNull, ExprDoneCond *isDone);
155 static Datum ExecEvalNullTest(NullTestState *nstate,
156 				 ExprContext *econtext,
157 				 bool *isNull, ExprDoneCond *isDone);
158 static Datum ExecEvalBooleanTest(GenericExprState *bstate,
159 					ExprContext *econtext,
160 					bool *isNull, ExprDoneCond *isDone);
161 static Datum ExecEvalCoerceToDomain(CoerceToDomainState *cstate,
162 					   ExprContext *econtext,
163 					   bool *isNull, ExprDoneCond *isDone);
164 static Datum ExecEvalCoerceToDomainValue(ExprState *exprstate,
165 							ExprContext *econtext,
166 							bool *isNull, ExprDoneCond *isDone);
167 static Datum ExecEvalFieldSelect(FieldSelectState *fstate,
168 					ExprContext *econtext,
169 					bool *isNull, ExprDoneCond *isDone);
170 static Datum ExecEvalFieldStore(FieldStoreState *fstate,
171 				   ExprContext *econtext,
172 				   bool *isNull, ExprDoneCond *isDone);
173 static Datum ExecEvalRelabelType(GenericExprState *exprstate,
174 					ExprContext *econtext,
175 					bool *isNull, ExprDoneCond *isDone);
176 static Datum ExecEvalCoerceViaIO(CoerceViaIOState *iostate,
177 					ExprContext *econtext,
178 					bool *isNull, ExprDoneCond *isDone);
179 static Datum ExecEvalArrayCoerceExpr(ArrayCoerceExprState *astate,
180 						ExprContext *econtext,
181 						bool *isNull, ExprDoneCond *isDone);
182 static Datum ExecEvalCurrentOfExpr(ExprState *exprstate, ExprContext *econtext,
183 					  bool *isNull, ExprDoneCond *isDone);
184 static Datum ExecEvalGroupingFuncExpr(GroupingFuncExprState *gstate,
185 						 ExprContext *econtext,
186 						 bool *isNull, ExprDoneCond *isDone);
187 
188 
189 /* ----------------------------------------------------------------
190  *		ExecEvalExpr routines
191  *
192  *		Recursively evaluate a targetlist or qualification expression.
193  *
194  * Each of the following routines having the signature
195  *		Datum ExecEvalFoo(ExprState *expression,
196  *						  ExprContext *econtext,
197  *						  bool *isNull,
198  *						  ExprDoneCond *isDone);
199  * is responsible for evaluating one type or subtype of ExprState node.
200  * They are normally called via the ExecEvalExpr macro, which makes use of
201  * the function pointer set up when the ExprState node was built by
202  * ExecInitExpr.  (In some cases, we change this pointer later to avoid
203  * re-executing one-time overhead.)
204  *
205  * Note: for notational simplicity we declare these functions as taking the
206  * specific type of ExprState that they work on.  This requires casting when
207  * assigning the function pointer in ExecInitExpr.  Be careful that the
208  * function signature is declared correctly, because the cast suppresses
209  * automatic checking!
210  *
211  *
212  * All these functions share this calling convention:
213  *
214  * Inputs:
215  *		expression: the expression state tree to evaluate
216  *		econtext: evaluation context information
217  *
218  * Outputs:
219  *		return value: Datum value of result
220  *		*isNull: set to TRUE if result is NULL (actual return value is
221  *				 meaningless if so); set to FALSE if non-null result
222  *		*isDone: set to indicator of set-result status
223  *
224  * A caller that can only accept a singleton (non-set) result should pass
225  * NULL for isDone; if the expression computes a set result then an error
226  * will be reported via ereport.  If the caller does pass an isDone pointer
227  * then *isDone is set to one of these three states:
228  *		ExprSingleResult		singleton result (not a set)
229  *		ExprMultipleResult		return value is one element of a set
230  *		ExprEndResult			there are no more elements in the set
231  * When ExprMultipleResult is returned, the caller should invoke
232  * ExecEvalExpr() repeatedly until ExprEndResult is returned.  ExprEndResult
233  * is returned after the last real set element.  For convenience isNull will
234  * always be set TRUE when ExprEndResult is returned, but this should not be
235  * taken as indicating a NULL element of the set.  Note that these return
236  * conventions allow us to distinguish among a singleton NULL, a NULL element
237  * of a set, and an empty set.
238  *
239  * The caller should already have switched into the temporary memory
240  * context econtext->ecxt_per_tuple_memory.  The convenience entry point
241  * ExecEvalExprSwitchContext() is provided for callers who don't prefer to
242  * do the switch in an outer loop.  We do not do the switch in these routines
243  * because it'd be a waste of cycles during nested expression evaluation.
244  * ----------------------------------------------------------------
245  */
246 
247 
248 /*----------
249  *	  ExecEvalArrayRef
250  *
251  *	   This function takes an ArrayRef and returns the extracted Datum
252  *	   if it's a simple reference, or the modified array value if it's
253  *	   an array assignment (i.e., array element or slice insertion).
254  *
255  * NOTE: if we get a NULL result from a subscript expression, we return NULL
256  * when it's an array reference, or raise an error when it's an assignment.
257  *----------
258  */
259 static Datum
ExecEvalArrayRef(ArrayRefExprState * astate,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)260 ExecEvalArrayRef(ArrayRefExprState *astate,
261 				 ExprContext *econtext,
262 				 bool *isNull,
263 				 ExprDoneCond *isDone)
264 {
265 	ArrayRef   *arrayRef = (ArrayRef *) astate->xprstate.expr;
266 	Datum		array_source;
267 	bool		isAssignment = (arrayRef->refassgnexpr != NULL);
268 	bool		eisnull;
269 	ListCell   *l;
270 	int			i = 0,
271 				j = 0;
272 	IntArray	upper,
273 				lower;
274 	bool		upperProvided[MAXDIM],
275 				lowerProvided[MAXDIM];
276 	int		   *lIndex;
277 
278 	array_source = ExecEvalExpr(astate->refexpr,
279 								econtext,
280 								isNull,
281 								isDone);
282 
283 	/*
284 	 * If refexpr yields NULL, and it's a fetch, then result is NULL. In the
285 	 * assignment case, we'll cons up something below.
286 	 */
287 	if (*isNull)
288 	{
289 		if (isDone && *isDone == ExprEndResult)
290 			return (Datum) NULL;	/* end of set result */
291 		if (!isAssignment)
292 			return (Datum) NULL;
293 	}
294 
295 	foreach(l, astate->refupperindexpr)
296 	{
297 		ExprState  *eltstate = (ExprState *) lfirst(l);
298 
299 		if (i >= MAXDIM)
300 			ereport(ERROR,
301 					(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
302 					 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
303 							i + 1, MAXDIM)));
304 
305 		if (eltstate == NULL)
306 		{
307 			/* Slice bound is omitted, so use array's upper bound */
308 			Assert(astate->reflowerindexpr != NIL);
309 			upperProvided[i++] = false;
310 			continue;
311 		}
312 		upperProvided[i] = true;
313 
314 		upper.indx[i++] = DatumGetInt32(ExecEvalExpr(eltstate,
315 													 econtext,
316 													 &eisnull,
317 													 NULL));
318 		/* If any index expr yields NULL, result is NULL or error */
319 		if (eisnull)
320 		{
321 			if (isAssignment)
322 				ereport(ERROR,
323 						(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
324 				  errmsg("array subscript in assignment must not be null")));
325 			*isNull = true;
326 			return (Datum) NULL;
327 		}
328 	}
329 
330 	if (astate->reflowerindexpr != NIL)
331 	{
332 		foreach(l, astate->reflowerindexpr)
333 		{
334 			ExprState  *eltstate = (ExprState *) lfirst(l);
335 
336 			if (j >= MAXDIM)
337 				ereport(ERROR,
338 						(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
339 						 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
340 								j + 1, MAXDIM)));
341 
342 			if (eltstate == NULL)
343 			{
344 				/* Slice bound is omitted, so use array's lower bound */
345 				lowerProvided[j++] = false;
346 				continue;
347 			}
348 			lowerProvided[j] = true;
349 
350 			lower.indx[j++] = DatumGetInt32(ExecEvalExpr(eltstate,
351 														 econtext,
352 														 &eisnull,
353 														 NULL));
354 			/* If any index expr yields NULL, result is NULL or error */
355 			if (eisnull)
356 			{
357 				if (isAssignment)
358 					ereport(ERROR,
359 							(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
360 							 errmsg("array subscript in assignment must not be null")));
361 				*isNull = true;
362 				return (Datum) NULL;
363 			}
364 		}
365 		/* this can't happen unless parser messed up */
366 		if (i != j)
367 			elog(ERROR, "upper and lower index lists are not same length");
368 		lIndex = lower.indx;
369 	}
370 	else
371 		lIndex = NULL;
372 
373 	if (isAssignment)
374 	{
375 		Datum		sourceData;
376 		Datum		save_datum;
377 		bool		save_isNull;
378 
379 		/*
380 		 * We might have a nested-assignment situation, in which the
381 		 * refassgnexpr is itself a FieldStore or ArrayRef that needs to
382 		 * obtain and modify the previous value of the array element or slice
383 		 * being replaced.  If so, we have to extract that value from the
384 		 * array and pass it down via the econtext's caseValue.  It's safe to
385 		 * reuse the CASE mechanism because there cannot be a CASE between
386 		 * here and where the value would be needed, and an array assignment
387 		 * can't be within a CASE either.  (So saving and restoring the
388 		 * caseValue is just paranoia, but let's do it anyway.)
389 		 *
390 		 * Since fetching the old element might be a nontrivial expense, do it
391 		 * only if the argument appears to actually need it.
392 		 */
393 		save_datum = econtext->caseValue_datum;
394 		save_isNull = econtext->caseValue_isNull;
395 
396 		if (isAssignmentIndirectionExpr(astate->refassgnexpr))
397 		{
398 			if (*isNull)
399 			{
400 				/* whole array is null, so any element or slice is too */
401 				econtext->caseValue_datum = (Datum) 0;
402 				econtext->caseValue_isNull = true;
403 			}
404 			else if (lIndex == NULL)
405 			{
406 				econtext->caseValue_datum =
407 					array_get_element(array_source, i,
408 									  upper.indx,
409 									  astate->refattrlength,
410 									  astate->refelemlength,
411 									  astate->refelembyval,
412 									  astate->refelemalign,
413 									  &econtext->caseValue_isNull);
414 			}
415 			else
416 			{
417 				econtext->caseValue_datum =
418 					array_get_slice(array_source, i,
419 									upper.indx, lower.indx,
420 									upperProvided, lowerProvided,
421 									astate->refattrlength,
422 									astate->refelemlength,
423 									astate->refelembyval,
424 									astate->refelemalign);
425 				econtext->caseValue_isNull = false;
426 			}
427 		}
428 		else
429 		{
430 			/* argument shouldn't need caseValue, but for safety set it null */
431 			econtext->caseValue_datum = (Datum) 0;
432 			econtext->caseValue_isNull = true;
433 		}
434 
435 		/*
436 		 * Evaluate the value to be assigned into the array.
437 		 */
438 		sourceData = ExecEvalExpr(astate->refassgnexpr,
439 								  econtext,
440 								  &eisnull,
441 								  NULL);
442 
443 		econtext->caseValue_datum = save_datum;
444 		econtext->caseValue_isNull = save_isNull;
445 
446 		/*
447 		 * For an assignment to a fixed-length array type, both the original
448 		 * array and the value to be assigned into it must be non-NULL, else
449 		 * we punt and return the original array.
450 		 */
451 		if (astate->refattrlength > 0)	/* fixed-length array? */
452 			if (eisnull || *isNull)
453 				return array_source;
454 
455 		/*
456 		 * For assignment to varlena arrays, we handle a NULL original array
457 		 * by substituting an empty (zero-dimensional) array; insertion of the
458 		 * new element will result in a singleton array value.  It does not
459 		 * matter whether the new element is NULL.
460 		 */
461 		if (*isNull)
462 		{
463 			array_source = PointerGetDatum(construct_empty_array(arrayRef->refelemtype));
464 			*isNull = false;
465 		}
466 
467 		if (lIndex == NULL)
468 			return array_set_element(array_source, i,
469 									 upper.indx,
470 									 sourceData,
471 									 eisnull,
472 									 astate->refattrlength,
473 									 astate->refelemlength,
474 									 astate->refelembyval,
475 									 astate->refelemalign);
476 		else
477 			return array_set_slice(array_source, i,
478 								   upper.indx, lower.indx,
479 								   upperProvided, lowerProvided,
480 								   sourceData,
481 								   eisnull,
482 								   astate->refattrlength,
483 								   astate->refelemlength,
484 								   astate->refelembyval,
485 								   astate->refelemalign);
486 	}
487 
488 	if (lIndex == NULL)
489 		return array_get_element(array_source, i,
490 								 upper.indx,
491 								 astate->refattrlength,
492 								 astate->refelemlength,
493 								 astate->refelembyval,
494 								 astate->refelemalign,
495 								 isNull);
496 	else
497 		return array_get_slice(array_source, i,
498 							   upper.indx, lower.indx,
499 							   upperProvided, lowerProvided,
500 							   astate->refattrlength,
501 							   astate->refelemlength,
502 							   astate->refelembyval,
503 							   astate->refelemalign);
504 }
505 
506 /*
507  * Helper for ExecEvalArrayRef: is expr a nested FieldStore or ArrayRef
508  * that might need the old element value passed down?
509  *
510  * (We could use this in ExecEvalFieldStore too, but in that case passing
511  * the old value is so cheap there's no need.)
512  */
513 static bool
isAssignmentIndirectionExpr(ExprState * exprstate)514 isAssignmentIndirectionExpr(ExprState *exprstate)
515 {
516 	if (exprstate == NULL)
517 		return false;			/* just paranoia */
518 	if (IsA(exprstate, FieldStoreState))
519 	{
520 		FieldStore *fstore = (FieldStore *) exprstate->expr;
521 
522 		if (fstore->arg && IsA(fstore->arg, CaseTestExpr))
523 			return true;
524 	}
525 	else if (IsA(exprstate, ArrayRefExprState))
526 	{
527 		ArrayRef   *arrayRef = (ArrayRef *) exprstate->expr;
528 
529 		if (arrayRef->refexpr && IsA(arrayRef->refexpr, CaseTestExpr))
530 			return true;
531 	}
532 	return false;
533 }
534 
535 /* ----------------------------------------------------------------
536  *		ExecEvalAggref
537  *
538  *		Returns a Datum whose value is the value of the precomputed
539  *		aggregate found in the given expression context.
540  * ----------------------------------------------------------------
541  */
542 static Datum
ExecEvalAggref(AggrefExprState * aggref,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)543 ExecEvalAggref(AggrefExprState *aggref, ExprContext *econtext,
544 			   bool *isNull, ExprDoneCond *isDone)
545 {
546 	if (isDone)
547 		*isDone = ExprSingleResult;
548 
549 	if (econtext->ecxt_aggvalues == NULL)		/* safety check */
550 		elog(ERROR, "no aggregates in this expression context");
551 
552 	*isNull = econtext->ecxt_aggnulls[aggref->aggno];
553 	return econtext->ecxt_aggvalues[aggref->aggno];
554 }
555 
556 /* ----------------------------------------------------------------
557  *		ExecEvalWindowFunc
558  *
559  *		Returns a Datum whose value is the value of the precomputed
560  *		window function found in the given expression context.
561  * ----------------------------------------------------------------
562  */
563 static Datum
ExecEvalWindowFunc(WindowFuncExprState * wfunc,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)564 ExecEvalWindowFunc(WindowFuncExprState *wfunc, ExprContext *econtext,
565 				   bool *isNull, ExprDoneCond *isDone)
566 {
567 	if (isDone)
568 		*isDone = ExprSingleResult;
569 
570 	if (econtext->ecxt_aggvalues == NULL)		/* safety check */
571 		elog(ERROR, "no window functions in this expression context");
572 
573 	*isNull = econtext->ecxt_aggnulls[wfunc->wfuncno];
574 	return econtext->ecxt_aggvalues[wfunc->wfuncno];
575 }
576 
577 /* ----------------------------------------------------------------
578  *		ExecEvalScalarVar
579  *
580  *		Returns a Datum whose value is the value of a scalar (not whole-row)
581  *		range variable with respect to given expression context.
582  *
583  * Note: ExecEvalScalarVar is executed only the first time through in a given
584  * plan; it changes the ExprState's function pointer to pass control directly
585  * to ExecEvalScalarVarFast after making one-time checks.
586  * ----------------------------------------------------------------
587  */
588 static Datum
ExecEvalScalarVar(ExprState * exprstate,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)589 ExecEvalScalarVar(ExprState *exprstate, ExprContext *econtext,
590 				  bool *isNull, ExprDoneCond *isDone)
591 {
592 	Var		   *variable = (Var *) exprstate->expr;
593 	TupleTableSlot *slot;
594 	AttrNumber	attnum;
595 
596 	if (isDone)
597 		*isDone = ExprSingleResult;
598 
599 	/* Get the input slot and attribute number we want */
600 	switch (variable->varno)
601 	{
602 		case INNER_VAR: /* get the tuple from the inner node */
603 			slot = econtext->ecxt_innertuple;
604 			break;
605 
606 		case OUTER_VAR: /* get the tuple from the outer node */
607 			slot = econtext->ecxt_outertuple;
608 			break;
609 
610 			/* INDEX_VAR is handled by default case */
611 
612 		default:				/* get the tuple from the relation being
613 								 * scanned */
614 			slot = econtext->ecxt_scantuple;
615 			break;
616 	}
617 
618 	attnum = variable->varattno;
619 
620 	/* This was checked by ExecInitExpr */
621 	Assert(attnum != InvalidAttrNumber);
622 
623 	/*
624 	 * If it's a user attribute, check validity (bogus system attnums will be
625 	 * caught inside slot_getattr).  What we have to check for here is the
626 	 * possibility of an attribute having been changed in type since the plan
627 	 * tree was created.  Ideally the plan will get invalidated and not
628 	 * re-used, but just in case, we keep these defenses.  Fortunately it's
629 	 * sufficient to check once on the first time through.
630 	 *
631 	 * Note: we allow a reference to a dropped attribute.  slot_getattr will
632 	 * force a NULL result in such cases.
633 	 *
634 	 * Note: ideally we'd check typmod as well as typid, but that seems
635 	 * impractical at the moment: in many cases the tupdesc will have been
636 	 * generated by ExecTypeFromTL(), and that can't guarantee to generate an
637 	 * accurate typmod in all cases, because some expression node types don't
638 	 * carry typmod.
639 	 */
640 	if (attnum > 0)
641 	{
642 		TupleDesc	slot_tupdesc = slot->tts_tupleDescriptor;
643 		Form_pg_attribute attr;
644 
645 		if (attnum > slot_tupdesc->natts)		/* should never happen */
646 			elog(ERROR, "attribute number %d exceeds number of columns %d",
647 				 attnum, slot_tupdesc->natts);
648 
649 		attr = slot_tupdesc->attrs[attnum - 1];
650 
651 		/* can't check type if dropped, since atttypid is probably 0 */
652 		if (!attr->attisdropped)
653 		{
654 			if (variable->vartype != attr->atttypid)
655 				ereport(ERROR,
656 						(errcode(ERRCODE_DATATYPE_MISMATCH),
657 						 errmsg("attribute %d has wrong type", attnum),
658 						 errdetail("Table has type %s, but query expects %s.",
659 								   format_type_be(attr->atttypid),
660 								   format_type_be(variable->vartype))));
661 		}
662 	}
663 
664 	/* Skip the checking on future executions of node */
665 	exprstate->evalfunc = ExecEvalScalarVarFast;
666 
667 	/* Fetch the value from the slot */
668 	return slot_getattr(slot, attnum, isNull);
669 }
670 
671 /* ----------------------------------------------------------------
672  *		ExecEvalScalarVarFast
673  *
674  *		Returns a Datum for a scalar variable.
675  * ----------------------------------------------------------------
676  */
677 static Datum
ExecEvalScalarVarFast(ExprState * exprstate,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)678 ExecEvalScalarVarFast(ExprState *exprstate, ExprContext *econtext,
679 					  bool *isNull, ExprDoneCond *isDone)
680 {
681 	Var		   *variable = (Var *) exprstate->expr;
682 	TupleTableSlot *slot;
683 	AttrNumber	attnum;
684 
685 	if (isDone)
686 		*isDone = ExprSingleResult;
687 
688 	/* Get the input slot and attribute number we want */
689 	switch (variable->varno)
690 	{
691 		case INNER_VAR: /* get the tuple from the inner node */
692 			slot = econtext->ecxt_innertuple;
693 			break;
694 
695 		case OUTER_VAR: /* get the tuple from the outer node */
696 			slot = econtext->ecxt_outertuple;
697 			break;
698 
699 			/* INDEX_VAR is handled by default case */
700 
701 		default:				/* get the tuple from the relation being
702 								 * scanned */
703 			slot = econtext->ecxt_scantuple;
704 			break;
705 	}
706 
707 	attnum = variable->varattno;
708 
709 	/* Fetch the value from the slot */
710 	return slot_getattr(slot, attnum, isNull);
711 }
712 
713 /* ----------------------------------------------------------------
714  *		ExecEvalWholeRowVar
715  *
716  *		Returns a Datum whose value is the value of a whole-row range
717  *		variable with respect to given expression context.
718  *
719  * Note: ExecEvalWholeRowVar is executed only the first time through in a
720  * given plan; it changes the ExprState's function pointer to pass control
721  * directly to ExecEvalWholeRowFast or ExecEvalWholeRowSlow after making
722  * one-time checks.
723  * ----------------------------------------------------------------
724  */
725 static Datum
ExecEvalWholeRowVar(WholeRowVarExprState * wrvstate,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)726 ExecEvalWholeRowVar(WholeRowVarExprState *wrvstate, ExprContext *econtext,
727 					bool *isNull, ExprDoneCond *isDone)
728 {
729 	Var		   *variable = (Var *) wrvstate->xprstate.expr;
730 	TupleTableSlot *slot;
731 	TupleDesc	output_tupdesc;
732 	MemoryContext oldcontext;
733 	bool		needslow = false;
734 
735 	if (isDone)
736 		*isDone = ExprSingleResult;
737 
738 	/* This was checked by ExecInitExpr */
739 	Assert(variable->varattno == InvalidAttrNumber);
740 
741 	/* Get the input slot we want */
742 	switch (variable->varno)
743 	{
744 		case INNER_VAR: /* get the tuple from the inner node */
745 			slot = econtext->ecxt_innertuple;
746 			break;
747 
748 		case OUTER_VAR: /* get the tuple from the outer node */
749 			slot = econtext->ecxt_outertuple;
750 			break;
751 
752 			/* INDEX_VAR is handled by default case */
753 
754 		default:				/* get the tuple from the relation being
755 								 * scanned */
756 			slot = econtext->ecxt_scantuple;
757 			break;
758 	}
759 
760 	/*
761 	 * If the input tuple came from a subquery, it might contain "resjunk"
762 	 * columns (such as GROUP BY or ORDER BY columns), which we don't want to
763 	 * keep in the whole-row result.  We can get rid of such columns by
764 	 * passing the tuple through a JunkFilter --- but to make one, we have to
765 	 * lay our hands on the subquery's targetlist.  Fortunately, there are not
766 	 * very many cases where this can happen, and we can identify all of them
767 	 * by examining our parent PlanState.  We assume this is not an issue in
768 	 * standalone expressions that don't have parent plans.  (Whole-row Vars
769 	 * can occur in such expressions, but they will always be referencing
770 	 * table rows.)
771 	 */
772 	if (wrvstate->parent)
773 	{
774 		PlanState  *subplan = NULL;
775 
776 		switch (nodeTag(wrvstate->parent))
777 		{
778 			case T_SubqueryScanState:
779 				subplan = ((SubqueryScanState *) wrvstate->parent)->subplan;
780 				break;
781 			case T_CteScanState:
782 				subplan = ((CteScanState *) wrvstate->parent)->cteplanstate;
783 				break;
784 			default:
785 				break;
786 		}
787 
788 		if (subplan)
789 		{
790 			bool		junk_filter_needed = false;
791 			ListCell   *tlist;
792 
793 			/* Detect whether subplan tlist actually has any junk columns */
794 			foreach(tlist, subplan->plan->targetlist)
795 			{
796 				TargetEntry *tle = (TargetEntry *) lfirst(tlist);
797 
798 				if (tle->resjunk)
799 				{
800 					junk_filter_needed = true;
801 					break;
802 				}
803 			}
804 
805 			/* If so, build the junkfilter in the query memory context */
806 			if (junk_filter_needed)
807 			{
808 				oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
809 				wrvstate->wrv_junkFilter =
810 					ExecInitJunkFilter(subplan->plan->targetlist,
811 									   ExecGetResultType(subplan)->tdhasoid,
812 							ExecInitExtraTupleSlot(wrvstate->parent->state));
813 				MemoryContextSwitchTo(oldcontext);
814 			}
815 		}
816 	}
817 
818 	/* Apply the junkfilter if any */
819 	if (wrvstate->wrv_junkFilter != NULL)
820 		slot = ExecFilterJunk(wrvstate->wrv_junkFilter, slot);
821 
822 	/*
823 	 * If the Var identifies a named composite type, we must check that the
824 	 * actual tuple type is compatible with it.
825 	 */
826 	if (variable->vartype != RECORDOID)
827 	{
828 		TupleDesc	var_tupdesc;
829 		TupleDesc	slot_tupdesc;
830 		int			i;
831 
832 		/*
833 		 * We really only care about numbers of attributes and data types.
834 		 * Also, we can ignore type mismatch on columns that are dropped in
835 		 * the destination type, so long as (1) the physical storage matches
836 		 * or (2) the actual column value is NULL.  Case (1) is helpful in
837 		 * some cases involving out-of-date cached plans, while case (2) is
838 		 * expected behavior in situations such as an INSERT into a table with
839 		 * dropped columns (the planner typically generates an INT4 NULL
840 		 * regardless of the dropped column type).  If we find a dropped
841 		 * column and cannot verify that case (1) holds, we have to use
842 		 * ExecEvalWholeRowSlow to check (2) for each row.
843 		 */
844 		var_tupdesc = lookup_rowtype_tupdesc(variable->vartype, -1);
845 
846 		slot_tupdesc = slot->tts_tupleDescriptor;
847 
848 		if (var_tupdesc->natts != slot_tupdesc->natts)
849 			ereport(ERROR,
850 					(errcode(ERRCODE_DATATYPE_MISMATCH),
851 					 errmsg("table row type and query-specified row type do not match"),
852 					 errdetail_plural("Table row contains %d attribute, but query expects %d.",
853 				   "Table row contains %d attributes, but query expects %d.",
854 									  slot_tupdesc->natts,
855 									  slot_tupdesc->natts,
856 									  var_tupdesc->natts)));
857 
858 		for (i = 0; i < var_tupdesc->natts; i++)
859 		{
860 			Form_pg_attribute vattr = var_tupdesc->attrs[i];
861 			Form_pg_attribute sattr = slot_tupdesc->attrs[i];
862 
863 			if (vattr->atttypid == sattr->atttypid)
864 				continue;		/* no worries */
865 			if (!vattr->attisdropped)
866 				ereport(ERROR,
867 						(errcode(ERRCODE_DATATYPE_MISMATCH),
868 						 errmsg("table row type and query-specified row type do not match"),
869 						 errdetail("Table has type %s at ordinal position %d, but query expects %s.",
870 								   format_type_be(sattr->atttypid),
871 								   i + 1,
872 								   format_type_be(vattr->atttypid))));
873 
874 			if (vattr->attlen != sattr->attlen ||
875 				vattr->attalign != sattr->attalign)
876 				needslow = true;	/* need runtime check for null */
877 		}
878 
879 		/*
880 		 * Use the variable's declared rowtype as the descriptor for the
881 		 * output values, modulo possibly assigning new column names below. In
882 		 * particular, we *must* absorb any attisdropped markings.
883 		 */
884 		oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
885 		output_tupdesc = CreateTupleDescCopy(var_tupdesc);
886 		MemoryContextSwitchTo(oldcontext);
887 
888 		ReleaseTupleDesc(var_tupdesc);
889 	}
890 	else
891 	{
892 		/*
893 		 * In the RECORD case, we use the input slot's rowtype as the
894 		 * descriptor for the output values, modulo possibly assigning new
895 		 * column names below.
896 		 */
897 		oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
898 		output_tupdesc = CreateTupleDescCopy(slot->tts_tupleDescriptor);
899 		MemoryContextSwitchTo(oldcontext);
900 	}
901 
902 	/*
903 	 * Construct a tuple descriptor for the composite values we'll produce,
904 	 * and make sure its record type is "blessed".  The main reason to do this
905 	 * is to be sure that operations such as row_to_json() will see the
906 	 * desired column names when they look up the descriptor from the type
907 	 * information embedded in the composite values.
908 	 *
909 	 * We already got the correct physical datatype info above, but now we
910 	 * should try to find the source RTE and adopt its column aliases, in case
911 	 * they are different from the original rowtype's names.  For example, in
912 	 * "SELECT foo(t) FROM tab t(x,y)", the first two columns in the composite
913 	 * output should be named "x" and "y" regardless of tab's column names.
914 	 *
915 	 * If we can't locate the RTE, assume the column names we've got are OK.
916 	 * (As of this writing, the only cases where we can't locate the RTE are
917 	 * in execution of trigger WHEN clauses, and then the Var will have the
918 	 * trigger's relation's rowtype, so its names are fine.)  Also, if the
919 	 * creator of the RTE didn't bother to fill in an eref field, assume our
920 	 * column names are OK.  (This happens in COPY, and perhaps other places.)
921 	 */
922 	if (econtext->ecxt_estate &&
923 		variable->varno <= list_length(econtext->ecxt_estate->es_range_table))
924 	{
925 		RangeTblEntry *rte = rt_fetch(variable->varno,
926 									  econtext->ecxt_estate->es_range_table);
927 
928 		if (rte->eref)
929 			ExecTypeSetColNames(output_tupdesc, rte->eref->colnames);
930 	}
931 
932 	/* Bless the tupdesc if needed, and save it in the execution state */
933 	wrvstate->wrv_tupdesc = BlessTupleDesc(output_tupdesc);
934 
935 	/* Skip all the above on future executions of node */
936 	if (needslow)
937 		wrvstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalWholeRowSlow;
938 	else
939 		wrvstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalWholeRowFast;
940 
941 	/* Fetch the value */
942 	return (*wrvstate->xprstate.evalfunc) ((ExprState *) wrvstate, econtext,
943 										   isNull, isDone);
944 }
945 
946 /* ----------------------------------------------------------------
947  *		ExecEvalWholeRowFast
948  *
949  *		Returns a Datum for a whole-row variable.
950  * ----------------------------------------------------------------
951  */
952 static Datum
ExecEvalWholeRowFast(WholeRowVarExprState * wrvstate,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)953 ExecEvalWholeRowFast(WholeRowVarExprState *wrvstate, ExprContext *econtext,
954 					 bool *isNull, ExprDoneCond *isDone)
955 {
956 	Var		   *variable = (Var *) wrvstate->xprstate.expr;
957 	TupleTableSlot *slot;
958 	HeapTupleHeader dtuple;
959 
960 	if (isDone)
961 		*isDone = ExprSingleResult;
962 	*isNull = false;
963 
964 	/* Get the input slot we want */
965 	switch (variable->varno)
966 	{
967 		case INNER_VAR: /* get the tuple from the inner node */
968 			slot = econtext->ecxt_innertuple;
969 			break;
970 
971 		case OUTER_VAR: /* get the tuple from the outer node */
972 			slot = econtext->ecxt_outertuple;
973 			break;
974 
975 			/* INDEX_VAR is handled by default case */
976 
977 		default:				/* get the tuple from the relation being
978 								 * scanned */
979 			slot = econtext->ecxt_scantuple;
980 			break;
981 	}
982 
983 	/* Apply the junkfilter if any */
984 	if (wrvstate->wrv_junkFilter != NULL)
985 		slot = ExecFilterJunk(wrvstate->wrv_junkFilter, slot);
986 
987 	/*
988 	 * Copy the slot tuple and make sure any toasted fields get detoasted.
989 	 */
990 	dtuple = DatumGetHeapTupleHeader(ExecFetchSlotTupleDatum(slot));
991 
992 	/*
993 	 * Label the datum with the composite type info we identified before.
994 	 */
995 	HeapTupleHeaderSetTypeId(dtuple, wrvstate->wrv_tupdesc->tdtypeid);
996 	HeapTupleHeaderSetTypMod(dtuple, wrvstate->wrv_tupdesc->tdtypmod);
997 
998 	return PointerGetDatum(dtuple);
999 }
1000 
1001 /* ----------------------------------------------------------------
1002  *		ExecEvalWholeRowSlow
1003  *
1004  *		Returns a Datum for a whole-row variable, in the "slow" case where
1005  *		we can't just copy the subplan's output.
1006  * ----------------------------------------------------------------
1007  */
1008 static Datum
ExecEvalWholeRowSlow(WholeRowVarExprState * wrvstate,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)1009 ExecEvalWholeRowSlow(WholeRowVarExprState *wrvstate, ExprContext *econtext,
1010 					 bool *isNull, ExprDoneCond *isDone)
1011 {
1012 	Var		   *variable = (Var *) wrvstate->xprstate.expr;
1013 	TupleTableSlot *slot;
1014 	HeapTuple	tuple;
1015 	TupleDesc	tupleDesc;
1016 	TupleDesc	var_tupdesc;
1017 	HeapTupleHeader dtuple;
1018 	int			i;
1019 
1020 	if (isDone)
1021 		*isDone = ExprSingleResult;
1022 	*isNull = false;
1023 
1024 	/* Get the input slot we want */
1025 	switch (variable->varno)
1026 	{
1027 		case INNER_VAR: /* get the tuple from the inner node */
1028 			slot = econtext->ecxt_innertuple;
1029 			break;
1030 
1031 		case OUTER_VAR: /* get the tuple from the outer node */
1032 			slot = econtext->ecxt_outertuple;
1033 			break;
1034 
1035 			/* INDEX_VAR is handled by default case */
1036 
1037 		default:				/* get the tuple from the relation being
1038 								 * scanned */
1039 			slot = econtext->ecxt_scantuple;
1040 			break;
1041 	}
1042 
1043 	/* Apply the junkfilter if any */
1044 	if (wrvstate->wrv_junkFilter != NULL)
1045 		slot = ExecFilterJunk(wrvstate->wrv_junkFilter, slot);
1046 
1047 	tuple = ExecFetchSlotTuple(slot);
1048 	tupleDesc = slot->tts_tupleDescriptor;
1049 
1050 	/* wrv_tupdesc is a good enough representation of the Var's rowtype */
1051 	Assert(variable->vartype != RECORDOID);
1052 	var_tupdesc = wrvstate->wrv_tupdesc;
1053 
1054 	/* Check to see if any dropped attributes are non-null */
1055 	for (i = 0; i < var_tupdesc->natts; i++)
1056 	{
1057 		Form_pg_attribute vattr = var_tupdesc->attrs[i];
1058 		Form_pg_attribute sattr = tupleDesc->attrs[i];
1059 
1060 		if (!vattr->attisdropped)
1061 			continue;			/* already checked non-dropped cols */
1062 		if (heap_attisnull(tuple, i + 1))
1063 			continue;			/* null is always okay */
1064 		if (vattr->attlen != sattr->attlen ||
1065 			vattr->attalign != sattr->attalign)
1066 			ereport(ERROR,
1067 					(errcode(ERRCODE_DATATYPE_MISMATCH),
1068 					 errmsg("table row type and query-specified row type do not match"),
1069 					 errdetail("Physical storage mismatch on dropped attribute at ordinal position %d.",
1070 							   i + 1)));
1071 	}
1072 
1073 	/*
1074 	 * Copy the slot tuple and make sure any toasted fields get detoasted.
1075 	 */
1076 	dtuple = DatumGetHeapTupleHeader(ExecFetchSlotTupleDatum(slot));
1077 
1078 	/*
1079 	 * Label the datum with the composite type info we identified before.
1080 	 */
1081 	HeapTupleHeaderSetTypeId(dtuple, wrvstate->wrv_tupdesc->tdtypeid);
1082 	HeapTupleHeaderSetTypMod(dtuple, wrvstate->wrv_tupdesc->tdtypmod);
1083 
1084 	return PointerGetDatum(dtuple);
1085 }
1086 
1087 /* ----------------------------------------------------------------
1088  *		ExecEvalConst
1089  *
1090  *		Returns the value of a constant.
1091  *
1092  *		Note that for pass-by-ref datatypes, we return a pointer to the
1093  *		actual constant node.  This is one of the reasons why functions
1094  *		must treat their input arguments as read-only.
1095  * ----------------------------------------------------------------
1096  */
1097 static Datum
ExecEvalConst(ExprState * exprstate,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)1098 ExecEvalConst(ExprState *exprstate, ExprContext *econtext,
1099 			  bool *isNull, ExprDoneCond *isDone)
1100 {
1101 	Const	   *con = (Const *) exprstate->expr;
1102 
1103 	if (isDone)
1104 		*isDone = ExprSingleResult;
1105 
1106 	*isNull = con->constisnull;
1107 	return con->constvalue;
1108 }
1109 
1110 /* ----------------------------------------------------------------
1111  *		ExecEvalParamExec
1112  *
1113  *		Returns the value of a PARAM_EXEC parameter.
1114  * ----------------------------------------------------------------
1115  */
1116 static Datum
ExecEvalParamExec(ExprState * exprstate,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)1117 ExecEvalParamExec(ExprState *exprstate, ExprContext *econtext,
1118 				  bool *isNull, ExprDoneCond *isDone)
1119 {
1120 	Param	   *expression = (Param *) exprstate->expr;
1121 	int			thisParamId = expression->paramid;
1122 	ParamExecData *prm;
1123 
1124 	if (isDone)
1125 		*isDone = ExprSingleResult;
1126 
1127 	/*
1128 	 * PARAM_EXEC params (internal executor parameters) are stored in the
1129 	 * ecxt_param_exec_vals array, and can be accessed by array index.
1130 	 */
1131 	prm = &(econtext->ecxt_param_exec_vals[thisParamId]);
1132 	if (prm->execPlan != NULL)
1133 	{
1134 		/* Parameter not evaluated yet, so go do it */
1135 		ExecSetParamPlan(prm->execPlan, econtext);
1136 		/* ExecSetParamPlan should have processed this param... */
1137 		Assert(prm->execPlan == NULL);
1138 	}
1139 	*isNull = prm->isnull;
1140 	return prm->value;
1141 }
1142 
1143 /* ----------------------------------------------------------------
1144  *		ExecEvalParamExtern
1145  *
1146  *		Returns the value of a PARAM_EXTERN parameter.
1147  * ----------------------------------------------------------------
1148  */
1149 static Datum
ExecEvalParamExtern(ExprState * exprstate,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)1150 ExecEvalParamExtern(ExprState *exprstate, ExprContext *econtext,
1151 					bool *isNull, ExprDoneCond *isDone)
1152 {
1153 	Param	   *expression = (Param *) exprstate->expr;
1154 	int			thisParamId = expression->paramid;
1155 	ParamListInfo paramInfo = econtext->ecxt_param_list_info;
1156 
1157 	if (isDone)
1158 		*isDone = ExprSingleResult;
1159 
1160 	/*
1161 	 * PARAM_EXTERN parameters must be sought in ecxt_param_list_info.
1162 	 */
1163 	if (paramInfo &&
1164 		thisParamId > 0 && thisParamId <= paramInfo->numParams)
1165 	{
1166 		ParamExternData *prm = &paramInfo->params[thisParamId - 1];
1167 
1168 		/* give hook a chance in case parameter is dynamic */
1169 		if (!OidIsValid(prm->ptype) && paramInfo->paramFetch != NULL)
1170 			(*paramInfo->paramFetch) (paramInfo, thisParamId);
1171 
1172 		if (OidIsValid(prm->ptype))
1173 		{
1174 			/* safety check in case hook did something unexpected */
1175 			if (prm->ptype != expression->paramtype)
1176 				ereport(ERROR,
1177 						(errcode(ERRCODE_DATATYPE_MISMATCH),
1178 						 errmsg("type of parameter %d (%s) does not match that when preparing the plan (%s)",
1179 								thisParamId,
1180 								format_type_be(prm->ptype),
1181 								format_type_be(expression->paramtype))));
1182 
1183 			*isNull = prm->isnull;
1184 			return prm->value;
1185 		}
1186 	}
1187 
1188 	ereport(ERROR,
1189 			(errcode(ERRCODE_UNDEFINED_OBJECT),
1190 			 errmsg("no value found for parameter %d", thisParamId)));
1191 	return (Datum) 0;			/* keep compiler quiet */
1192 }
1193 
1194 
1195 /* ----------------------------------------------------------------
1196  *		ExecEvalOper / ExecEvalFunc support routines
1197  * ----------------------------------------------------------------
1198  */
1199 
1200 /*
1201  *		GetAttributeByName
1202  *		GetAttributeByNum
1203  *
1204  *		These functions return the value of the requested attribute
1205  *		out of the given tuple Datum.
1206  *		C functions which take a tuple as an argument are expected
1207  *		to use these.  Ex: overpaid(EMP) might call GetAttributeByNum().
1208  *		Note: these are actually rather slow because they do a typcache
1209  *		lookup on each call.
1210  */
1211 Datum
GetAttributeByNum(HeapTupleHeader tuple,AttrNumber attrno,bool * isNull)1212 GetAttributeByNum(HeapTupleHeader tuple,
1213 				  AttrNumber attrno,
1214 				  bool *isNull)
1215 {
1216 	Datum		result;
1217 	Oid			tupType;
1218 	int32		tupTypmod;
1219 	TupleDesc	tupDesc;
1220 	HeapTupleData tmptup;
1221 
1222 	if (!AttributeNumberIsValid(attrno))
1223 		elog(ERROR, "invalid attribute number %d", attrno);
1224 
1225 	if (isNull == NULL)
1226 		elog(ERROR, "a NULL isNull pointer was passed");
1227 
1228 	if (tuple == NULL)
1229 	{
1230 		/* Kinda bogus but compatible with old behavior... */
1231 		*isNull = true;
1232 		return (Datum) 0;
1233 	}
1234 
1235 	tupType = HeapTupleHeaderGetTypeId(tuple);
1236 	tupTypmod = HeapTupleHeaderGetTypMod(tuple);
1237 	tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
1238 
1239 	/*
1240 	 * heap_getattr needs a HeapTuple not a bare HeapTupleHeader.  We set all
1241 	 * the fields in the struct just in case user tries to inspect system
1242 	 * columns.
1243 	 */
1244 	tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
1245 	ItemPointerSetInvalid(&(tmptup.t_self));
1246 	tmptup.t_tableOid = InvalidOid;
1247 	tmptup.t_data = tuple;
1248 
1249 	result = heap_getattr(&tmptup,
1250 						  attrno,
1251 						  tupDesc,
1252 						  isNull);
1253 
1254 	ReleaseTupleDesc(tupDesc);
1255 
1256 	return result;
1257 }
1258 
1259 Datum
GetAttributeByName(HeapTupleHeader tuple,const char * attname,bool * isNull)1260 GetAttributeByName(HeapTupleHeader tuple, const char *attname, bool *isNull)
1261 {
1262 	AttrNumber	attrno;
1263 	Datum		result;
1264 	Oid			tupType;
1265 	int32		tupTypmod;
1266 	TupleDesc	tupDesc;
1267 	HeapTupleData tmptup;
1268 	int			i;
1269 
1270 	if (attname == NULL)
1271 		elog(ERROR, "invalid attribute name");
1272 
1273 	if (isNull == NULL)
1274 		elog(ERROR, "a NULL isNull pointer was passed");
1275 
1276 	if (tuple == NULL)
1277 	{
1278 		/* Kinda bogus but compatible with old behavior... */
1279 		*isNull = true;
1280 		return (Datum) 0;
1281 	}
1282 
1283 	tupType = HeapTupleHeaderGetTypeId(tuple);
1284 	tupTypmod = HeapTupleHeaderGetTypMod(tuple);
1285 	tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
1286 
1287 	attrno = InvalidAttrNumber;
1288 	for (i = 0; i < tupDesc->natts; i++)
1289 	{
1290 		if (namestrcmp(&(tupDesc->attrs[i]->attname), attname) == 0)
1291 		{
1292 			attrno = tupDesc->attrs[i]->attnum;
1293 			break;
1294 		}
1295 	}
1296 
1297 	if (attrno == InvalidAttrNumber)
1298 		elog(ERROR, "attribute \"%s\" does not exist", attname);
1299 
1300 	/*
1301 	 * heap_getattr needs a HeapTuple not a bare HeapTupleHeader.  We set all
1302 	 * the fields in the struct just in case user tries to inspect system
1303 	 * columns.
1304 	 */
1305 	tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
1306 	ItemPointerSetInvalid(&(tmptup.t_self));
1307 	tmptup.t_tableOid = InvalidOid;
1308 	tmptup.t_data = tuple;
1309 
1310 	result = heap_getattr(&tmptup,
1311 						  attrno,
1312 						  tupDesc,
1313 						  isNull);
1314 
1315 	ReleaseTupleDesc(tupDesc);
1316 
1317 	return result;
1318 }
1319 
1320 /*
1321  * init_fcache - initialize a FuncExprState node during first use
1322  */
1323 static void
init_fcache(Oid foid,Oid input_collation,FuncExprState * fcache,MemoryContext fcacheCxt,bool needDescForSets)1324 init_fcache(Oid foid, Oid input_collation, FuncExprState *fcache,
1325 			MemoryContext fcacheCxt, bool needDescForSets)
1326 {
1327 	AclResult	aclresult;
1328 
1329 	/* Check permission to call function */
1330 	aclresult = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE);
1331 	if (aclresult != ACLCHECK_OK)
1332 		aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(foid));
1333 	InvokeFunctionExecuteHook(foid);
1334 
1335 	/*
1336 	 * Safety check on nargs.  Under normal circumstances this should never
1337 	 * fail, as parser should check sooner.  But possibly it might fail if
1338 	 * server has been compiled with FUNC_MAX_ARGS smaller than some functions
1339 	 * declared in pg_proc?
1340 	 */
1341 	if (list_length(fcache->args) > FUNC_MAX_ARGS)
1342 		ereport(ERROR,
1343 				(errcode(ERRCODE_TOO_MANY_ARGUMENTS),
1344 			 errmsg_plural("cannot pass more than %d argument to a function",
1345 						   "cannot pass more than %d arguments to a function",
1346 						   FUNC_MAX_ARGS,
1347 						   FUNC_MAX_ARGS)));
1348 
1349 	/* Set up the primary fmgr lookup information */
1350 	fmgr_info_cxt(foid, &(fcache->func), fcacheCxt);
1351 	fmgr_info_set_expr((Node *) fcache->xprstate.expr, &(fcache->func));
1352 
1353 	/* Initialize the function call parameter struct as well */
1354 	InitFunctionCallInfoData(fcache->fcinfo_data, &(fcache->func),
1355 							 list_length(fcache->args),
1356 							 input_collation, NULL, NULL);
1357 
1358 	/* If function returns set, prepare expected tuple descriptor */
1359 	if (fcache->func.fn_retset && needDescForSets)
1360 	{
1361 		TypeFuncClass functypclass;
1362 		Oid			funcrettype;
1363 		TupleDesc	tupdesc;
1364 		MemoryContext oldcontext;
1365 
1366 		functypclass = get_expr_result_type(fcache->func.fn_expr,
1367 											&funcrettype,
1368 											&tupdesc);
1369 
1370 		/* Must save tupdesc in fcache's context */
1371 		oldcontext = MemoryContextSwitchTo(fcacheCxt);
1372 
1373 		if (functypclass == TYPEFUNC_COMPOSITE)
1374 		{
1375 			/* Composite data type, e.g. a table's row type */
1376 			Assert(tupdesc);
1377 			/* Must copy it out of typcache for safety */
1378 			fcache->funcResultDesc = CreateTupleDescCopy(tupdesc);
1379 			fcache->funcReturnsTuple = true;
1380 		}
1381 		else if (functypclass == TYPEFUNC_SCALAR)
1382 		{
1383 			/* Base data type, i.e. scalar */
1384 			tupdesc = CreateTemplateTupleDesc(1, false);
1385 			TupleDescInitEntry(tupdesc,
1386 							   (AttrNumber) 1,
1387 							   NULL,
1388 							   funcrettype,
1389 							   -1,
1390 							   0);
1391 			fcache->funcResultDesc = tupdesc;
1392 			fcache->funcReturnsTuple = false;
1393 		}
1394 		else if (functypclass == TYPEFUNC_RECORD)
1395 		{
1396 			/* This will work if function doesn't need an expectedDesc */
1397 			fcache->funcResultDesc = NULL;
1398 			fcache->funcReturnsTuple = true;
1399 		}
1400 		else
1401 		{
1402 			/* Else, we will fail if function needs an expectedDesc */
1403 			fcache->funcResultDesc = NULL;
1404 		}
1405 
1406 		MemoryContextSwitchTo(oldcontext);
1407 	}
1408 	else
1409 		fcache->funcResultDesc = NULL;
1410 
1411 	/* Initialize additional state */
1412 	fcache->funcResultStore = NULL;
1413 	fcache->funcResultSlot = NULL;
1414 	fcache->setArgsValid = false;
1415 	fcache->shutdown_reg = false;
1416 }
1417 
1418 /*
1419  * callback function in case a FuncExpr returning a set needs to be shut down
1420  * before it has been run to completion
1421  */
1422 static void
ShutdownFuncExpr(Datum arg)1423 ShutdownFuncExpr(Datum arg)
1424 {
1425 	FuncExprState *fcache = (FuncExprState *) DatumGetPointer(arg);
1426 
1427 	/* If we have a slot, make sure it's let go of any tuplestore pointer */
1428 	if (fcache->funcResultSlot)
1429 		ExecClearTuple(fcache->funcResultSlot);
1430 
1431 	/* Release any open tuplestore */
1432 	if (fcache->funcResultStore)
1433 		tuplestore_end(fcache->funcResultStore);
1434 	fcache->funcResultStore = NULL;
1435 
1436 	/* Clear any active set-argument state */
1437 	fcache->setArgsValid = false;
1438 
1439 	/* execUtils will deregister the callback... */
1440 	fcache->shutdown_reg = false;
1441 }
1442 
1443 /*
1444  * get_cached_rowtype: utility function to lookup a rowtype tupdesc
1445  *
1446  * type_id, typmod: identity of the rowtype
1447  * cache_field: where to cache the TupleDesc pointer in expression state node
1448  *		(field must be initialized to NULL)
1449  * econtext: expression context we are executing in
1450  *
1451  * NOTE: because the shutdown callback will be called during plan rescan,
1452  * must be prepared to re-do this during any node execution; cannot call
1453  * just once during expression initialization
1454  */
1455 static TupleDesc
get_cached_rowtype(Oid type_id,int32 typmod,TupleDesc * cache_field,ExprContext * econtext)1456 get_cached_rowtype(Oid type_id, int32 typmod,
1457 				   TupleDesc *cache_field, ExprContext *econtext)
1458 {
1459 	TupleDesc	tupDesc = *cache_field;
1460 
1461 	/* Do lookup if no cached value or if requested type changed */
1462 	if (tupDesc == NULL ||
1463 		type_id != tupDesc->tdtypeid ||
1464 		typmod != tupDesc->tdtypmod)
1465 	{
1466 		tupDesc = lookup_rowtype_tupdesc(type_id, typmod);
1467 
1468 		if (*cache_field)
1469 		{
1470 			/* Release old tupdesc; but callback is already registered */
1471 			ReleaseTupleDesc(*cache_field);
1472 		}
1473 		else
1474 		{
1475 			/* Need to register shutdown callback to release tupdesc */
1476 			RegisterExprContextCallback(econtext,
1477 										ShutdownTupleDescRef,
1478 										PointerGetDatum(cache_field));
1479 		}
1480 		*cache_field = tupDesc;
1481 	}
1482 	return tupDesc;
1483 }
1484 
1485 /*
1486  * Callback function to release a tupdesc refcount at expression tree shutdown
1487  */
1488 static void
ShutdownTupleDescRef(Datum arg)1489 ShutdownTupleDescRef(Datum arg)
1490 {
1491 	TupleDesc  *cache_field = (TupleDesc *) DatumGetPointer(arg);
1492 
1493 	if (*cache_field)
1494 		ReleaseTupleDesc(*cache_field);
1495 	*cache_field = NULL;
1496 }
1497 
1498 /*
1499  * Evaluate arguments for a function.
1500  */
1501 static ExprDoneCond
ExecEvalFuncArgs(FunctionCallInfo fcinfo,List * argList,ExprContext * econtext)1502 ExecEvalFuncArgs(FunctionCallInfo fcinfo,
1503 				 List *argList,
1504 				 ExprContext *econtext)
1505 {
1506 	ExprDoneCond argIsDone;
1507 	int			i;
1508 	ListCell   *arg;
1509 
1510 	argIsDone = ExprSingleResult;		/* default assumption */
1511 
1512 	i = 0;
1513 	foreach(arg, argList)
1514 	{
1515 		ExprState  *argstate = (ExprState *) lfirst(arg);
1516 		ExprDoneCond thisArgIsDone;
1517 
1518 		fcinfo->arg[i] = ExecEvalExpr(argstate,
1519 									  econtext,
1520 									  &fcinfo->argnull[i],
1521 									  &thisArgIsDone);
1522 
1523 		if (thisArgIsDone != ExprSingleResult)
1524 		{
1525 			/*
1526 			 * We allow only one argument to have a set value; we'd need much
1527 			 * more complexity to keep track of multiple set arguments (cf.
1528 			 * ExecTargetList) and it doesn't seem worth it.
1529 			 */
1530 			if (argIsDone != ExprSingleResult)
1531 				ereport(ERROR,
1532 						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1533 						 errmsg("functions and operators can take at most one set argument")));
1534 			argIsDone = thisArgIsDone;
1535 		}
1536 		i++;
1537 	}
1538 
1539 	Assert(i == fcinfo->nargs);
1540 
1541 	return argIsDone;
1542 }
1543 
1544 /*
1545  *		ExecPrepareTuplestoreResult
1546  *
1547  * Subroutine for ExecMakeFunctionResult: prepare to extract rows from a
1548  * tuplestore function result.  We must set up a funcResultSlot (unless
1549  * already done in a previous call cycle) and verify that the function
1550  * returned the expected tuple descriptor.
1551  */
1552 static void
ExecPrepareTuplestoreResult(FuncExprState * fcache,ExprContext * econtext,Tuplestorestate * resultStore,TupleDesc resultDesc)1553 ExecPrepareTuplestoreResult(FuncExprState *fcache,
1554 							ExprContext *econtext,
1555 							Tuplestorestate *resultStore,
1556 							TupleDesc resultDesc)
1557 {
1558 	fcache->funcResultStore = resultStore;
1559 
1560 	if (fcache->funcResultSlot == NULL)
1561 	{
1562 		/* Create a slot so we can read data out of the tuplestore */
1563 		TupleDesc	slotDesc;
1564 		MemoryContext oldcontext;
1565 
1566 		oldcontext = MemoryContextSwitchTo(fcache->func.fn_mcxt);
1567 
1568 		/*
1569 		 * If we were not able to determine the result rowtype from context,
1570 		 * and the function didn't return a tupdesc, we have to fail.
1571 		 */
1572 		if (fcache->funcResultDesc)
1573 			slotDesc = fcache->funcResultDesc;
1574 		else if (resultDesc)
1575 		{
1576 			/* don't assume resultDesc is long-lived */
1577 			slotDesc = CreateTupleDescCopy(resultDesc);
1578 		}
1579 		else
1580 		{
1581 			ereport(ERROR,
1582 					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1583 					 errmsg("function returning setof record called in "
1584 							"context that cannot accept type record")));
1585 			slotDesc = NULL;	/* keep compiler quiet */
1586 		}
1587 
1588 		fcache->funcResultSlot = MakeSingleTupleTableSlot(slotDesc);
1589 		MemoryContextSwitchTo(oldcontext);
1590 	}
1591 
1592 	/*
1593 	 * If function provided a tupdesc, cross-check it.  We only really need to
1594 	 * do this for functions returning RECORD, but might as well do it always.
1595 	 */
1596 	if (resultDesc)
1597 	{
1598 		if (fcache->funcResultDesc)
1599 			tupledesc_match(fcache->funcResultDesc, resultDesc);
1600 
1601 		/*
1602 		 * If it is a dynamically-allocated TupleDesc, free it: it is
1603 		 * typically allocated in a per-query context, so we must avoid
1604 		 * leaking it across multiple usages.
1605 		 */
1606 		if (resultDesc->tdrefcount == -1)
1607 			FreeTupleDesc(resultDesc);
1608 	}
1609 
1610 	/* Register cleanup callback if we didn't already */
1611 	if (!fcache->shutdown_reg)
1612 	{
1613 		RegisterExprContextCallback(econtext,
1614 									ShutdownFuncExpr,
1615 									PointerGetDatum(fcache));
1616 		fcache->shutdown_reg = true;
1617 	}
1618 }
1619 
1620 /*
1621  * Check that function result tuple type (src_tupdesc) matches or can
1622  * be considered to match what the query expects (dst_tupdesc). If
1623  * they don't match, ereport.
1624  *
1625  * We really only care about number of attributes and data type.
1626  * Also, we can ignore type mismatch on columns that are dropped in the
1627  * destination type, so long as the physical storage matches.  This is
1628  * helpful in some cases involving out-of-date cached plans.
1629  */
1630 static void
tupledesc_match(TupleDesc dst_tupdesc,TupleDesc src_tupdesc)1631 tupledesc_match(TupleDesc dst_tupdesc, TupleDesc src_tupdesc)
1632 {
1633 	int			i;
1634 
1635 	if (dst_tupdesc->natts != src_tupdesc->natts)
1636 		ereport(ERROR,
1637 				(errcode(ERRCODE_DATATYPE_MISMATCH),
1638 				 errmsg("function return row and query-specified return row do not match"),
1639 				 errdetail_plural("Returned row contains %d attribute, but query expects %d.",
1640 				"Returned row contains %d attributes, but query expects %d.",
1641 								  src_tupdesc->natts,
1642 								  src_tupdesc->natts, dst_tupdesc->natts)));
1643 
1644 	for (i = 0; i < dst_tupdesc->natts; i++)
1645 	{
1646 		Form_pg_attribute dattr = dst_tupdesc->attrs[i];
1647 		Form_pg_attribute sattr = src_tupdesc->attrs[i];
1648 
1649 		if (IsBinaryCoercible(sattr->atttypid, dattr->atttypid))
1650 			continue;			/* no worries */
1651 		if (!dattr->attisdropped)
1652 			ereport(ERROR,
1653 					(errcode(ERRCODE_DATATYPE_MISMATCH),
1654 					 errmsg("function return row and query-specified return row do not match"),
1655 					 errdetail("Returned type %s at ordinal position %d, but query expects %s.",
1656 							   format_type_be(sattr->atttypid),
1657 							   i + 1,
1658 							   format_type_be(dattr->atttypid))));
1659 
1660 		if (dattr->attlen != sattr->attlen ||
1661 			dattr->attalign != sattr->attalign)
1662 			ereport(ERROR,
1663 					(errcode(ERRCODE_DATATYPE_MISMATCH),
1664 					 errmsg("function return row and query-specified return row do not match"),
1665 					 errdetail("Physical storage mismatch on dropped attribute at ordinal position %d.",
1666 							   i + 1)));
1667 	}
1668 }
1669 
1670 /*
1671  *		ExecMakeFunctionResult
1672  *
1673  * Evaluate the arguments to a function and then the function itself.
1674  * init_fcache is presumed already run on the FuncExprState.
1675  *
1676  * This function handles the most general case, wherein the function or
1677  * one of its arguments can return a set.
1678  */
1679 static Datum
ExecMakeFunctionResult(FuncExprState * fcache,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)1680 ExecMakeFunctionResult(FuncExprState *fcache,
1681 					   ExprContext *econtext,
1682 					   bool *isNull,
1683 					   ExprDoneCond *isDone)
1684 {
1685 	List	   *arguments;
1686 	Datum		result;
1687 	FunctionCallInfo fcinfo;
1688 	PgStat_FunctionCallUsage fcusage;
1689 	ReturnSetInfo rsinfo;		/* for functions returning sets */
1690 	ExprDoneCond argDone;
1691 	bool		hasSetArg;
1692 	int			i;
1693 
1694 restart:
1695 
1696 	/* Guard against stack overflow due to overly complex expressions */
1697 	check_stack_depth();
1698 
1699 	/*
1700 	 * If a previous call of the function returned a set result in the form of
1701 	 * a tuplestore, continue reading rows from the tuplestore until it's
1702 	 * empty.
1703 	 */
1704 	if (fcache->funcResultStore)
1705 	{
1706 		Assert(isDone);			/* it was provided before ... */
1707 		if (tuplestore_gettupleslot(fcache->funcResultStore, true, false,
1708 									fcache->funcResultSlot))
1709 		{
1710 			*isDone = ExprMultipleResult;
1711 			if (fcache->funcReturnsTuple)
1712 			{
1713 				/* We must return the whole tuple as a Datum. */
1714 				*isNull = false;
1715 				return ExecFetchSlotTupleDatum(fcache->funcResultSlot);
1716 			}
1717 			else
1718 			{
1719 				/* Extract the first column and return it as a scalar. */
1720 				return slot_getattr(fcache->funcResultSlot, 1, isNull);
1721 			}
1722 		}
1723 		/* Exhausted the tuplestore, so clean up */
1724 		tuplestore_end(fcache->funcResultStore);
1725 		fcache->funcResultStore = NULL;
1726 		/* We are done unless there was a set-valued argument */
1727 		if (!fcache->setHasSetArg)
1728 		{
1729 			*isDone = ExprEndResult;
1730 			*isNull = true;
1731 			return (Datum) 0;
1732 		}
1733 		/* If there was, continue evaluating the argument values */
1734 		Assert(!fcache->setArgsValid);
1735 	}
1736 
1737 	/*
1738 	 * arguments is a list of expressions to evaluate before passing to the
1739 	 * function manager.  We skip the evaluation if it was already done in the
1740 	 * previous call (ie, we are continuing the evaluation of a set-valued
1741 	 * function).  Otherwise, collect the current argument values into fcinfo.
1742 	 */
1743 	fcinfo = &fcache->fcinfo_data;
1744 	arguments = fcache->args;
1745 	if (!fcache->setArgsValid)
1746 	{
1747 		argDone = ExecEvalFuncArgs(fcinfo, arguments, econtext);
1748 		if (argDone == ExprEndResult)
1749 		{
1750 			/* input is an empty set, so return an empty set. */
1751 			*isNull = true;
1752 			if (isDone)
1753 				*isDone = ExprEndResult;
1754 			else
1755 				ereport(ERROR,
1756 						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1757 						 errmsg("set-valued function called in context that cannot accept a set")));
1758 			return (Datum) 0;
1759 		}
1760 		hasSetArg = (argDone != ExprSingleResult);
1761 	}
1762 	else
1763 	{
1764 		/* Re-use callinfo from previous evaluation */
1765 		hasSetArg = fcache->setHasSetArg;
1766 		/* Reset flag (we may set it again below) */
1767 		fcache->setArgsValid = false;
1768 	}
1769 
1770 	/*
1771 	 * Now call the function, passing the evaluated parameter values.
1772 	 */
1773 	if (fcache->func.fn_retset || hasSetArg)
1774 	{
1775 		/*
1776 		 * We need to return a set result.  Complain if caller not ready to
1777 		 * accept one.
1778 		 */
1779 		if (isDone == NULL)
1780 			ereport(ERROR,
1781 					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1782 					 errmsg("set-valued function called in context that cannot accept a set")));
1783 
1784 		/*
1785 		 * Prepare a resultinfo node for communication.  If the function
1786 		 * doesn't itself return set, we don't pass the resultinfo to the
1787 		 * function, but we need to fill it in anyway for internal use.
1788 		 */
1789 		if (fcache->func.fn_retset)
1790 			fcinfo->resultinfo = (Node *) &rsinfo;
1791 		rsinfo.type = T_ReturnSetInfo;
1792 		rsinfo.econtext = econtext;
1793 		rsinfo.expectedDesc = fcache->funcResultDesc;
1794 		rsinfo.allowedModes = (int) (SFRM_ValuePerCall | SFRM_Materialize);
1795 		/* note we do not set SFRM_Materialize_Random or _Preferred */
1796 		rsinfo.returnMode = SFRM_ValuePerCall;
1797 		/* isDone is filled below */
1798 		rsinfo.setResult = NULL;
1799 		rsinfo.setDesc = NULL;
1800 
1801 		/*
1802 		 * This loop handles the situation where we have both a set argument
1803 		 * and a set-valued function.  Once we have exhausted the function's
1804 		 * value(s) for a particular argument value, we have to get the next
1805 		 * argument value and start the function over again. We might have to
1806 		 * do it more than once, if the function produces an empty result set
1807 		 * for a particular input value.
1808 		 */
1809 		for (;;)
1810 		{
1811 			/*
1812 			 * If function is strict, and there are any NULL arguments, skip
1813 			 * calling the function (at least for this set of args).
1814 			 */
1815 			bool		callit = true;
1816 
1817 			if (fcache->func.fn_strict)
1818 			{
1819 				for (i = 0; i < fcinfo->nargs; i++)
1820 				{
1821 					if (fcinfo->argnull[i])
1822 					{
1823 						callit = false;
1824 						break;
1825 					}
1826 				}
1827 			}
1828 
1829 			if (callit)
1830 			{
1831 				pgstat_init_function_usage(fcinfo, &fcusage);
1832 
1833 				fcinfo->isnull = false;
1834 				rsinfo.isDone = ExprSingleResult;
1835 				result = FunctionCallInvoke(fcinfo);
1836 				*isNull = fcinfo->isnull;
1837 				*isDone = rsinfo.isDone;
1838 
1839 				pgstat_end_function_usage(&fcusage,
1840 										rsinfo.isDone != ExprMultipleResult);
1841 			}
1842 			else if (fcache->func.fn_retset)
1843 			{
1844 				/* for a strict SRF, result for NULL is an empty set */
1845 				result = (Datum) 0;
1846 				*isNull = true;
1847 				*isDone = ExprEndResult;
1848 			}
1849 			else
1850 			{
1851 				/* for a strict non-SRF, result for NULL is a NULL */
1852 				result = (Datum) 0;
1853 				*isNull = true;
1854 				*isDone = ExprSingleResult;
1855 			}
1856 
1857 			/* Which protocol does function want to use? */
1858 			if (rsinfo.returnMode == SFRM_ValuePerCall)
1859 			{
1860 				if (*isDone != ExprEndResult)
1861 				{
1862 					/*
1863 					 * Got a result from current argument. If function itself
1864 					 * returns set, save the current argument values to re-use
1865 					 * on the next call.
1866 					 */
1867 					if (fcache->func.fn_retset &&
1868 						*isDone == ExprMultipleResult)
1869 					{
1870 						fcache->setHasSetArg = hasSetArg;
1871 						fcache->setArgsValid = true;
1872 						/* Register cleanup callback if we didn't already */
1873 						if (!fcache->shutdown_reg)
1874 						{
1875 							RegisterExprContextCallback(econtext,
1876 														ShutdownFuncExpr,
1877 													PointerGetDatum(fcache));
1878 							fcache->shutdown_reg = true;
1879 						}
1880 					}
1881 
1882 					/*
1883 					 * Make sure we say we are returning a set, even if the
1884 					 * function itself doesn't return sets.
1885 					 */
1886 					if (hasSetArg)
1887 						*isDone = ExprMultipleResult;
1888 					break;
1889 				}
1890 			}
1891 			else if (rsinfo.returnMode == SFRM_Materialize)
1892 			{
1893 				/* check we're on the same page as the function author */
1894 				if (rsinfo.isDone != ExprSingleResult)
1895 					ereport(ERROR,
1896 							(errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
1897 							 errmsg("table-function protocol for materialize mode was not followed")));
1898 				if (rsinfo.setResult != NULL)
1899 				{
1900 					/* prepare to return values from the tuplestore */
1901 					ExecPrepareTuplestoreResult(fcache, econtext,
1902 												rsinfo.setResult,
1903 												rsinfo.setDesc);
1904 					/* remember whether we had set arguments */
1905 					fcache->setHasSetArg = hasSetArg;
1906 					/* loop back to top to start returning from tuplestore */
1907 					goto restart;
1908 				}
1909 				/* if setResult was left null, treat it as empty set */
1910 				*isDone = ExprEndResult;
1911 				*isNull = true;
1912 				result = (Datum) 0;
1913 			}
1914 			else
1915 				ereport(ERROR,
1916 						(errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
1917 						 errmsg("unrecognized table-function returnMode: %d",
1918 								(int) rsinfo.returnMode)));
1919 
1920 			/* Else, done with this argument */
1921 			if (!hasSetArg)
1922 				break;			/* input not a set, so done */
1923 
1924 			/* Re-eval args to get the next element of the input set */
1925 			argDone = ExecEvalFuncArgs(fcinfo, arguments, econtext);
1926 
1927 			if (argDone != ExprMultipleResult)
1928 			{
1929 				/* End of argument set, so we're done. */
1930 				*isNull = true;
1931 				*isDone = ExprEndResult;
1932 				result = (Datum) 0;
1933 				break;
1934 			}
1935 
1936 			/*
1937 			 * If we reach here, loop around to run the function on the new
1938 			 * argument.
1939 			 */
1940 		}
1941 	}
1942 	else
1943 	{
1944 		/*
1945 		 * Non-set case: much easier.
1946 		 *
1947 		 * In common cases, this code path is unreachable because we'd have
1948 		 * selected ExecMakeFunctionResultNoSets instead.  However, it's
1949 		 * possible to get here if an argument sometimes produces set results
1950 		 * and sometimes scalar results.  For example, a CASE expression might
1951 		 * call a set-returning function in only some of its arms.
1952 		 */
1953 		if (isDone)
1954 			*isDone = ExprSingleResult;
1955 
1956 		/*
1957 		 * If function is strict, and there are any NULL arguments, skip
1958 		 * calling the function and return NULL.
1959 		 */
1960 		if (fcache->func.fn_strict)
1961 		{
1962 			for (i = 0; i < fcinfo->nargs; i++)
1963 			{
1964 				if (fcinfo->argnull[i])
1965 				{
1966 					*isNull = true;
1967 					return (Datum) 0;
1968 				}
1969 			}
1970 		}
1971 
1972 		pgstat_init_function_usage(fcinfo, &fcusage);
1973 
1974 		fcinfo->isnull = false;
1975 		result = FunctionCallInvoke(fcinfo);
1976 		*isNull = fcinfo->isnull;
1977 
1978 		pgstat_end_function_usage(&fcusage, true);
1979 	}
1980 
1981 	return result;
1982 }
1983 
1984 /*
1985  *		ExecMakeFunctionResultNoSets
1986  *
1987  * Simplified version of ExecMakeFunctionResult that can only handle
1988  * non-set cases.  Hand-tuned for speed.
1989  */
1990 static Datum
ExecMakeFunctionResultNoSets(FuncExprState * fcache,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)1991 ExecMakeFunctionResultNoSets(FuncExprState *fcache,
1992 							 ExprContext *econtext,
1993 							 bool *isNull,
1994 							 ExprDoneCond *isDone)
1995 {
1996 	ListCell   *arg;
1997 	Datum		result;
1998 	FunctionCallInfo fcinfo;
1999 	PgStat_FunctionCallUsage fcusage;
2000 	int			i;
2001 
2002 	/* Guard against stack overflow due to overly complex expressions */
2003 	check_stack_depth();
2004 
2005 	if (isDone)
2006 		*isDone = ExprSingleResult;
2007 
2008 	/* inlined, simplified version of ExecEvalFuncArgs */
2009 	fcinfo = &fcache->fcinfo_data;
2010 	i = 0;
2011 	foreach(arg, fcache->args)
2012 	{
2013 		ExprState  *argstate = (ExprState *) lfirst(arg);
2014 
2015 		fcinfo->arg[i] = ExecEvalExpr(argstate,
2016 									  econtext,
2017 									  &fcinfo->argnull[i],
2018 									  NULL);
2019 		i++;
2020 	}
2021 
2022 	/*
2023 	 * If function is strict, and there are any NULL arguments, skip calling
2024 	 * the function and return NULL.
2025 	 */
2026 	if (fcache->func.fn_strict)
2027 	{
2028 		while (--i >= 0)
2029 		{
2030 			if (fcinfo->argnull[i])
2031 			{
2032 				*isNull = true;
2033 				return (Datum) 0;
2034 			}
2035 		}
2036 	}
2037 
2038 	pgstat_init_function_usage(fcinfo, &fcusage);
2039 
2040 	fcinfo->isnull = false;
2041 	result = FunctionCallInvoke(fcinfo);
2042 	*isNull = fcinfo->isnull;
2043 
2044 	pgstat_end_function_usage(&fcusage, true);
2045 
2046 	return result;
2047 }
2048 
2049 
2050 /*
2051  *		ExecMakeTableFunctionResult
2052  *
2053  * Evaluate a table function, producing a materialized result in a Tuplestore
2054  * object.
2055  */
2056 Tuplestorestate *
ExecMakeTableFunctionResult(ExprState * funcexpr,ExprContext * econtext,MemoryContext argContext,TupleDesc expectedDesc,bool randomAccess)2057 ExecMakeTableFunctionResult(ExprState *funcexpr,
2058 							ExprContext *econtext,
2059 							MemoryContext argContext,
2060 							TupleDesc expectedDesc,
2061 							bool randomAccess)
2062 {
2063 	Tuplestorestate *tupstore = NULL;
2064 	TupleDesc	tupdesc = NULL;
2065 	Oid			funcrettype;
2066 	bool		returnsTuple;
2067 	bool		returnsSet = false;
2068 	FunctionCallInfoData fcinfo;
2069 	PgStat_FunctionCallUsage fcusage;
2070 	ReturnSetInfo rsinfo;
2071 	HeapTupleData tmptup;
2072 	MemoryContext callerContext;
2073 	MemoryContext oldcontext;
2074 	bool		direct_function_call;
2075 	bool		first_time = true;
2076 
2077 	callerContext = CurrentMemoryContext;
2078 
2079 	funcrettype = exprType((Node *) funcexpr->expr);
2080 
2081 	returnsTuple = type_is_rowtype(funcrettype);
2082 
2083 	/*
2084 	 * Prepare a resultinfo node for communication.  We always do this even if
2085 	 * not expecting a set result, so that we can pass expectedDesc.  In the
2086 	 * generic-expression case, the expression doesn't actually get to see the
2087 	 * resultinfo, but set it up anyway because we use some of the fields as
2088 	 * our own state variables.
2089 	 */
2090 	rsinfo.type = T_ReturnSetInfo;
2091 	rsinfo.econtext = econtext;
2092 	rsinfo.expectedDesc = expectedDesc;
2093 	rsinfo.allowedModes = (int) (SFRM_ValuePerCall | SFRM_Materialize | SFRM_Materialize_Preferred);
2094 	if (randomAccess)
2095 		rsinfo.allowedModes |= (int) SFRM_Materialize_Random;
2096 	rsinfo.returnMode = SFRM_ValuePerCall;
2097 	/* isDone is filled below */
2098 	rsinfo.setResult = NULL;
2099 	rsinfo.setDesc = NULL;
2100 
2101 	/*
2102 	 * Normally the passed expression tree will be a FuncExprState, since the
2103 	 * grammar only allows a function call at the top level of a table
2104 	 * function reference.  However, if the function doesn't return set then
2105 	 * the planner might have replaced the function call via constant-folding
2106 	 * or inlining.  So if we see any other kind of expression node, execute
2107 	 * it via the general ExecEvalExpr() code; the only difference is that we
2108 	 * don't get a chance to pass a special ReturnSetInfo to any functions
2109 	 * buried in the expression.
2110 	 */
2111 	if (funcexpr && IsA(funcexpr, FuncExprState) &&
2112 		IsA(funcexpr->expr, FuncExpr))
2113 	{
2114 		FuncExprState *fcache = (FuncExprState *) funcexpr;
2115 		ExprDoneCond argDone;
2116 
2117 		/*
2118 		 * This path is similar to ExecMakeFunctionResult.
2119 		 */
2120 		direct_function_call = true;
2121 
2122 		/*
2123 		 * Initialize function cache if first time through
2124 		 */
2125 		if (fcache->func.fn_oid == InvalidOid)
2126 		{
2127 			FuncExpr   *func = (FuncExpr *) fcache->xprstate.expr;
2128 
2129 			init_fcache(func->funcid, func->inputcollid, fcache,
2130 						econtext->ecxt_per_query_memory, false);
2131 		}
2132 		returnsSet = fcache->func.fn_retset;
2133 		InitFunctionCallInfoData(fcinfo, &(fcache->func),
2134 								 list_length(fcache->args),
2135 								 fcache->fcinfo_data.fncollation,
2136 								 NULL, (Node *) &rsinfo);
2137 
2138 		/*
2139 		 * Evaluate the function's argument list.
2140 		 *
2141 		 * We can't do this in the per-tuple context: the argument values
2142 		 * would disappear when we reset that context in the inner loop.  And
2143 		 * the caller's CurrentMemoryContext is typically a query-lifespan
2144 		 * context, so we don't want to leak memory there.  We require the
2145 		 * caller to pass a separate memory context that can be used for this,
2146 		 * and can be reset each time through to avoid bloat.
2147 		 */
2148 		MemoryContextReset(argContext);
2149 		oldcontext = MemoryContextSwitchTo(argContext);
2150 		argDone = ExecEvalFuncArgs(&fcinfo, fcache->args, econtext);
2151 		MemoryContextSwitchTo(oldcontext);
2152 
2153 		/* We don't allow sets in the arguments of the table function */
2154 		if (argDone != ExprSingleResult)
2155 			ereport(ERROR,
2156 					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2157 					 errmsg("set-valued function called in context that cannot accept a set")));
2158 
2159 		/*
2160 		 * If function is strict, and there are any NULL arguments, skip
2161 		 * calling the function and act like it returned NULL (or an empty
2162 		 * set, in the returns-set case).
2163 		 */
2164 		if (fcache->func.fn_strict)
2165 		{
2166 			int			i;
2167 
2168 			for (i = 0; i < fcinfo.nargs; i++)
2169 			{
2170 				if (fcinfo.argnull[i])
2171 					goto no_function_result;
2172 			}
2173 		}
2174 	}
2175 	else
2176 	{
2177 		/* Treat funcexpr as a generic expression */
2178 		direct_function_call = false;
2179 		InitFunctionCallInfoData(fcinfo, NULL, 0, InvalidOid, NULL, NULL);
2180 	}
2181 
2182 	/*
2183 	 * Switch to short-lived context for calling the function or expression.
2184 	 */
2185 	MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
2186 
2187 	/*
2188 	 * Loop to handle the ValuePerCall protocol (which is also the same
2189 	 * behavior needed in the generic ExecEvalExpr path).
2190 	 */
2191 	for (;;)
2192 	{
2193 		Datum		result;
2194 
2195 		CHECK_FOR_INTERRUPTS();
2196 
2197 		/*
2198 		 * reset per-tuple memory context before each call of the function or
2199 		 * expression. This cleans up any local memory the function may leak
2200 		 * when called.
2201 		 */
2202 		ResetExprContext(econtext);
2203 
2204 		/* Call the function or expression one time */
2205 		if (direct_function_call)
2206 		{
2207 			pgstat_init_function_usage(&fcinfo, &fcusage);
2208 
2209 			fcinfo.isnull = false;
2210 			rsinfo.isDone = ExprSingleResult;
2211 			result = FunctionCallInvoke(&fcinfo);
2212 
2213 			pgstat_end_function_usage(&fcusage,
2214 									  rsinfo.isDone != ExprMultipleResult);
2215 		}
2216 		else
2217 		{
2218 			result = ExecEvalExpr(funcexpr, econtext,
2219 								  &fcinfo.isnull, &rsinfo.isDone);
2220 		}
2221 
2222 		/* Which protocol does function want to use? */
2223 		if (rsinfo.returnMode == SFRM_ValuePerCall)
2224 		{
2225 			/*
2226 			 * Check for end of result set.
2227 			 */
2228 			if (rsinfo.isDone == ExprEndResult)
2229 				break;
2230 
2231 			/*
2232 			 * If first time through, build tuplestore for result.  For a
2233 			 * scalar function result type, also make a suitable tupdesc.
2234 			 */
2235 			if (first_time)
2236 			{
2237 				oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
2238 				tupstore = tuplestore_begin_heap(randomAccess, false, work_mem);
2239 				rsinfo.setResult = tupstore;
2240 				if (!returnsTuple)
2241 				{
2242 					tupdesc = CreateTemplateTupleDesc(1, false);
2243 					TupleDescInitEntry(tupdesc,
2244 									   (AttrNumber) 1,
2245 									   "column",
2246 									   funcrettype,
2247 									   -1,
2248 									   0);
2249 					rsinfo.setDesc = tupdesc;
2250 				}
2251 				MemoryContextSwitchTo(oldcontext);
2252 			}
2253 
2254 			/*
2255 			 * Store current resultset item.
2256 			 */
2257 			if (returnsTuple)
2258 			{
2259 				if (!fcinfo.isnull)
2260 				{
2261 					HeapTupleHeader td = DatumGetHeapTupleHeader(result);
2262 
2263 					if (tupdesc == NULL)
2264 					{
2265 						/*
2266 						 * This is the first non-NULL result from the
2267 						 * function.  Use the type info embedded in the
2268 						 * rowtype Datum to look up the needed tupdesc.  Make
2269 						 * a copy for the query.
2270 						 */
2271 						oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
2272 						tupdesc = lookup_rowtype_tupdesc_copy(HeapTupleHeaderGetTypeId(td),
2273 											   HeapTupleHeaderGetTypMod(td));
2274 						rsinfo.setDesc = tupdesc;
2275 						MemoryContextSwitchTo(oldcontext);
2276 					}
2277 					else
2278 					{
2279 						/*
2280 						 * Verify all later returned rows have same subtype;
2281 						 * necessary in case the type is RECORD.
2282 						 */
2283 						if (HeapTupleHeaderGetTypeId(td) != tupdesc->tdtypeid ||
2284 							HeapTupleHeaderGetTypMod(td) != tupdesc->tdtypmod)
2285 							ereport(ERROR,
2286 									(errcode(ERRCODE_DATATYPE_MISMATCH),
2287 									 errmsg("rows returned by function are not all of the same row type")));
2288 					}
2289 
2290 					/*
2291 					 * tuplestore_puttuple needs a HeapTuple not a bare
2292 					 * HeapTupleHeader, but it doesn't need all the fields.
2293 					 */
2294 					tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
2295 					tmptup.t_data = td;
2296 
2297 					tuplestore_puttuple(tupstore, &tmptup);
2298 				}
2299 				else
2300 				{
2301 					/*
2302 					 * NULL result from a tuple-returning function; expand it
2303 					 * to a row of all nulls.  We rely on the expectedDesc to
2304 					 * form such rows.  (Note: this would be problematic if
2305 					 * tuplestore_putvalues saved the tdtypeid/tdtypmod from
2306 					 * the provided descriptor, since that might not match
2307 					 * what we get from the function itself.  But it doesn't.)
2308 					 */
2309 					int			natts = expectedDesc->natts;
2310 					bool	   *nullflags;
2311 
2312 					nullflags = (bool *) palloc(natts * sizeof(bool));
2313 					memset(nullflags, true, natts * sizeof(bool));
2314 					tuplestore_putvalues(tupstore, expectedDesc, NULL, nullflags);
2315 				}
2316 			}
2317 			else
2318 			{
2319 				/* Scalar-type case: just store the function result */
2320 				tuplestore_putvalues(tupstore, tupdesc, &result, &fcinfo.isnull);
2321 			}
2322 
2323 			/*
2324 			 * Are we done?
2325 			 */
2326 			if (rsinfo.isDone != ExprMultipleResult)
2327 				break;
2328 		}
2329 		else if (rsinfo.returnMode == SFRM_Materialize)
2330 		{
2331 			/* check we're on the same page as the function author */
2332 			if (!first_time || rsinfo.isDone != ExprSingleResult)
2333 				ereport(ERROR,
2334 						(errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
2335 						 errmsg("table-function protocol for materialize mode was not followed")));
2336 			/* Done evaluating the set result */
2337 			break;
2338 		}
2339 		else
2340 			ereport(ERROR,
2341 					(errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
2342 					 errmsg("unrecognized table-function returnMode: %d",
2343 							(int) rsinfo.returnMode)));
2344 
2345 		first_time = false;
2346 	}
2347 
2348 no_function_result:
2349 
2350 	/*
2351 	 * If we got nothing from the function (ie, an empty-set or NULL result),
2352 	 * we have to create the tuplestore to return, and if it's a
2353 	 * non-set-returning function then insert a single all-nulls row.  As
2354 	 * above, we depend on the expectedDesc to manufacture the dummy row.
2355 	 */
2356 	if (rsinfo.setResult == NULL)
2357 	{
2358 		MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
2359 		tupstore = tuplestore_begin_heap(randomAccess, false, work_mem);
2360 		rsinfo.setResult = tupstore;
2361 		if (!returnsSet)
2362 		{
2363 			int			natts = expectedDesc->natts;
2364 			bool	   *nullflags;
2365 
2366 			MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
2367 			nullflags = (bool *) palloc(natts * sizeof(bool));
2368 			memset(nullflags, true, natts * sizeof(bool));
2369 			tuplestore_putvalues(tupstore, expectedDesc, NULL, nullflags);
2370 		}
2371 	}
2372 
2373 	/*
2374 	 * If function provided a tupdesc, cross-check it.  We only really need to
2375 	 * do this for functions returning RECORD, but might as well do it always.
2376 	 */
2377 	if (rsinfo.setDesc)
2378 	{
2379 		tupledesc_match(expectedDesc, rsinfo.setDesc);
2380 
2381 		/*
2382 		 * If it is a dynamically-allocated TupleDesc, free it: it is
2383 		 * typically allocated in a per-query context, so we must avoid
2384 		 * leaking it across multiple usages.
2385 		 */
2386 		if (rsinfo.setDesc->tdrefcount == -1)
2387 			FreeTupleDesc(rsinfo.setDesc);
2388 	}
2389 
2390 	MemoryContextSwitchTo(callerContext);
2391 
2392 	/* All done, pass back the tuplestore */
2393 	return rsinfo.setResult;
2394 }
2395 
2396 
2397 /* ----------------------------------------------------------------
2398  *		ExecEvalFunc
2399  *		ExecEvalOper
2400  *
2401  *		Evaluate the functional result of a list of arguments by calling the
2402  *		function manager.
2403  * ----------------------------------------------------------------
2404  */
2405 
2406 /* ----------------------------------------------------------------
2407  *		ExecEvalFunc
2408  * ----------------------------------------------------------------
2409  */
2410 static Datum
ExecEvalFunc(FuncExprState * fcache,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)2411 ExecEvalFunc(FuncExprState *fcache,
2412 			 ExprContext *econtext,
2413 			 bool *isNull,
2414 			 ExprDoneCond *isDone)
2415 {
2416 	/* This is called only the first time through */
2417 	FuncExpr   *func = (FuncExpr *) fcache->xprstate.expr;
2418 
2419 	/* Initialize function lookup info */
2420 	init_fcache(func->funcid, func->inputcollid, fcache,
2421 				econtext->ecxt_per_query_memory, true);
2422 
2423 	/*
2424 	 * We need to invoke ExecMakeFunctionResult if either the function itself
2425 	 * or any of its input expressions can return a set.  Otherwise, invoke
2426 	 * ExecMakeFunctionResultNoSets.  In either case, change the evalfunc
2427 	 * pointer to go directly there on subsequent uses.
2428 	 */
2429 	if (fcache->func.fn_retset || expression_returns_set((Node *) func->args))
2430 	{
2431 		fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResult;
2432 		return ExecMakeFunctionResult(fcache, econtext, isNull, isDone);
2433 	}
2434 	else
2435 	{
2436 		fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResultNoSets;
2437 		return ExecMakeFunctionResultNoSets(fcache, econtext, isNull, isDone);
2438 	}
2439 }
2440 
2441 /* ----------------------------------------------------------------
2442  *		ExecEvalOper
2443  * ----------------------------------------------------------------
2444  */
2445 static Datum
ExecEvalOper(FuncExprState * fcache,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)2446 ExecEvalOper(FuncExprState *fcache,
2447 			 ExprContext *econtext,
2448 			 bool *isNull,
2449 			 ExprDoneCond *isDone)
2450 {
2451 	/* This is called only the first time through */
2452 	OpExpr	   *op = (OpExpr *) fcache->xprstate.expr;
2453 
2454 	/* Initialize function lookup info */
2455 	init_fcache(op->opfuncid, op->inputcollid, fcache,
2456 				econtext->ecxt_per_query_memory, true);
2457 
2458 	/*
2459 	 * We need to invoke ExecMakeFunctionResult if either the function itself
2460 	 * or any of its input expressions can return a set.  Otherwise, invoke
2461 	 * ExecMakeFunctionResultNoSets.  In either case, change the evalfunc
2462 	 * pointer to go directly there on subsequent uses.
2463 	 */
2464 	if (fcache->func.fn_retset || expression_returns_set((Node *) op->args))
2465 	{
2466 		fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResult;
2467 		return ExecMakeFunctionResult(fcache, econtext, isNull, isDone);
2468 	}
2469 	else
2470 	{
2471 		fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResultNoSets;
2472 		return ExecMakeFunctionResultNoSets(fcache, econtext, isNull, isDone);
2473 	}
2474 }
2475 
2476 /* ----------------------------------------------------------------
2477  *		ExecEvalDistinct
2478  *
2479  * IS DISTINCT FROM must evaluate arguments to determine whether
2480  * they are NULL; if either is NULL then the result is already
2481  * known. If neither is NULL, then proceed to evaluate the
2482  * function. Note that this is *always* derived from the equals
2483  * operator, but since we need special processing of the arguments
2484  * we can not simply reuse ExecEvalOper() or ExecEvalFunc().
2485  * ----------------------------------------------------------------
2486  */
2487 static Datum
ExecEvalDistinct(FuncExprState * fcache,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)2488 ExecEvalDistinct(FuncExprState *fcache,
2489 				 ExprContext *econtext,
2490 				 bool *isNull,
2491 				 ExprDoneCond *isDone)
2492 {
2493 	Datum		result;
2494 	FunctionCallInfo fcinfo;
2495 	ExprDoneCond argDone;
2496 
2497 	/* Set default values for result flags: non-null, not a set result */
2498 	*isNull = false;
2499 	if (isDone)
2500 		*isDone = ExprSingleResult;
2501 
2502 	/*
2503 	 * Initialize function cache if first time through
2504 	 */
2505 	if (fcache->func.fn_oid == InvalidOid)
2506 	{
2507 		DistinctExpr *op = (DistinctExpr *) fcache->xprstate.expr;
2508 
2509 		init_fcache(op->opfuncid, op->inputcollid, fcache,
2510 					econtext->ecxt_per_query_memory, true);
2511 		Assert(!fcache->func.fn_retset);
2512 	}
2513 
2514 	/*
2515 	 * Evaluate arguments
2516 	 */
2517 	fcinfo = &fcache->fcinfo_data;
2518 	argDone = ExecEvalFuncArgs(fcinfo, fcache->args, econtext);
2519 	if (argDone != ExprSingleResult)
2520 		ereport(ERROR,
2521 				(errcode(ERRCODE_DATATYPE_MISMATCH),
2522 				 errmsg("IS DISTINCT FROM does not support set arguments")));
2523 	Assert(fcinfo->nargs == 2);
2524 
2525 	if (fcinfo->argnull[0] && fcinfo->argnull[1])
2526 	{
2527 		/* Both NULL? Then is not distinct... */
2528 		result = BoolGetDatum(FALSE);
2529 	}
2530 	else if (fcinfo->argnull[0] || fcinfo->argnull[1])
2531 	{
2532 		/* Only one is NULL? Then is distinct... */
2533 		result = BoolGetDatum(TRUE);
2534 	}
2535 	else
2536 	{
2537 		fcinfo->isnull = false;
2538 		result = FunctionCallInvoke(fcinfo);
2539 		*isNull = fcinfo->isnull;
2540 		/* Must invert result of "=" */
2541 		result = BoolGetDatum(!DatumGetBool(result));
2542 	}
2543 
2544 	return result;
2545 }
2546 
2547 /*
2548  * ExecEvalScalarArrayOp
2549  *
2550  * Evaluate "scalar op ANY/ALL (array)".  The operator always yields boolean,
2551  * and we combine the results across all array elements using OR and AND
2552  * (for ANY and ALL respectively).  Of course we short-circuit as soon as
2553  * the result is known.
2554  */
2555 static Datum
ExecEvalScalarArrayOp(ScalarArrayOpExprState * sstate,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)2556 ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate,
2557 					  ExprContext *econtext,
2558 					  bool *isNull, ExprDoneCond *isDone)
2559 {
2560 	ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) sstate->fxprstate.xprstate.expr;
2561 	bool		useOr = opexpr->useOr;
2562 	ArrayType  *arr;
2563 	int			nitems;
2564 	Datum		result;
2565 	bool		resultnull;
2566 	FunctionCallInfo fcinfo;
2567 	ExprDoneCond argDone;
2568 	int			i;
2569 	int16		typlen;
2570 	bool		typbyval;
2571 	char		typalign;
2572 	char	   *s;
2573 	bits8	   *bitmap;
2574 	int			bitmask;
2575 
2576 	/* Set default values for result flags: non-null, not a set result */
2577 	*isNull = false;
2578 	if (isDone)
2579 		*isDone = ExprSingleResult;
2580 
2581 	/*
2582 	 * Initialize function cache if first time through
2583 	 */
2584 	if (sstate->fxprstate.func.fn_oid == InvalidOid)
2585 	{
2586 		init_fcache(opexpr->opfuncid, opexpr->inputcollid, &sstate->fxprstate,
2587 					econtext->ecxt_per_query_memory, true);
2588 		Assert(!sstate->fxprstate.func.fn_retset);
2589 	}
2590 
2591 	/*
2592 	 * Evaluate arguments
2593 	 */
2594 	fcinfo = &sstate->fxprstate.fcinfo_data;
2595 	argDone = ExecEvalFuncArgs(fcinfo, sstate->fxprstate.args, econtext);
2596 	if (argDone != ExprSingleResult)
2597 		ereport(ERROR,
2598 				(errcode(ERRCODE_DATATYPE_MISMATCH),
2599 			   errmsg("op ANY/ALL (array) does not support set arguments")));
2600 	Assert(fcinfo->nargs == 2);
2601 
2602 	/*
2603 	 * If the array is NULL then we return NULL --- it's not very meaningful
2604 	 * to do anything else, even if the operator isn't strict.
2605 	 */
2606 	if (fcinfo->argnull[1])
2607 	{
2608 		*isNull = true;
2609 		return (Datum) 0;
2610 	}
2611 	/* Else okay to fetch and detoast the array */
2612 	arr = DatumGetArrayTypeP(fcinfo->arg[1]);
2613 
2614 	/*
2615 	 * If the array is empty, we return either FALSE or TRUE per the useOr
2616 	 * flag.  This is correct even if the scalar is NULL; since we would
2617 	 * evaluate the operator zero times, it matters not whether it would want
2618 	 * to return NULL.
2619 	 */
2620 	nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
2621 	if (nitems <= 0)
2622 		return BoolGetDatum(!useOr);
2623 
2624 	/*
2625 	 * If the scalar is NULL, and the function is strict, return NULL; no
2626 	 * point in iterating the loop.
2627 	 */
2628 	if (fcinfo->argnull[0] && sstate->fxprstate.func.fn_strict)
2629 	{
2630 		*isNull = true;
2631 		return (Datum) 0;
2632 	}
2633 
2634 	/*
2635 	 * We arrange to look up info about the element type only once per series
2636 	 * of calls, assuming the element type doesn't change underneath us.
2637 	 */
2638 	if (sstate->element_type != ARR_ELEMTYPE(arr))
2639 	{
2640 		get_typlenbyvalalign(ARR_ELEMTYPE(arr),
2641 							 &sstate->typlen,
2642 							 &sstate->typbyval,
2643 							 &sstate->typalign);
2644 		sstate->element_type = ARR_ELEMTYPE(arr);
2645 	}
2646 	typlen = sstate->typlen;
2647 	typbyval = sstate->typbyval;
2648 	typalign = sstate->typalign;
2649 
2650 	result = BoolGetDatum(!useOr);
2651 	resultnull = false;
2652 
2653 	/* Loop over the array elements */
2654 	s = (char *) ARR_DATA_PTR(arr);
2655 	bitmap = ARR_NULLBITMAP(arr);
2656 	bitmask = 1;
2657 
2658 	for (i = 0; i < nitems; i++)
2659 	{
2660 		Datum		elt;
2661 		Datum		thisresult;
2662 
2663 		/* Get array element, checking for NULL */
2664 		if (bitmap && (*bitmap & bitmask) == 0)
2665 		{
2666 			fcinfo->arg[1] = (Datum) 0;
2667 			fcinfo->argnull[1] = true;
2668 		}
2669 		else
2670 		{
2671 			elt = fetch_att(s, typbyval, typlen);
2672 			s = att_addlength_pointer(s, typlen, s);
2673 			s = (char *) att_align_nominal(s, typalign);
2674 			fcinfo->arg[1] = elt;
2675 			fcinfo->argnull[1] = false;
2676 		}
2677 
2678 		/* Call comparison function */
2679 		if (fcinfo->argnull[1] && sstate->fxprstate.func.fn_strict)
2680 		{
2681 			fcinfo->isnull = true;
2682 			thisresult = (Datum) 0;
2683 		}
2684 		else
2685 		{
2686 			fcinfo->isnull = false;
2687 			thisresult = FunctionCallInvoke(fcinfo);
2688 		}
2689 
2690 		/* Combine results per OR or AND semantics */
2691 		if (fcinfo->isnull)
2692 			resultnull = true;
2693 		else if (useOr)
2694 		{
2695 			if (DatumGetBool(thisresult))
2696 			{
2697 				result = BoolGetDatum(true);
2698 				resultnull = false;
2699 				break;			/* needn't look at any more elements */
2700 			}
2701 		}
2702 		else
2703 		{
2704 			if (!DatumGetBool(thisresult))
2705 			{
2706 				result = BoolGetDatum(false);
2707 				resultnull = false;
2708 				break;			/* needn't look at any more elements */
2709 			}
2710 		}
2711 
2712 		/* advance bitmap pointer if any */
2713 		if (bitmap)
2714 		{
2715 			bitmask <<= 1;
2716 			if (bitmask == 0x100)
2717 			{
2718 				bitmap++;
2719 				bitmask = 1;
2720 			}
2721 		}
2722 	}
2723 
2724 	*isNull = resultnull;
2725 	return result;
2726 }
2727 
2728 /* ----------------------------------------------------------------
2729  *		ExecEvalNot
2730  *		ExecEvalOr
2731  *		ExecEvalAnd
2732  *
2733  *		Evaluate boolean expressions, with appropriate short-circuiting.
2734  *
2735  *		The query planner reformulates clause expressions in the
2736  *		qualification to conjunctive normal form.  If we ever get
2737  *		an AND to evaluate, we can be sure that it's not a top-level
2738  *		clause in the qualification, but appears lower (as a function
2739  *		argument, for example), or in the target list.  Not that you
2740  *		need to know this, mind you...
2741  * ----------------------------------------------------------------
2742  */
2743 static Datum
ExecEvalNot(BoolExprState * notclause,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)2744 ExecEvalNot(BoolExprState *notclause, ExprContext *econtext,
2745 			bool *isNull, ExprDoneCond *isDone)
2746 {
2747 	ExprState  *clause = linitial(notclause->args);
2748 	Datum		expr_value;
2749 
2750 	if (isDone)
2751 		*isDone = ExprSingleResult;
2752 
2753 	expr_value = ExecEvalExpr(clause, econtext, isNull, NULL);
2754 
2755 	/*
2756 	 * if the expression evaluates to null, then we just cascade the null back
2757 	 * to whoever called us.
2758 	 */
2759 	if (*isNull)
2760 		return expr_value;
2761 
2762 	/*
2763 	 * evaluation of 'not' is simple.. expr is false, then return 'true' and
2764 	 * vice versa.
2765 	 */
2766 	return BoolGetDatum(!DatumGetBool(expr_value));
2767 }
2768 
2769 /* ----------------------------------------------------------------
2770  *		ExecEvalOr
2771  * ----------------------------------------------------------------
2772  */
2773 static Datum
ExecEvalOr(BoolExprState * orExpr,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)2774 ExecEvalOr(BoolExprState *orExpr, ExprContext *econtext,
2775 		   bool *isNull, ExprDoneCond *isDone)
2776 {
2777 	List	   *clauses = orExpr->args;
2778 	ListCell   *clause;
2779 	bool		AnyNull;
2780 
2781 	if (isDone)
2782 		*isDone = ExprSingleResult;
2783 
2784 	AnyNull = false;
2785 
2786 	/*
2787 	 * If any of the clauses is TRUE, the OR result is TRUE regardless of the
2788 	 * states of the rest of the clauses, so we can stop evaluating and return
2789 	 * TRUE immediately.  If none are TRUE and one or more is NULL, we return
2790 	 * NULL; otherwise we return FALSE.  This makes sense when you interpret
2791 	 * NULL as "don't know": if we have a TRUE then the OR is TRUE even if we
2792 	 * aren't sure about some of the other inputs. If all the known inputs are
2793 	 * FALSE, but we have one or more "don't knows", then we have to report
2794 	 * that we "don't know" what the OR's result should be --- perhaps one of
2795 	 * the "don't knows" would have been TRUE if we'd known its value.  Only
2796 	 * when all the inputs are known to be FALSE can we state confidently that
2797 	 * the OR's result is FALSE.
2798 	 */
2799 	foreach(clause, clauses)
2800 	{
2801 		ExprState  *clausestate = (ExprState *) lfirst(clause);
2802 		Datum		clause_value;
2803 
2804 		clause_value = ExecEvalExpr(clausestate, econtext, isNull, NULL);
2805 
2806 		/*
2807 		 * if we have a non-null true result, then return it.
2808 		 */
2809 		if (*isNull)
2810 			AnyNull = true;		/* remember we got a null */
2811 		else if (DatumGetBool(clause_value))
2812 			return clause_value;
2813 	}
2814 
2815 	/* AnyNull is true if at least one clause evaluated to NULL */
2816 	*isNull = AnyNull;
2817 	return BoolGetDatum(false);
2818 }
2819 
2820 /* ----------------------------------------------------------------
2821  *		ExecEvalAnd
2822  * ----------------------------------------------------------------
2823  */
2824 static Datum
ExecEvalAnd(BoolExprState * andExpr,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)2825 ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
2826 			bool *isNull, ExprDoneCond *isDone)
2827 {
2828 	List	   *clauses = andExpr->args;
2829 	ListCell   *clause;
2830 	bool		AnyNull;
2831 
2832 	if (isDone)
2833 		*isDone = ExprSingleResult;
2834 
2835 	AnyNull = false;
2836 
2837 	/*
2838 	 * If any of the clauses is FALSE, the AND result is FALSE regardless of
2839 	 * the states of the rest of the clauses, so we can stop evaluating and
2840 	 * return FALSE immediately.  If none are FALSE and one or more is NULL,
2841 	 * we return NULL; otherwise we return TRUE.  This makes sense when you
2842 	 * interpret NULL as "don't know", using the same sort of reasoning as for
2843 	 * OR, above.
2844 	 */
2845 
2846 	foreach(clause, clauses)
2847 	{
2848 		ExprState  *clausestate = (ExprState *) lfirst(clause);
2849 		Datum		clause_value;
2850 
2851 		clause_value = ExecEvalExpr(clausestate, econtext, isNull, NULL);
2852 
2853 		/*
2854 		 * if we have a non-null false result, then return it.
2855 		 */
2856 		if (*isNull)
2857 			AnyNull = true;		/* remember we got a null */
2858 		else if (!DatumGetBool(clause_value))
2859 			return clause_value;
2860 	}
2861 
2862 	/* AnyNull is true if at least one clause evaluated to NULL */
2863 	*isNull = AnyNull;
2864 	return BoolGetDatum(!AnyNull);
2865 }
2866 
2867 /* ----------------------------------------------------------------
2868  *		ExecEvalConvertRowtype
2869  *
2870  *		Evaluate a rowtype coercion operation.  This may require
2871  *		rearranging field positions.
2872  * ----------------------------------------------------------------
2873  */
2874 static Datum
ExecEvalConvertRowtype(ConvertRowtypeExprState * cstate,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)2875 ExecEvalConvertRowtype(ConvertRowtypeExprState *cstate,
2876 					   ExprContext *econtext,
2877 					   bool *isNull, ExprDoneCond *isDone)
2878 {
2879 	ConvertRowtypeExpr *convert = (ConvertRowtypeExpr *) cstate->xprstate.expr;
2880 	HeapTuple	result;
2881 	Datum		tupDatum;
2882 	HeapTupleHeader tuple;
2883 	HeapTupleData tmptup;
2884 
2885 	tupDatum = ExecEvalExpr(cstate->arg, econtext, isNull, isDone);
2886 
2887 	/* this test covers the isDone exception too: */
2888 	if (*isNull)
2889 		return tupDatum;
2890 
2891 	tuple = DatumGetHeapTupleHeader(tupDatum);
2892 
2893 	/* Lookup tupdescs if first time through or after rescan */
2894 	if (cstate->indesc == NULL)
2895 	{
2896 		get_cached_rowtype(exprType((Node *) convert->arg), -1,
2897 						   &cstate->indesc, econtext);
2898 		cstate->initialized = false;
2899 	}
2900 	if (cstate->outdesc == NULL)
2901 	{
2902 		get_cached_rowtype(convert->resulttype, -1,
2903 						   &cstate->outdesc, econtext);
2904 		cstate->initialized = false;
2905 	}
2906 
2907 	/*
2908 	 * We used to be able to assert that incoming tuples are marked with
2909 	 * exactly the rowtype of cstate->indesc.  However, now that
2910 	 * ExecEvalWholeRowVar might change the tuples' marking to plain RECORD
2911 	 * due to inserting aliases, we can only make this weak test:
2912 	 */
2913 	Assert(HeapTupleHeaderGetTypeId(tuple) == cstate->indesc->tdtypeid ||
2914 		   HeapTupleHeaderGetTypeId(tuple) == RECORDOID);
2915 
2916 	/* if first time through, initialize conversion map */
2917 	if (!cstate->initialized)
2918 	{
2919 		MemoryContext old_cxt;
2920 
2921 		/* allocate map in long-lived memory context */
2922 		old_cxt = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
2923 
2924 		/* prepare map from old to new attribute numbers */
2925 		cstate->map = convert_tuples_by_name(cstate->indesc,
2926 											 cstate->outdesc,
2927 								 gettext_noop("could not convert row type"));
2928 		cstate->initialized = true;
2929 
2930 		MemoryContextSwitchTo(old_cxt);
2931 	}
2932 
2933 	/*
2934 	 * No-op if no conversion needed (not clear this can happen here).
2935 	 */
2936 	if (cstate->map == NULL)
2937 		return tupDatum;
2938 
2939 	/*
2940 	 * do_convert_tuple needs a HeapTuple not a bare HeapTupleHeader.
2941 	 */
2942 	tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
2943 	tmptup.t_data = tuple;
2944 
2945 	result = do_convert_tuple(&tmptup, cstate->map);
2946 
2947 	return HeapTupleGetDatum(result);
2948 }
2949 
2950 /* ----------------------------------------------------------------
2951  *		ExecEvalCase
2952  *
2953  *		Evaluate a CASE clause. Will have boolean expressions
2954  *		inside the WHEN clauses, and will have expressions
2955  *		for results.
2956  *		- thomas 1998-11-09
2957  * ----------------------------------------------------------------
2958  */
2959 static Datum
ExecEvalCase(CaseExprState * caseExpr,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)2960 ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
2961 			 bool *isNull, ExprDoneCond *isDone)
2962 {
2963 	List	   *clauses = caseExpr->args;
2964 	ListCell   *clause;
2965 	Datum		save_datum;
2966 	bool		save_isNull;
2967 
2968 	if (isDone)
2969 		*isDone = ExprSingleResult;
2970 
2971 	/*
2972 	 * If there's a test expression, we have to evaluate it and save the value
2973 	 * where the CaseTestExpr placeholders can find it.  We must save and
2974 	 * restore prior setting of econtext's caseValue fields, in case this node
2975 	 * is itself within a larger CASE.  Furthermore, don't assign to the
2976 	 * econtext fields until after returning from evaluation of the test
2977 	 * expression.  We used to pass &econtext->caseValue_isNull to the
2978 	 * recursive call, but that leads to aliasing that variable within said
2979 	 * call, which can (and did) produce bugs when the test expression itself
2980 	 * contains a CASE.
2981 	 *
2982 	 * If there's no test expression, we don't actually need to save and
2983 	 * restore these fields; but it's less code to just do so unconditionally.
2984 	 */
2985 	save_datum = econtext->caseValue_datum;
2986 	save_isNull = econtext->caseValue_isNull;
2987 
2988 	if (caseExpr->arg)
2989 	{
2990 		Datum		arg_value;
2991 		bool		arg_isNull;
2992 
2993 		arg_value = ExecEvalExpr(caseExpr->arg,
2994 								 econtext,
2995 								 &arg_isNull,
2996 								 NULL);
2997 		/* Since caseValue_datum may be read multiple times, force to R/O */
2998 		econtext->caseValue_datum =
2999 			MakeExpandedObjectReadOnly(arg_value,
3000 									   arg_isNull,
3001 									   caseExpr->argtyplen);
3002 		econtext->caseValue_isNull = arg_isNull;
3003 	}
3004 
3005 	/*
3006 	 * we evaluate each of the WHEN clauses in turn, as soon as one is true we
3007 	 * return the corresponding result. If none are true then we return the
3008 	 * value of the default clause, or NULL if there is none.
3009 	 */
3010 	foreach(clause, clauses)
3011 	{
3012 		CaseWhenState *wclause = lfirst(clause);
3013 		Datum		clause_value;
3014 		bool		clause_isNull;
3015 
3016 		clause_value = ExecEvalExpr(wclause->expr,
3017 									econtext,
3018 									&clause_isNull,
3019 									NULL);
3020 
3021 		/*
3022 		 * if we have a true test, then we return the result, since the case
3023 		 * statement is satisfied.  A NULL result from the test is not
3024 		 * considered true.
3025 		 */
3026 		if (DatumGetBool(clause_value) && !clause_isNull)
3027 		{
3028 			econtext->caseValue_datum = save_datum;
3029 			econtext->caseValue_isNull = save_isNull;
3030 			return ExecEvalExpr(wclause->result,
3031 								econtext,
3032 								isNull,
3033 								isDone);
3034 		}
3035 	}
3036 
3037 	econtext->caseValue_datum = save_datum;
3038 	econtext->caseValue_isNull = save_isNull;
3039 
3040 	if (caseExpr->defresult)
3041 	{
3042 		return ExecEvalExpr(caseExpr->defresult,
3043 							econtext,
3044 							isNull,
3045 							isDone);
3046 	}
3047 
3048 	*isNull = true;
3049 	return (Datum) 0;
3050 }
3051 
3052 /*
3053  * ExecEvalCaseTestExpr
3054  *
3055  * Return the value stored by CASE.
3056  */
3057 static Datum
ExecEvalCaseTestExpr(ExprState * exprstate,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)3058 ExecEvalCaseTestExpr(ExprState *exprstate,
3059 					 ExprContext *econtext,
3060 					 bool *isNull, ExprDoneCond *isDone)
3061 {
3062 	if (isDone)
3063 		*isDone = ExprSingleResult;
3064 	*isNull = econtext->caseValue_isNull;
3065 	return econtext->caseValue_datum;
3066 }
3067 
3068 /*
3069  * ExecEvalGroupingFuncExpr
3070  *
3071  * Return a bitmask with a bit for each (unevaluated) argument expression
3072  * (rightmost arg is least significant bit).
3073  *
3074  * A bit is set if the corresponding expression is NOT part of the set of
3075  * grouping expressions in the current grouping set.
3076  */
3077 static Datum
ExecEvalGroupingFuncExpr(GroupingFuncExprState * gstate,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)3078 ExecEvalGroupingFuncExpr(GroupingFuncExprState *gstate,
3079 						 ExprContext *econtext,
3080 						 bool *isNull,
3081 						 ExprDoneCond *isDone)
3082 {
3083 	int			result = 0;
3084 	int			attnum = 0;
3085 	Bitmapset  *grouped_cols = gstate->aggstate->grouped_cols;
3086 	ListCell   *lc;
3087 
3088 	if (isDone)
3089 		*isDone = ExprSingleResult;
3090 
3091 	*isNull = false;
3092 
3093 	foreach(lc, (gstate->clauses))
3094 	{
3095 		attnum = lfirst_int(lc);
3096 
3097 		result = result << 1;
3098 
3099 		if (!bms_is_member(attnum, grouped_cols))
3100 			result = result | 1;
3101 	}
3102 
3103 	return (Datum) result;
3104 }
3105 
3106 /* ----------------------------------------------------------------
3107  *		ExecEvalArray - ARRAY[] expressions
3108  * ----------------------------------------------------------------
3109  */
3110 static Datum
ExecEvalArray(ArrayExprState * astate,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)3111 ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
3112 			  bool *isNull, ExprDoneCond *isDone)
3113 {
3114 	ArrayExpr  *arrayExpr = (ArrayExpr *) astate->xprstate.expr;
3115 	ArrayType  *result;
3116 	ListCell   *element;
3117 	Oid			element_type = arrayExpr->element_typeid;
3118 	int			ndims = 0;
3119 	int			dims[MAXDIM];
3120 	int			lbs[MAXDIM];
3121 
3122 	/* Set default values for result flags: non-null, not a set result */
3123 	*isNull = false;
3124 	if (isDone)
3125 		*isDone = ExprSingleResult;
3126 
3127 	if (!arrayExpr->multidims)
3128 	{
3129 		/* Elements are presumably of scalar type */
3130 		int			nelems;
3131 		Datum	   *dvalues;
3132 		bool	   *dnulls;
3133 		int			i = 0;
3134 
3135 		ndims = 1;
3136 		nelems = list_length(astate->elements);
3137 
3138 		/* Shouldn't happen here, but if length is 0, return empty array */
3139 		if (nelems == 0)
3140 			return PointerGetDatum(construct_empty_array(element_type));
3141 
3142 		dvalues = (Datum *) palloc(nelems * sizeof(Datum));
3143 		dnulls = (bool *) palloc(nelems * sizeof(bool));
3144 
3145 		/* loop through and build array of datums */
3146 		foreach(element, astate->elements)
3147 		{
3148 			ExprState  *e = (ExprState *) lfirst(element);
3149 
3150 			dvalues[i] = ExecEvalExpr(e, econtext, &dnulls[i], NULL);
3151 			i++;
3152 		}
3153 
3154 		/* setup for 1-D array of the given length */
3155 		dims[0] = nelems;
3156 		lbs[0] = 1;
3157 
3158 		result = construct_md_array(dvalues, dnulls, ndims, dims, lbs,
3159 									element_type,
3160 									astate->elemlength,
3161 									astate->elembyval,
3162 									astate->elemalign);
3163 	}
3164 	else
3165 	{
3166 		/* Must be nested array expressions */
3167 		int			nbytes = 0;
3168 		int			nitems = 0;
3169 		int			outer_nelems = 0;
3170 		int			elem_ndims = 0;
3171 		int		   *elem_dims = NULL;
3172 		int		   *elem_lbs = NULL;
3173 		bool		firstone = true;
3174 		bool		havenulls = false;
3175 		bool		haveempty = false;
3176 		char	  **subdata;
3177 		bits8	  **subbitmaps;
3178 		int		   *subbytes;
3179 		int		   *subnitems;
3180 		int			i;
3181 		int32		dataoffset;
3182 		char	   *dat;
3183 		int			iitem;
3184 
3185 		i = list_length(astate->elements);
3186 		subdata = (char **) palloc(i * sizeof(char *));
3187 		subbitmaps = (bits8 **) palloc(i * sizeof(bits8 *));
3188 		subbytes = (int *) palloc(i * sizeof(int));
3189 		subnitems = (int *) palloc(i * sizeof(int));
3190 
3191 		/* loop through and get data area from each element */
3192 		foreach(element, astate->elements)
3193 		{
3194 			ExprState  *e = (ExprState *) lfirst(element);
3195 			bool		eisnull;
3196 			Datum		arraydatum;
3197 			ArrayType  *array;
3198 			int			this_ndims;
3199 
3200 			arraydatum = ExecEvalExpr(e, econtext, &eisnull, NULL);
3201 			/* temporarily ignore null subarrays */
3202 			if (eisnull)
3203 			{
3204 				haveempty = true;
3205 				continue;
3206 			}
3207 
3208 			array = DatumGetArrayTypeP(arraydatum);
3209 
3210 			/* run-time double-check on element type */
3211 			if (element_type != ARR_ELEMTYPE(array))
3212 				ereport(ERROR,
3213 						(errcode(ERRCODE_DATATYPE_MISMATCH),
3214 						 errmsg("cannot merge incompatible arrays"),
3215 						 errdetail("Array with element type %s cannot be "
3216 						 "included in ARRAY construct with element type %s.",
3217 								   format_type_be(ARR_ELEMTYPE(array)),
3218 								   format_type_be(element_type))));
3219 
3220 			this_ndims = ARR_NDIM(array);
3221 			/* temporarily ignore zero-dimensional subarrays */
3222 			if (this_ndims <= 0)
3223 			{
3224 				haveempty = true;
3225 				continue;
3226 			}
3227 
3228 			if (firstone)
3229 			{
3230 				/* Get sub-array details from first member */
3231 				elem_ndims = this_ndims;
3232 				ndims = elem_ndims + 1;
3233 				if (ndims <= 0 || ndims > MAXDIM)
3234 					ereport(ERROR,
3235 							(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3236 						  errmsg("number of array dimensions (%d) exceeds " \
3237 								 "the maximum allowed (%d)", ndims, MAXDIM)));
3238 
3239 				elem_dims = (int *) palloc(elem_ndims * sizeof(int));
3240 				memcpy(elem_dims, ARR_DIMS(array), elem_ndims * sizeof(int));
3241 				elem_lbs = (int *) palloc(elem_ndims * sizeof(int));
3242 				memcpy(elem_lbs, ARR_LBOUND(array), elem_ndims * sizeof(int));
3243 
3244 				firstone = false;
3245 			}
3246 			else
3247 			{
3248 				/* Check other sub-arrays are compatible */
3249 				if (elem_ndims != this_ndims ||
3250 					memcmp(elem_dims, ARR_DIMS(array),
3251 						   elem_ndims * sizeof(int)) != 0 ||
3252 					memcmp(elem_lbs, ARR_LBOUND(array),
3253 						   elem_ndims * sizeof(int)) != 0)
3254 					ereport(ERROR,
3255 							(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3256 							 errmsg("multidimensional arrays must have array "
3257 									"expressions with matching dimensions")));
3258 			}
3259 
3260 			subdata[outer_nelems] = ARR_DATA_PTR(array);
3261 			subbitmaps[outer_nelems] = ARR_NULLBITMAP(array);
3262 			subbytes[outer_nelems] = ARR_SIZE(array) - ARR_DATA_OFFSET(array);
3263 			nbytes += subbytes[outer_nelems];
3264 			subnitems[outer_nelems] = ArrayGetNItems(this_ndims,
3265 													 ARR_DIMS(array));
3266 			nitems += subnitems[outer_nelems];
3267 			havenulls |= ARR_HASNULL(array);
3268 			outer_nelems++;
3269 		}
3270 
3271 		/*
3272 		 * If all items were null or empty arrays, return an empty array;
3273 		 * otherwise, if some were and some weren't, raise error.  (Note: we
3274 		 * must special-case this somehow to avoid trying to generate a 1-D
3275 		 * array formed from empty arrays.  It's not ideal...)
3276 		 */
3277 		if (haveempty)
3278 		{
3279 			if (ndims == 0)		/* didn't find any nonempty array */
3280 				return PointerGetDatum(construct_empty_array(element_type));
3281 			ereport(ERROR,
3282 					(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3283 					 errmsg("multidimensional arrays must have array "
3284 							"expressions with matching dimensions")));
3285 		}
3286 
3287 		/* setup for multi-D array */
3288 		dims[0] = outer_nelems;
3289 		lbs[0] = 1;
3290 		for (i = 1; i < ndims; i++)
3291 		{
3292 			dims[i] = elem_dims[i - 1];
3293 			lbs[i] = elem_lbs[i - 1];
3294 		}
3295 
3296 		/* check for subscript overflow */
3297 		(void) ArrayGetNItems(ndims, dims);
3298 		ArrayCheckBounds(ndims, dims, lbs);
3299 
3300 		if (havenulls)
3301 		{
3302 			dataoffset = ARR_OVERHEAD_WITHNULLS(ndims, nitems);
3303 			nbytes += dataoffset;
3304 		}
3305 		else
3306 		{
3307 			dataoffset = 0;		/* marker for no null bitmap */
3308 			nbytes += ARR_OVERHEAD_NONULLS(ndims);
3309 		}
3310 
3311 		result = (ArrayType *) palloc(nbytes);
3312 		SET_VARSIZE(result, nbytes);
3313 		result->ndim = ndims;
3314 		result->dataoffset = dataoffset;
3315 		result->elemtype = element_type;
3316 		memcpy(ARR_DIMS(result), dims, ndims * sizeof(int));
3317 		memcpy(ARR_LBOUND(result), lbs, ndims * sizeof(int));
3318 
3319 		dat = ARR_DATA_PTR(result);
3320 		iitem = 0;
3321 		for (i = 0; i < outer_nelems; i++)
3322 		{
3323 			memcpy(dat, subdata[i], subbytes[i]);
3324 			dat += subbytes[i];
3325 			if (havenulls)
3326 				array_bitmap_copy(ARR_NULLBITMAP(result), iitem,
3327 								  subbitmaps[i], 0,
3328 								  subnitems[i]);
3329 			iitem += subnitems[i];
3330 		}
3331 	}
3332 
3333 	return PointerGetDatum(result);
3334 }
3335 
3336 /* ----------------------------------------------------------------
3337  *		ExecEvalRow - ROW() expressions
3338  * ----------------------------------------------------------------
3339  */
3340 static Datum
ExecEvalRow(RowExprState * rstate,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)3341 ExecEvalRow(RowExprState *rstate,
3342 			ExprContext *econtext,
3343 			bool *isNull, ExprDoneCond *isDone)
3344 {
3345 	HeapTuple	tuple;
3346 	Datum	   *values;
3347 	bool	   *isnull;
3348 	int			natts;
3349 	ListCell   *arg;
3350 	int			i;
3351 
3352 	/* Set default values for result flags: non-null, not a set result */
3353 	*isNull = false;
3354 	if (isDone)
3355 		*isDone = ExprSingleResult;
3356 
3357 	/* Allocate workspace */
3358 	natts = rstate->tupdesc->natts;
3359 	values = (Datum *) palloc0(natts * sizeof(Datum));
3360 	isnull = (bool *) palloc(natts * sizeof(bool));
3361 
3362 	/* preset to nulls in case rowtype has some later-added columns */
3363 	memset(isnull, true, natts * sizeof(bool));
3364 
3365 	/* Evaluate field values */
3366 	i = 0;
3367 	foreach(arg, rstate->args)
3368 	{
3369 		ExprState  *e = (ExprState *) lfirst(arg);
3370 
3371 		values[i] = ExecEvalExpr(e, econtext, &isnull[i], NULL);
3372 		i++;
3373 	}
3374 
3375 	tuple = heap_form_tuple(rstate->tupdesc, values, isnull);
3376 
3377 	pfree(values);
3378 	pfree(isnull);
3379 
3380 	return HeapTupleGetDatum(tuple);
3381 }
3382 
3383 /* ----------------------------------------------------------------
3384  *		ExecEvalRowCompare - ROW() comparison-op ROW()
3385  * ----------------------------------------------------------------
3386  */
3387 static Datum
ExecEvalRowCompare(RowCompareExprState * rstate,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)3388 ExecEvalRowCompare(RowCompareExprState *rstate,
3389 				   ExprContext *econtext,
3390 				   bool *isNull, ExprDoneCond *isDone)
3391 {
3392 	bool		result;
3393 	RowCompareType rctype = ((RowCompareExpr *) rstate->xprstate.expr)->rctype;
3394 	int32		cmpresult = 0;
3395 	ListCell   *l;
3396 	ListCell   *r;
3397 	int			i;
3398 
3399 	if (isDone)
3400 		*isDone = ExprSingleResult;
3401 	*isNull = true;				/* until we get a result */
3402 
3403 	i = 0;
3404 	forboth(l, rstate->largs, r, rstate->rargs)
3405 	{
3406 		ExprState  *le = (ExprState *) lfirst(l);
3407 		ExprState  *re = (ExprState *) lfirst(r);
3408 		FunctionCallInfoData locfcinfo;
3409 
3410 		InitFunctionCallInfoData(locfcinfo, &(rstate->funcs[i]), 2,
3411 								 rstate->collations[i],
3412 								 NULL, NULL);
3413 		locfcinfo.arg[0] = ExecEvalExpr(le, econtext,
3414 										&locfcinfo.argnull[0], NULL);
3415 		locfcinfo.arg[1] = ExecEvalExpr(re, econtext,
3416 										&locfcinfo.argnull[1], NULL);
3417 		if (rstate->funcs[i].fn_strict &&
3418 			(locfcinfo.argnull[0] || locfcinfo.argnull[1]))
3419 			return (Datum) 0;	/* force NULL result */
3420 		locfcinfo.isnull = false;
3421 		cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo));
3422 		if (locfcinfo.isnull)
3423 			return (Datum) 0;	/* force NULL result */
3424 		if (cmpresult != 0)
3425 			break;				/* no need to compare remaining columns */
3426 		i++;
3427 	}
3428 
3429 	switch (rctype)
3430 	{
3431 			/* EQ and NE cases aren't allowed here */
3432 		case ROWCOMPARE_LT:
3433 			result = (cmpresult < 0);
3434 			break;
3435 		case ROWCOMPARE_LE:
3436 			result = (cmpresult <= 0);
3437 			break;
3438 		case ROWCOMPARE_GE:
3439 			result = (cmpresult >= 0);
3440 			break;
3441 		case ROWCOMPARE_GT:
3442 			result = (cmpresult > 0);
3443 			break;
3444 		default:
3445 			elog(ERROR, "unrecognized RowCompareType: %d", (int) rctype);
3446 			result = 0;			/* keep compiler quiet */
3447 			break;
3448 	}
3449 
3450 	*isNull = false;
3451 	return BoolGetDatum(result);
3452 }
3453 
3454 /* ----------------------------------------------------------------
3455  *		ExecEvalCoalesce
3456  * ----------------------------------------------------------------
3457  */
3458 static Datum
ExecEvalCoalesce(CoalesceExprState * coalesceExpr,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)3459 ExecEvalCoalesce(CoalesceExprState *coalesceExpr, ExprContext *econtext,
3460 				 bool *isNull, ExprDoneCond *isDone)
3461 {
3462 	ListCell   *arg;
3463 
3464 	if (isDone)
3465 		*isDone = ExprSingleResult;
3466 
3467 	/* Simply loop through until something NOT NULL is found */
3468 	foreach(arg, coalesceExpr->args)
3469 	{
3470 		ExprState  *e = (ExprState *) lfirst(arg);
3471 		Datum		value;
3472 
3473 		value = ExecEvalExpr(e, econtext, isNull, NULL);
3474 		if (!*isNull)
3475 			return value;
3476 	}
3477 
3478 	/* Else return NULL */
3479 	*isNull = true;
3480 	return (Datum) 0;
3481 }
3482 
3483 /* ----------------------------------------------------------------
3484  *		ExecEvalMinMax
3485  * ----------------------------------------------------------------
3486  */
3487 static Datum
ExecEvalMinMax(MinMaxExprState * minmaxExpr,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)3488 ExecEvalMinMax(MinMaxExprState *minmaxExpr, ExprContext *econtext,
3489 			   bool *isNull, ExprDoneCond *isDone)
3490 {
3491 	Datum		result = (Datum) 0;
3492 	MinMaxExpr *minmax = (MinMaxExpr *) minmaxExpr->xprstate.expr;
3493 	Oid			collation = minmax->inputcollid;
3494 	MinMaxOp	op = minmax->op;
3495 	FunctionCallInfoData locfcinfo;
3496 	ListCell   *arg;
3497 
3498 	if (isDone)
3499 		*isDone = ExprSingleResult;
3500 	*isNull = true;				/* until we get a result */
3501 
3502 	InitFunctionCallInfoData(locfcinfo, &minmaxExpr->cfunc, 2,
3503 							 collation, NULL, NULL);
3504 	locfcinfo.argnull[0] = false;
3505 	locfcinfo.argnull[1] = false;
3506 
3507 	foreach(arg, minmaxExpr->args)
3508 	{
3509 		ExprState  *e = (ExprState *) lfirst(arg);
3510 		Datum		value;
3511 		bool		valueIsNull;
3512 		int32		cmpresult;
3513 
3514 		value = ExecEvalExpr(e, econtext, &valueIsNull, NULL);
3515 		if (valueIsNull)
3516 			continue;			/* ignore NULL inputs */
3517 
3518 		if (*isNull)
3519 		{
3520 			/* first nonnull input, adopt value */
3521 			result = value;
3522 			*isNull = false;
3523 		}
3524 		else
3525 		{
3526 			/* apply comparison function */
3527 			locfcinfo.arg[0] = result;
3528 			locfcinfo.arg[1] = value;
3529 			locfcinfo.isnull = false;
3530 			cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo));
3531 			if (locfcinfo.isnull)		/* probably should not happen */
3532 				continue;
3533 			if (cmpresult > 0 && op == IS_LEAST)
3534 				result = value;
3535 			else if (cmpresult < 0 && op == IS_GREATEST)
3536 				result = value;
3537 		}
3538 	}
3539 
3540 	return result;
3541 }
3542 
3543 /* ----------------------------------------------------------------
3544  *		ExecEvalXml
3545  * ----------------------------------------------------------------
3546  */
3547 static Datum
ExecEvalXml(XmlExprState * xmlExpr,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)3548 ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
3549 			bool *isNull, ExprDoneCond *isDone)
3550 {
3551 	XmlExpr    *xexpr = (XmlExpr *) xmlExpr->xprstate.expr;
3552 	Datum		value;
3553 	bool		isnull;
3554 	ListCell   *arg;
3555 	ListCell   *narg;
3556 
3557 	if (isDone)
3558 		*isDone = ExprSingleResult;
3559 	*isNull = true;				/* until we get a result */
3560 
3561 	switch (xexpr->op)
3562 	{
3563 		case IS_XMLCONCAT:
3564 			{
3565 				List	   *values = NIL;
3566 
3567 				foreach(arg, xmlExpr->args)
3568 				{
3569 					ExprState  *e = (ExprState *) lfirst(arg);
3570 
3571 					value = ExecEvalExpr(e, econtext, &isnull, NULL);
3572 					if (!isnull)
3573 						values = lappend(values, DatumGetPointer(value));
3574 				}
3575 
3576 				if (list_length(values) > 0)
3577 				{
3578 					*isNull = false;
3579 					return PointerGetDatum(xmlconcat(values));
3580 				}
3581 				else
3582 					return (Datum) 0;
3583 			}
3584 			break;
3585 
3586 		case IS_XMLFOREST:
3587 			{
3588 				StringInfoData buf;
3589 
3590 				initStringInfo(&buf);
3591 				forboth(arg, xmlExpr->named_args, narg, xexpr->arg_names)
3592 				{
3593 					ExprState  *e = (ExprState *) lfirst(arg);
3594 					char	   *argname = strVal(lfirst(narg));
3595 
3596 					value = ExecEvalExpr(e, econtext, &isnull, NULL);
3597 					if (!isnull)
3598 					{
3599 						appendStringInfo(&buf, "<%s>%s</%s>",
3600 										 argname,
3601 										 map_sql_value_to_xml_value(value, exprType((Node *) e->expr), true),
3602 										 argname);
3603 						*isNull = false;
3604 					}
3605 				}
3606 
3607 				if (*isNull)
3608 				{
3609 					pfree(buf.data);
3610 					return (Datum) 0;
3611 				}
3612 				else
3613 				{
3614 					text	   *result;
3615 
3616 					result = cstring_to_text_with_len(buf.data, buf.len);
3617 					pfree(buf.data);
3618 
3619 					return PointerGetDatum(result);
3620 				}
3621 			}
3622 			break;
3623 
3624 		case IS_XMLELEMENT:
3625 			*isNull = false;
3626 			return PointerGetDatum(xmlelement(xmlExpr, econtext));
3627 			break;
3628 
3629 		case IS_XMLPARSE:
3630 			{
3631 				ExprState  *e;
3632 				text	   *data;
3633 				bool		preserve_whitespace;
3634 
3635 				/* arguments are known to be text, bool */
3636 				Assert(list_length(xmlExpr->args) == 2);
3637 
3638 				e = (ExprState *) linitial(xmlExpr->args);
3639 				value = ExecEvalExpr(e, econtext, &isnull, NULL);
3640 				if (isnull)
3641 					return (Datum) 0;
3642 				data = DatumGetTextP(value);
3643 
3644 				e = (ExprState *) lsecond(xmlExpr->args);
3645 				value = ExecEvalExpr(e, econtext, &isnull, NULL);
3646 				if (isnull)		/* probably can't happen */
3647 					return (Datum) 0;
3648 				preserve_whitespace = DatumGetBool(value);
3649 
3650 				*isNull = false;
3651 
3652 				return PointerGetDatum(xmlparse(data,
3653 												xexpr->xmloption,
3654 												preserve_whitespace));
3655 			}
3656 			break;
3657 
3658 		case IS_XMLPI:
3659 			{
3660 				ExprState  *e;
3661 				text	   *arg;
3662 
3663 				/* optional argument is known to be text */
3664 				Assert(list_length(xmlExpr->args) <= 1);
3665 
3666 				if (xmlExpr->args)
3667 				{
3668 					e = (ExprState *) linitial(xmlExpr->args);
3669 					value = ExecEvalExpr(e, econtext, &isnull, NULL);
3670 					if (isnull)
3671 						arg = NULL;
3672 					else
3673 						arg = DatumGetTextP(value);
3674 				}
3675 				else
3676 				{
3677 					arg = NULL;
3678 					isnull = false;
3679 				}
3680 
3681 				return PointerGetDatum(xmlpi(xexpr->name, arg, isnull, isNull));
3682 			}
3683 			break;
3684 
3685 		case IS_XMLROOT:
3686 			{
3687 				ExprState  *e;
3688 				xmltype    *data;
3689 				text	   *version;
3690 				int			standalone;
3691 
3692 				/* arguments are known to be xml, text, int */
3693 				Assert(list_length(xmlExpr->args) == 3);
3694 
3695 				e = (ExprState *) linitial(xmlExpr->args);
3696 				value = ExecEvalExpr(e, econtext, &isnull, NULL);
3697 				if (isnull)
3698 					return (Datum) 0;
3699 				data = DatumGetXmlP(value);
3700 
3701 				e = (ExprState *) lsecond(xmlExpr->args);
3702 				value = ExecEvalExpr(e, econtext, &isnull, NULL);
3703 				if (isnull)
3704 					version = NULL;
3705 				else
3706 					version = DatumGetTextP(value);
3707 
3708 				e = (ExprState *) lthird(xmlExpr->args);
3709 				value = ExecEvalExpr(e, econtext, &isnull, NULL);
3710 				standalone = DatumGetInt32(value);
3711 
3712 				*isNull = false;
3713 
3714 				return PointerGetDatum(xmlroot(data,
3715 											   version,
3716 											   standalone));
3717 			}
3718 			break;
3719 
3720 		case IS_XMLSERIALIZE:
3721 			{
3722 				ExprState  *e;
3723 
3724 				/* argument type is known to be xml */
3725 				Assert(list_length(xmlExpr->args) == 1);
3726 
3727 				e = (ExprState *) linitial(xmlExpr->args);
3728 				value = ExecEvalExpr(e, econtext, &isnull, NULL);
3729 				if (isnull)
3730 					return (Datum) 0;
3731 
3732 				*isNull = false;
3733 
3734 				return PointerGetDatum(xmltotext_with_xmloption(DatumGetXmlP(value), xexpr->xmloption));
3735 			}
3736 			break;
3737 
3738 		case IS_DOCUMENT:
3739 			{
3740 				ExprState  *e;
3741 
3742 				/* optional argument is known to be xml */
3743 				Assert(list_length(xmlExpr->args) == 1);
3744 
3745 				e = (ExprState *) linitial(xmlExpr->args);
3746 				value = ExecEvalExpr(e, econtext, &isnull, NULL);
3747 				if (isnull)
3748 					return (Datum) 0;
3749 				else
3750 				{
3751 					*isNull = false;
3752 					return BoolGetDatum(xml_is_document(DatumGetXmlP(value)));
3753 				}
3754 			}
3755 			break;
3756 	}
3757 
3758 	elog(ERROR, "unrecognized XML operation");
3759 	return (Datum) 0;
3760 }
3761 
3762 /* ----------------------------------------------------------------
3763  *		ExecEvalNullIf
3764  *
3765  * Note that this is *always* derived from the equals operator,
3766  * but since we need special processing of the arguments
3767  * we can not simply reuse ExecEvalOper() or ExecEvalFunc().
3768  * ----------------------------------------------------------------
3769  */
3770 static Datum
ExecEvalNullIf(FuncExprState * nullIfExpr,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)3771 ExecEvalNullIf(FuncExprState *nullIfExpr,
3772 			   ExprContext *econtext,
3773 			   bool *isNull, ExprDoneCond *isDone)
3774 {
3775 	Datum		result;
3776 	FunctionCallInfo fcinfo;
3777 	ExprDoneCond argDone;
3778 
3779 	if (isDone)
3780 		*isDone = ExprSingleResult;
3781 
3782 	/*
3783 	 * Initialize function cache if first time through
3784 	 */
3785 	if (nullIfExpr->func.fn_oid == InvalidOid)
3786 	{
3787 		NullIfExpr *op = (NullIfExpr *) nullIfExpr->xprstate.expr;
3788 
3789 		init_fcache(op->opfuncid, op->inputcollid, nullIfExpr,
3790 					econtext->ecxt_per_query_memory, true);
3791 		Assert(!nullIfExpr->func.fn_retset);
3792 	}
3793 
3794 	/*
3795 	 * Evaluate arguments
3796 	 */
3797 	fcinfo = &nullIfExpr->fcinfo_data;
3798 	argDone = ExecEvalFuncArgs(fcinfo, nullIfExpr->args, econtext);
3799 	if (argDone != ExprSingleResult)
3800 		ereport(ERROR,
3801 				(errcode(ERRCODE_DATATYPE_MISMATCH),
3802 				 errmsg("NULLIF does not support set arguments")));
3803 	Assert(fcinfo->nargs == 2);
3804 
3805 	/* if either argument is NULL they can't be equal */
3806 	if (!fcinfo->argnull[0] && !fcinfo->argnull[1])
3807 	{
3808 		fcinfo->isnull = false;
3809 		result = FunctionCallInvoke(fcinfo);
3810 		/* if the arguments are equal return null */
3811 		if (!fcinfo->isnull && DatumGetBool(result))
3812 		{
3813 			*isNull = true;
3814 			return (Datum) 0;
3815 		}
3816 	}
3817 
3818 	/* else return first argument */
3819 	*isNull = fcinfo->argnull[0];
3820 	return fcinfo->arg[0];
3821 }
3822 
3823 /* ----------------------------------------------------------------
3824  *		ExecEvalNullTest
3825  *
3826  *		Evaluate a NullTest node.
3827  * ----------------------------------------------------------------
3828  */
3829 static Datum
ExecEvalNullTest(NullTestState * nstate,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)3830 ExecEvalNullTest(NullTestState *nstate,
3831 				 ExprContext *econtext,
3832 				 bool *isNull,
3833 				 ExprDoneCond *isDone)
3834 {
3835 	NullTest   *ntest = (NullTest *) nstate->xprstate.expr;
3836 	Datum		result;
3837 
3838 	result = ExecEvalExpr(nstate->arg, econtext, isNull, isDone);
3839 
3840 	if (isDone && *isDone == ExprEndResult)
3841 		return result;			/* nothing to check */
3842 
3843 	if (ntest->argisrow && !(*isNull))
3844 	{
3845 		/*
3846 		 * The SQL standard defines IS [NOT] NULL for a non-null rowtype
3847 		 * argument as:
3848 		 *
3849 		 * "R IS NULL" is true if every field is the null value.
3850 		 *
3851 		 * "R IS NOT NULL" is true if no field is the null value.
3852 		 *
3853 		 * This definition is (apparently intentionally) not recursive; so our
3854 		 * tests on the fields are primitive attisnull tests, not recursive
3855 		 * checks to see if they are all-nulls or no-nulls rowtypes.
3856 		 *
3857 		 * The standard does not consider the possibility of zero-field rows,
3858 		 * but here we consider them to vacuously satisfy both predicates.
3859 		 */
3860 		HeapTupleHeader tuple;
3861 		Oid			tupType;
3862 		int32		tupTypmod;
3863 		TupleDesc	tupDesc;
3864 		HeapTupleData tmptup;
3865 		int			att;
3866 
3867 		tuple = DatumGetHeapTupleHeader(result);
3868 
3869 		tupType = HeapTupleHeaderGetTypeId(tuple);
3870 		tupTypmod = HeapTupleHeaderGetTypMod(tuple);
3871 
3872 		/* Lookup tupdesc if first time through or if type changes */
3873 		tupDesc = get_cached_rowtype(tupType, tupTypmod,
3874 									 &nstate->argdesc, econtext);
3875 
3876 		/*
3877 		 * heap_attisnull needs a HeapTuple not a bare HeapTupleHeader.
3878 		 */
3879 		tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
3880 		tmptup.t_data = tuple;
3881 
3882 		for (att = 1; att <= tupDesc->natts; att++)
3883 		{
3884 			/* ignore dropped columns */
3885 			if (tupDesc->attrs[att - 1]->attisdropped)
3886 				continue;
3887 			if (heap_attisnull(&tmptup, att))
3888 			{
3889 				/* null field disproves IS NOT NULL */
3890 				if (ntest->nulltesttype == IS_NOT_NULL)
3891 					return BoolGetDatum(false);
3892 			}
3893 			else
3894 			{
3895 				/* non-null field disproves IS NULL */
3896 				if (ntest->nulltesttype == IS_NULL)
3897 					return BoolGetDatum(false);
3898 			}
3899 		}
3900 
3901 		return BoolGetDatum(true);
3902 	}
3903 	else
3904 	{
3905 		/* Simple scalar-argument case, or a null rowtype datum */
3906 		switch (ntest->nulltesttype)
3907 		{
3908 			case IS_NULL:
3909 				if (*isNull)
3910 				{
3911 					*isNull = false;
3912 					return BoolGetDatum(true);
3913 				}
3914 				else
3915 					return BoolGetDatum(false);
3916 			case IS_NOT_NULL:
3917 				if (*isNull)
3918 				{
3919 					*isNull = false;
3920 					return BoolGetDatum(false);
3921 				}
3922 				else
3923 					return BoolGetDatum(true);
3924 			default:
3925 				elog(ERROR, "unrecognized nulltesttype: %d",
3926 					 (int) ntest->nulltesttype);
3927 				return (Datum) 0;		/* keep compiler quiet */
3928 		}
3929 	}
3930 }
3931 
3932 /* ----------------------------------------------------------------
3933  *		ExecEvalBooleanTest
3934  *
3935  *		Evaluate a BooleanTest node.
3936  * ----------------------------------------------------------------
3937  */
3938 static Datum
ExecEvalBooleanTest(GenericExprState * bstate,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)3939 ExecEvalBooleanTest(GenericExprState *bstate,
3940 					ExprContext *econtext,
3941 					bool *isNull,
3942 					ExprDoneCond *isDone)
3943 {
3944 	BooleanTest *btest = (BooleanTest *) bstate->xprstate.expr;
3945 	Datum		result;
3946 
3947 	result = ExecEvalExpr(bstate->arg, econtext, isNull, isDone);
3948 
3949 	if (isDone && *isDone == ExprEndResult)
3950 		return result;			/* nothing to check */
3951 
3952 	switch (btest->booltesttype)
3953 	{
3954 		case IS_TRUE:
3955 			if (*isNull)
3956 			{
3957 				*isNull = false;
3958 				return BoolGetDatum(false);
3959 			}
3960 			else if (DatumGetBool(result))
3961 				return BoolGetDatum(true);
3962 			else
3963 				return BoolGetDatum(false);
3964 		case IS_NOT_TRUE:
3965 			if (*isNull)
3966 			{
3967 				*isNull = false;
3968 				return BoolGetDatum(true);
3969 			}
3970 			else if (DatumGetBool(result))
3971 				return BoolGetDatum(false);
3972 			else
3973 				return BoolGetDatum(true);
3974 		case IS_FALSE:
3975 			if (*isNull)
3976 			{
3977 				*isNull = false;
3978 				return BoolGetDatum(false);
3979 			}
3980 			else if (DatumGetBool(result))
3981 				return BoolGetDatum(false);
3982 			else
3983 				return BoolGetDatum(true);
3984 		case IS_NOT_FALSE:
3985 			if (*isNull)
3986 			{
3987 				*isNull = false;
3988 				return BoolGetDatum(true);
3989 			}
3990 			else if (DatumGetBool(result))
3991 				return BoolGetDatum(true);
3992 			else
3993 				return BoolGetDatum(false);
3994 		case IS_UNKNOWN:
3995 			if (*isNull)
3996 			{
3997 				*isNull = false;
3998 				return BoolGetDatum(true);
3999 			}
4000 			else
4001 				return BoolGetDatum(false);
4002 		case IS_NOT_UNKNOWN:
4003 			if (*isNull)
4004 			{
4005 				*isNull = false;
4006 				return BoolGetDatum(false);
4007 			}
4008 			else
4009 				return BoolGetDatum(true);
4010 		default:
4011 			elog(ERROR, "unrecognized booltesttype: %d",
4012 				 (int) btest->booltesttype);
4013 			return (Datum) 0;	/* keep compiler quiet */
4014 	}
4015 }
4016 
4017 /*
4018  * ExecEvalCoerceToDomain
4019  *
4020  * Test the provided data against the domain constraint(s).  If the data
4021  * passes the constraint specifications, pass it through (return the
4022  * datum) otherwise throw an error.
4023  */
4024 static Datum
ExecEvalCoerceToDomain(CoerceToDomainState * cstate,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)4025 ExecEvalCoerceToDomain(CoerceToDomainState *cstate, ExprContext *econtext,
4026 					   bool *isNull, ExprDoneCond *isDone)
4027 {
4028 	CoerceToDomain *ctest = (CoerceToDomain *) cstate->xprstate.expr;
4029 	Datum		result;
4030 	ListCell   *l;
4031 
4032 	result = ExecEvalExpr(cstate->arg, econtext, isNull, isDone);
4033 
4034 	if (isDone && *isDone == ExprEndResult)
4035 		return result;			/* nothing to check */
4036 
4037 	/* Make sure we have up-to-date constraints */
4038 	UpdateDomainConstraintRef(cstate->constraint_ref);
4039 
4040 	foreach(l, cstate->constraint_ref->constraints)
4041 	{
4042 		DomainConstraintState *con = (DomainConstraintState *) lfirst(l);
4043 
4044 		switch (con->constrainttype)
4045 		{
4046 			case DOM_CONSTRAINT_NOTNULL:
4047 				if (*isNull)
4048 					ereport(ERROR,
4049 							(errcode(ERRCODE_NOT_NULL_VIOLATION),
4050 							 errmsg("domain %s does not allow null values",
4051 									format_type_be(ctest->resulttype)),
4052 							 errdatatype(ctest->resulttype)));
4053 				break;
4054 			case DOM_CONSTRAINT_CHECK:
4055 				{
4056 					Datum		conResult;
4057 					bool		conIsNull;
4058 					Datum		save_datum;
4059 					bool		save_isNull;
4060 
4061 					/*
4062 					 * Set up value to be returned by CoerceToDomainValue
4063 					 * nodes. We must save and restore prior setting of
4064 					 * econtext's domainValue fields, in case this node is
4065 					 * itself within a check expression for another domain.
4066 					 *
4067 					 * Also, if we are working with a read-write expanded
4068 					 * datum, be sure that what we pass to CHECK expressions
4069 					 * is a read-only pointer; else called functions might
4070 					 * modify or even delete the expanded object.
4071 					 */
4072 					save_datum = econtext->domainValue_datum;
4073 					save_isNull = econtext->domainValue_isNull;
4074 
4075 					econtext->domainValue_datum =
4076 						MakeExpandedObjectReadOnly(result, *isNull,
4077 									 cstate->constraint_ref->tcache->typlen);
4078 					econtext->domainValue_isNull = *isNull;
4079 
4080 					conResult = ExecEvalExpr(con->check_expr,
4081 											 econtext, &conIsNull, NULL);
4082 
4083 					if (!conIsNull &&
4084 						!DatumGetBool(conResult))
4085 						ereport(ERROR,
4086 								(errcode(ERRCODE_CHECK_VIOLATION),
4087 								 errmsg("value for domain %s violates check constraint \"%s\"",
4088 										format_type_be(ctest->resulttype),
4089 										con->name),
4090 								 errdomainconstraint(ctest->resulttype,
4091 													 con->name)));
4092 					econtext->domainValue_datum = save_datum;
4093 					econtext->domainValue_isNull = save_isNull;
4094 
4095 					break;
4096 				}
4097 			default:
4098 				elog(ERROR, "unrecognized constraint type: %d",
4099 					 (int) con->constrainttype);
4100 				break;
4101 		}
4102 	}
4103 
4104 	/* If all has gone well (constraints did not fail) return the datum */
4105 	return result;
4106 }
4107 
4108 /*
4109  * ExecEvalCoerceToDomainValue
4110  *
4111  * Return the value stored by CoerceToDomain.
4112  */
4113 static Datum
ExecEvalCoerceToDomainValue(ExprState * exprstate,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)4114 ExecEvalCoerceToDomainValue(ExprState *exprstate,
4115 							ExprContext *econtext,
4116 							bool *isNull, ExprDoneCond *isDone)
4117 {
4118 	if (isDone)
4119 		*isDone = ExprSingleResult;
4120 	*isNull = econtext->domainValue_isNull;
4121 	return econtext->domainValue_datum;
4122 }
4123 
4124 /* ----------------------------------------------------------------
4125  *		ExecEvalFieldSelect
4126  *
4127  *		Evaluate a FieldSelect node.
4128  * ----------------------------------------------------------------
4129  */
4130 static Datum
ExecEvalFieldSelect(FieldSelectState * fstate,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)4131 ExecEvalFieldSelect(FieldSelectState *fstate,
4132 					ExprContext *econtext,
4133 					bool *isNull,
4134 					ExprDoneCond *isDone)
4135 {
4136 	FieldSelect *fselect = (FieldSelect *) fstate->xprstate.expr;
4137 	AttrNumber	fieldnum = fselect->fieldnum;
4138 	Datum		result;
4139 	Datum		tupDatum;
4140 	HeapTupleHeader tuple;
4141 	Oid			tupType;
4142 	int32		tupTypmod;
4143 	TupleDesc	tupDesc;
4144 	Form_pg_attribute attr;
4145 	HeapTupleData tmptup;
4146 
4147 	tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull, isDone);
4148 
4149 	/* this test covers the isDone exception too: */
4150 	if (*isNull)
4151 		return tupDatum;
4152 
4153 	tuple = DatumGetHeapTupleHeader(tupDatum);
4154 
4155 	tupType = HeapTupleHeaderGetTypeId(tuple);
4156 	tupTypmod = HeapTupleHeaderGetTypMod(tuple);
4157 
4158 	/* Lookup tupdesc if first time through or if type changes */
4159 	tupDesc = get_cached_rowtype(tupType, tupTypmod,
4160 								 &fstate->argdesc, econtext);
4161 
4162 	/*
4163 	 * Find field's attr record.  Note we don't support system columns here: a
4164 	 * datum tuple doesn't have valid values for most of the interesting
4165 	 * system columns anyway.
4166 	 */
4167 	if (fieldnum <= 0)			/* should never happen */
4168 		elog(ERROR, "unsupported reference to system column %d in FieldSelect",
4169 			 fieldnum);
4170 	if (fieldnum > tupDesc->natts)		/* should never happen */
4171 		elog(ERROR, "attribute number %d exceeds number of columns %d",
4172 			 fieldnum, tupDesc->natts);
4173 	attr = tupDesc->attrs[fieldnum - 1];
4174 
4175 	/* Check for dropped column, and force a NULL result if so */
4176 	if (attr->attisdropped)
4177 	{
4178 		*isNull = true;
4179 		return (Datum) 0;
4180 	}
4181 
4182 	/* Check for type mismatch --- possible after ALTER COLUMN TYPE? */
4183 	/* As in ExecEvalScalarVar, we should but can't check typmod */
4184 	if (fselect->resulttype != attr->atttypid)
4185 		ereport(ERROR,
4186 				(errcode(ERRCODE_DATATYPE_MISMATCH),
4187 				 errmsg("attribute %d has wrong type", fieldnum),
4188 				 errdetail("Table has type %s, but query expects %s.",
4189 						   format_type_be(attr->atttypid),
4190 						   format_type_be(fselect->resulttype))));
4191 
4192 	/* heap_getattr needs a HeapTuple not a bare HeapTupleHeader */
4193 	tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
4194 	tmptup.t_data = tuple;
4195 
4196 	result = heap_getattr(&tmptup,
4197 						  fieldnum,
4198 						  tupDesc,
4199 						  isNull);
4200 	return result;
4201 }
4202 
4203 /* ----------------------------------------------------------------
4204  *		ExecEvalFieldStore
4205  *
4206  *		Evaluate a FieldStore node.
4207  * ----------------------------------------------------------------
4208  */
4209 static Datum
ExecEvalFieldStore(FieldStoreState * fstate,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)4210 ExecEvalFieldStore(FieldStoreState *fstate,
4211 				   ExprContext *econtext,
4212 				   bool *isNull,
4213 				   ExprDoneCond *isDone)
4214 {
4215 	FieldStore *fstore = (FieldStore *) fstate->xprstate.expr;
4216 	HeapTuple	tuple;
4217 	Datum		tupDatum;
4218 	TupleDesc	tupDesc;
4219 	Datum	   *values;
4220 	bool	   *isnull;
4221 	Datum		save_datum;
4222 	bool		save_isNull;
4223 	ListCell   *l1,
4224 			   *l2;
4225 
4226 	tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull, isDone);
4227 
4228 	if (isDone && *isDone == ExprEndResult)
4229 		return tupDatum;
4230 
4231 	/* Lookup tupdesc if first time through or after rescan */
4232 	tupDesc = get_cached_rowtype(fstore->resulttype, -1,
4233 								 &fstate->argdesc, econtext);
4234 
4235 	/* Allocate workspace */
4236 	values = (Datum *) palloc(tupDesc->natts * sizeof(Datum));
4237 	isnull = (bool *) palloc(tupDesc->natts * sizeof(bool));
4238 
4239 	if (!*isNull)
4240 	{
4241 		/*
4242 		 * heap_deform_tuple needs a HeapTuple not a bare HeapTupleHeader. We
4243 		 * set all the fields in the struct just in case.
4244 		 */
4245 		HeapTupleHeader tuphdr;
4246 		HeapTupleData tmptup;
4247 
4248 		tuphdr = DatumGetHeapTupleHeader(tupDatum);
4249 		tmptup.t_len = HeapTupleHeaderGetDatumLength(tuphdr);
4250 		ItemPointerSetInvalid(&(tmptup.t_self));
4251 		tmptup.t_tableOid = InvalidOid;
4252 		tmptup.t_data = tuphdr;
4253 
4254 		heap_deform_tuple(&tmptup, tupDesc, values, isnull);
4255 	}
4256 	else
4257 	{
4258 		/* Convert null input tuple into an all-nulls row */
4259 		memset(isnull, true, tupDesc->natts * sizeof(bool));
4260 	}
4261 
4262 	/* Result is never null */
4263 	*isNull = false;
4264 
4265 	save_datum = econtext->caseValue_datum;
4266 	save_isNull = econtext->caseValue_isNull;
4267 
4268 	forboth(l1, fstate->newvals, l2, fstore->fieldnums)
4269 	{
4270 		ExprState  *newval = (ExprState *) lfirst(l1);
4271 		AttrNumber	fieldnum = lfirst_int(l2);
4272 
4273 		Assert(fieldnum > 0 && fieldnum <= tupDesc->natts);
4274 
4275 		/*
4276 		 * Use the CaseTestExpr mechanism to pass down the old value of the
4277 		 * field being replaced; this is needed in case the newval is itself a
4278 		 * FieldStore or ArrayRef that has to obtain and modify the old value.
4279 		 * It's safe to reuse the CASE mechanism because there cannot be a
4280 		 * CASE between here and where the value would be needed, and a field
4281 		 * assignment can't be within a CASE either.  (So saving and restoring
4282 		 * the caseValue is just paranoia, but let's do it anyway.)
4283 		 */
4284 		econtext->caseValue_datum = values[fieldnum - 1];
4285 		econtext->caseValue_isNull = isnull[fieldnum - 1];
4286 
4287 		values[fieldnum - 1] = ExecEvalExpr(newval,
4288 											econtext,
4289 											&isnull[fieldnum - 1],
4290 											NULL);
4291 	}
4292 
4293 	econtext->caseValue_datum = save_datum;
4294 	econtext->caseValue_isNull = save_isNull;
4295 
4296 	tuple = heap_form_tuple(tupDesc, values, isnull);
4297 
4298 	pfree(values);
4299 	pfree(isnull);
4300 
4301 	return HeapTupleGetDatum(tuple);
4302 }
4303 
4304 /* ----------------------------------------------------------------
4305  *		ExecEvalRelabelType
4306  *
4307  *		Evaluate a RelabelType node.
4308  * ----------------------------------------------------------------
4309  */
4310 static Datum
ExecEvalRelabelType(GenericExprState * exprstate,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)4311 ExecEvalRelabelType(GenericExprState *exprstate,
4312 					ExprContext *econtext,
4313 					bool *isNull, ExprDoneCond *isDone)
4314 {
4315 	return ExecEvalExpr(exprstate->arg, econtext, isNull, isDone);
4316 }
4317 
4318 /* ----------------------------------------------------------------
4319  *		ExecEvalCoerceViaIO
4320  *
4321  *		Evaluate a CoerceViaIO node.
4322  * ----------------------------------------------------------------
4323  */
4324 static Datum
ExecEvalCoerceViaIO(CoerceViaIOState * iostate,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)4325 ExecEvalCoerceViaIO(CoerceViaIOState *iostate,
4326 					ExprContext *econtext,
4327 					bool *isNull, ExprDoneCond *isDone)
4328 {
4329 	Datum		result;
4330 	Datum		inputval;
4331 	char	   *string;
4332 
4333 	inputval = ExecEvalExpr(iostate->arg, econtext, isNull, isDone);
4334 
4335 	if (isDone && *isDone == ExprEndResult)
4336 		return inputval;		/* nothing to do */
4337 
4338 	if (*isNull)
4339 		string = NULL;			/* output functions are not called on nulls */
4340 	else
4341 		string = OutputFunctionCall(&iostate->outfunc, inputval);
4342 
4343 	result = InputFunctionCall(&iostate->infunc,
4344 							   string,
4345 							   iostate->intypioparam,
4346 							   -1);
4347 
4348 	/* The input function cannot change the null/not-null status */
4349 	return result;
4350 }
4351 
4352 /* ----------------------------------------------------------------
4353  *		ExecEvalArrayCoerceExpr
4354  *
4355  *		Evaluate an ArrayCoerceExpr node.
4356  * ----------------------------------------------------------------
4357  */
4358 static Datum
ExecEvalArrayCoerceExpr(ArrayCoerceExprState * astate,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)4359 ExecEvalArrayCoerceExpr(ArrayCoerceExprState *astate,
4360 						ExprContext *econtext,
4361 						bool *isNull, ExprDoneCond *isDone)
4362 {
4363 	ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) astate->xprstate.expr;
4364 	Datum		result;
4365 	FunctionCallInfoData locfcinfo;
4366 
4367 	result = ExecEvalExpr(astate->arg, econtext, isNull, isDone);
4368 
4369 	if (isDone && *isDone == ExprEndResult)
4370 		return result;			/* nothing to do */
4371 	if (*isNull)
4372 		return result;			/* nothing to do */
4373 
4374 	/*
4375 	 * If it's binary-compatible, modify the element type in the array header,
4376 	 * but otherwise leave the array as we received it.
4377 	 */
4378 	if (!OidIsValid(acoerce->elemfuncid))
4379 	{
4380 		/* Detoast input array if necessary, and copy in any case */
4381 		ArrayType  *array = DatumGetArrayTypePCopy(result);
4382 
4383 		ARR_ELEMTYPE(array) = astate->resultelemtype;
4384 		PG_RETURN_ARRAYTYPE_P(array);
4385 	}
4386 
4387 	/* Initialize function cache if first time through */
4388 	if (astate->elemfunc.fn_oid == InvalidOid)
4389 	{
4390 		AclResult	aclresult;
4391 
4392 		/* Check permission to call function */
4393 		aclresult = pg_proc_aclcheck(acoerce->elemfuncid, GetUserId(),
4394 									 ACL_EXECUTE);
4395 		if (aclresult != ACLCHECK_OK)
4396 			aclcheck_error(aclresult, ACL_KIND_PROC,
4397 						   get_func_name(acoerce->elemfuncid));
4398 		InvokeFunctionExecuteHook(acoerce->elemfuncid);
4399 
4400 		/* Set up the primary fmgr lookup information */
4401 		fmgr_info_cxt(acoerce->elemfuncid, &(astate->elemfunc),
4402 					  econtext->ecxt_per_query_memory);
4403 		fmgr_info_set_expr((Node *) acoerce, &(astate->elemfunc));
4404 	}
4405 
4406 	/*
4407 	 * Use array_map to apply the function to each array element.
4408 	 *
4409 	 * We pass on the desttypmod and isExplicit flags whether or not the
4410 	 * function wants them.
4411 	 *
4412 	 * Note: coercion functions are assumed to not use collation.
4413 	 */
4414 	InitFunctionCallInfoData(locfcinfo, &(astate->elemfunc), 3,
4415 							 InvalidOid, NULL, NULL);
4416 	locfcinfo.arg[0] = result;
4417 	locfcinfo.arg[1] = Int32GetDatum(acoerce->resulttypmod);
4418 	locfcinfo.arg[2] = BoolGetDatum(acoerce->isExplicit);
4419 	locfcinfo.argnull[0] = false;
4420 	locfcinfo.argnull[1] = false;
4421 	locfcinfo.argnull[2] = false;
4422 
4423 	return array_map(&locfcinfo, astate->resultelemtype, astate->amstate);
4424 }
4425 
4426 /* ----------------------------------------------------------------
4427  *		ExecEvalCurrentOfExpr
4428  *
4429  * The planner should convert CURRENT OF into a TidScan qualification, or some
4430  * other special handling in a ForeignScan node.  So we have to be able to do
4431  * ExecInitExpr on a CurrentOfExpr, but we shouldn't ever actually execute it.
4432  * If we get here, we suppose we must be dealing with CURRENT OF on a foreign
4433  * table whose FDW doesn't handle it, and complain accordingly.
4434  * ----------------------------------------------------------------
4435  */
4436 static Datum
ExecEvalCurrentOfExpr(ExprState * exprstate,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)4437 ExecEvalCurrentOfExpr(ExprState *exprstate, ExprContext *econtext,
4438 					  bool *isNull, ExprDoneCond *isDone)
4439 {
4440 	ereport(ERROR,
4441 			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4442 		   errmsg("WHERE CURRENT OF is not supported for this table type")));
4443 	return 0;					/* keep compiler quiet */
4444 }
4445 
4446 
4447 /*
4448  * ExecEvalExprSwitchContext
4449  *
4450  * Same as ExecEvalExpr, but get into the right allocation context explicitly.
4451  */
4452 Datum
ExecEvalExprSwitchContext(ExprState * expression,ExprContext * econtext,bool * isNull,ExprDoneCond * isDone)4453 ExecEvalExprSwitchContext(ExprState *expression,
4454 						  ExprContext *econtext,
4455 						  bool *isNull,
4456 						  ExprDoneCond *isDone)
4457 {
4458 	Datum		retDatum;
4459 	MemoryContext oldContext;
4460 
4461 	oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
4462 	retDatum = ExecEvalExpr(expression, econtext, isNull, isDone);
4463 	MemoryContextSwitchTo(oldContext);
4464 	return retDatum;
4465 }
4466 
4467 
4468 /*
4469  * ExecInitExpr: prepare an expression tree for execution
4470  *
4471  * This function builds and returns an ExprState tree paralleling the given
4472  * Expr node tree.  The ExprState tree can then be handed to ExecEvalExpr
4473  * for execution.  Because the Expr tree itself is read-only as far as
4474  * ExecInitExpr and ExecEvalExpr are concerned, several different executions
4475  * of the same plan tree can occur concurrently.
4476  *
4477  * This must be called in a memory context that will last as long as repeated
4478  * executions of the expression are needed.  Typically the context will be
4479  * the same as the per-query context of the associated ExprContext.
4480  *
4481  * Any Aggref, WindowFunc, or SubPlan nodes found in the tree are added to the
4482  * lists of such nodes held by the parent PlanState. Otherwise, we do very
4483  * little initialization here other than building the state-node tree.  Any
4484  * nontrivial work associated with initializing runtime info for a node should
4485  * happen during the first actual evaluation of that node.  (This policy lets
4486  * us avoid work if the node is never actually evaluated.)
4487  *
4488  * Note: there is no ExecEndExpr function; we assume that any resource
4489  * cleanup needed will be handled by just releasing the memory context
4490  * in which the state tree is built.  Functions that require additional
4491  * cleanup work can register a shutdown callback in the ExprContext.
4492  *
4493  *	'node' is the root of the expression tree to examine
4494  *	'parent' is the PlanState node that owns the expression.
4495  *
4496  * 'parent' may be NULL if we are preparing an expression that is not
4497  * associated with a plan tree.  (If so, it can't have aggs or subplans.)
4498  * This case should usually come through ExecPrepareExpr, not directly here.
4499  */
4500 ExprState *
ExecInitExpr(Expr * node,PlanState * parent)4501 ExecInitExpr(Expr *node, PlanState *parent)
4502 {
4503 	ExprState  *state;
4504 
4505 	if (node == NULL)
4506 		return NULL;
4507 
4508 	/* Guard against stack overflow due to overly complex expressions */
4509 	check_stack_depth();
4510 
4511 	switch (nodeTag(node))
4512 	{
4513 		case T_Var:
4514 			/* varattno == InvalidAttrNumber means it's a whole-row Var */
4515 			if (((Var *) node)->varattno == InvalidAttrNumber)
4516 			{
4517 				WholeRowVarExprState *wstate = makeNode(WholeRowVarExprState);
4518 
4519 				wstate->parent = parent;
4520 				wstate->wrv_tupdesc = NULL;
4521 				wstate->wrv_junkFilter = NULL;
4522 				state = (ExprState *) wstate;
4523 				state->evalfunc = (ExprStateEvalFunc) ExecEvalWholeRowVar;
4524 			}
4525 			else
4526 			{
4527 				state = (ExprState *) makeNode(ExprState);
4528 				state->evalfunc = ExecEvalScalarVar;
4529 			}
4530 			break;
4531 		case T_Const:
4532 			state = (ExprState *) makeNode(ExprState);
4533 			state->evalfunc = ExecEvalConst;
4534 			break;
4535 		case T_Param:
4536 			state = (ExprState *) makeNode(ExprState);
4537 			switch (((Param *) node)->paramkind)
4538 			{
4539 				case PARAM_EXEC:
4540 					state->evalfunc = ExecEvalParamExec;
4541 					break;
4542 				case PARAM_EXTERN:
4543 					state->evalfunc = ExecEvalParamExtern;
4544 					break;
4545 				default:
4546 					elog(ERROR, "unrecognized paramkind: %d",
4547 						 (int) ((Param *) node)->paramkind);
4548 					break;
4549 			}
4550 			break;
4551 		case T_CoerceToDomainValue:
4552 			state = (ExprState *) makeNode(ExprState);
4553 			state->evalfunc = ExecEvalCoerceToDomainValue;
4554 			break;
4555 		case T_CaseTestExpr:
4556 			state = (ExprState *) makeNode(ExprState);
4557 			state->evalfunc = ExecEvalCaseTestExpr;
4558 			break;
4559 		case T_Aggref:
4560 			{
4561 				AggrefExprState *astate = makeNode(AggrefExprState);
4562 
4563 				astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalAggref;
4564 				if (parent && IsA(parent, AggState))
4565 				{
4566 					AggState   *aggstate = (AggState *) parent;
4567 
4568 					aggstate->aggs = lcons(astate, aggstate->aggs);
4569 					aggstate->numaggs++;
4570 				}
4571 				else
4572 				{
4573 					/* planner messed up */
4574 					elog(ERROR, "Aggref found in non-Agg plan node");
4575 				}
4576 				state = (ExprState *) astate;
4577 			}
4578 			break;
4579 		case T_GroupingFunc:
4580 			{
4581 				GroupingFunc *grp_node = (GroupingFunc *) node;
4582 				GroupingFuncExprState *grp_state = makeNode(GroupingFuncExprState);
4583 				Agg		   *agg = NULL;
4584 
4585 				if (!parent || !IsA(parent, AggState) ||!IsA(parent->plan, Agg))
4586 					elog(ERROR, "parent of GROUPING is not Agg node");
4587 
4588 				grp_state->aggstate = (AggState *) parent;
4589 
4590 				agg = (Agg *) (parent->plan);
4591 
4592 				if (agg->groupingSets)
4593 					grp_state->clauses = grp_node->cols;
4594 				else
4595 					grp_state->clauses = NIL;
4596 
4597 				state = (ExprState *) grp_state;
4598 				state->evalfunc = (ExprStateEvalFunc) ExecEvalGroupingFuncExpr;
4599 			}
4600 			break;
4601 		case T_WindowFunc:
4602 			{
4603 				WindowFunc *wfunc = (WindowFunc *) node;
4604 				WindowFuncExprState *wfstate = makeNode(WindowFuncExprState);
4605 
4606 				wfstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalWindowFunc;
4607 				if (parent && IsA(parent, WindowAggState))
4608 				{
4609 					WindowAggState *winstate = (WindowAggState *) parent;
4610 					int			nfuncs;
4611 
4612 					winstate->funcs = lcons(wfstate, winstate->funcs);
4613 					nfuncs = ++winstate->numfuncs;
4614 					if (wfunc->winagg)
4615 						winstate->numaggs++;
4616 
4617 					wfstate->args = (List *) ExecInitExpr((Expr *) wfunc->args,
4618 														  parent);
4619 					wfstate->aggfilter = ExecInitExpr(wfunc->aggfilter,
4620 													  parent);
4621 
4622 					/*
4623 					 * Complain if the windowfunc's arguments contain any
4624 					 * windowfuncs; nested window functions are semantically
4625 					 * nonsensical.  (This should have been caught earlier,
4626 					 * but we defend against it here anyway.)
4627 					 */
4628 					if (nfuncs != winstate->numfuncs)
4629 						ereport(ERROR,
4630 								(errcode(ERRCODE_WINDOWING_ERROR),
4631 						  errmsg("window function calls cannot be nested")));
4632 				}
4633 				else
4634 				{
4635 					/* planner messed up */
4636 					elog(ERROR, "WindowFunc found in non-WindowAgg plan node");
4637 				}
4638 				state = (ExprState *) wfstate;
4639 			}
4640 			break;
4641 		case T_ArrayRef:
4642 			{
4643 				ArrayRef   *aref = (ArrayRef *) node;
4644 				ArrayRefExprState *astate = makeNode(ArrayRefExprState);
4645 
4646 				astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArrayRef;
4647 				astate->refupperindexpr = (List *)
4648 					ExecInitExpr((Expr *) aref->refupperindexpr, parent);
4649 				astate->reflowerindexpr = (List *)
4650 					ExecInitExpr((Expr *) aref->reflowerindexpr, parent);
4651 				astate->refexpr = ExecInitExpr(aref->refexpr, parent);
4652 				astate->refassgnexpr = ExecInitExpr(aref->refassgnexpr,
4653 													parent);
4654 				/* do one-time catalog lookups for type info */
4655 				astate->refattrlength = get_typlen(aref->refarraytype);
4656 				get_typlenbyvalalign(aref->refelemtype,
4657 									 &astate->refelemlength,
4658 									 &astate->refelembyval,
4659 									 &astate->refelemalign);
4660 				state = (ExprState *) astate;
4661 			}
4662 			break;
4663 		case T_FuncExpr:
4664 			{
4665 				FuncExpr   *funcexpr = (FuncExpr *) node;
4666 				FuncExprState *fstate = makeNode(FuncExprState);
4667 
4668 				fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFunc;
4669 				fstate->args = (List *)
4670 					ExecInitExpr((Expr *) funcexpr->args, parent);
4671 				fstate->func.fn_oid = InvalidOid;		/* not initialized */
4672 				state = (ExprState *) fstate;
4673 			}
4674 			break;
4675 		case T_OpExpr:
4676 			{
4677 				OpExpr	   *opexpr = (OpExpr *) node;
4678 				FuncExprState *fstate = makeNode(FuncExprState);
4679 
4680 				fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalOper;
4681 				fstate->args = (List *)
4682 					ExecInitExpr((Expr *) opexpr->args, parent);
4683 				fstate->func.fn_oid = InvalidOid;		/* not initialized */
4684 				state = (ExprState *) fstate;
4685 			}
4686 			break;
4687 		case T_DistinctExpr:
4688 			{
4689 				DistinctExpr *distinctexpr = (DistinctExpr *) node;
4690 				FuncExprState *fstate = makeNode(FuncExprState);
4691 
4692 				fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalDistinct;
4693 				fstate->args = (List *)
4694 					ExecInitExpr((Expr *) distinctexpr->args, parent);
4695 				fstate->func.fn_oid = InvalidOid;		/* not initialized */
4696 				state = (ExprState *) fstate;
4697 			}
4698 			break;
4699 		case T_NullIfExpr:
4700 			{
4701 				NullIfExpr *nullifexpr = (NullIfExpr *) node;
4702 				FuncExprState *fstate = makeNode(FuncExprState);
4703 
4704 				fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNullIf;
4705 				fstate->args = (List *)
4706 					ExecInitExpr((Expr *) nullifexpr->args, parent);
4707 				fstate->func.fn_oid = InvalidOid;		/* not initialized */
4708 				state = (ExprState *) fstate;
4709 			}
4710 			break;
4711 		case T_ScalarArrayOpExpr:
4712 			{
4713 				ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) node;
4714 				ScalarArrayOpExprState *sstate = makeNode(ScalarArrayOpExprState);
4715 
4716 				sstate->fxprstate.xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalScalarArrayOp;
4717 				sstate->fxprstate.args = (List *)
4718 					ExecInitExpr((Expr *) opexpr->args, parent);
4719 				sstate->fxprstate.func.fn_oid = InvalidOid;		/* not initialized */
4720 				sstate->element_type = InvalidOid;		/* ditto */
4721 				state = (ExprState *) sstate;
4722 			}
4723 			break;
4724 		case T_BoolExpr:
4725 			{
4726 				BoolExpr   *boolexpr = (BoolExpr *) node;
4727 				BoolExprState *bstate = makeNode(BoolExprState);
4728 
4729 				switch (boolexpr->boolop)
4730 				{
4731 					case AND_EXPR:
4732 						bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalAnd;
4733 						break;
4734 					case OR_EXPR:
4735 						bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalOr;
4736 						break;
4737 					case NOT_EXPR:
4738 						bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNot;
4739 						break;
4740 					default:
4741 						elog(ERROR, "unrecognized boolop: %d",
4742 							 (int) boolexpr->boolop);
4743 						break;
4744 				}
4745 				bstate->args = (List *)
4746 					ExecInitExpr((Expr *) boolexpr->args, parent);
4747 				state = (ExprState *) bstate;
4748 			}
4749 			break;
4750 		case T_SubPlan:
4751 			{
4752 				SubPlan    *subplan = (SubPlan *) node;
4753 				SubPlanState *sstate;
4754 
4755 				if (!parent)
4756 					elog(ERROR, "SubPlan found with no parent plan");
4757 
4758 				sstate = ExecInitSubPlan(subplan, parent);
4759 
4760 				/* Add SubPlanState nodes to parent->subPlan */
4761 				parent->subPlan = lappend(parent->subPlan, sstate);
4762 
4763 				state = (ExprState *) sstate;
4764 			}
4765 			break;
4766 		case T_AlternativeSubPlan:
4767 			{
4768 				AlternativeSubPlan *asplan = (AlternativeSubPlan *) node;
4769 				AlternativeSubPlanState *asstate;
4770 
4771 				if (!parent)
4772 					elog(ERROR, "AlternativeSubPlan found with no parent plan");
4773 
4774 				asstate = ExecInitAlternativeSubPlan(asplan, parent);
4775 
4776 				state = (ExprState *) asstate;
4777 			}
4778 			break;
4779 		case T_FieldSelect:
4780 			{
4781 				FieldSelect *fselect = (FieldSelect *) node;
4782 				FieldSelectState *fstate = makeNode(FieldSelectState);
4783 
4784 				fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFieldSelect;
4785 				fstate->arg = ExecInitExpr(fselect->arg, parent);
4786 				fstate->argdesc = NULL;
4787 				state = (ExprState *) fstate;
4788 			}
4789 			break;
4790 		case T_FieldStore:
4791 			{
4792 				FieldStore *fstore = (FieldStore *) node;
4793 				FieldStoreState *fstate = makeNode(FieldStoreState);
4794 
4795 				fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFieldStore;
4796 				fstate->arg = ExecInitExpr(fstore->arg, parent);
4797 				fstate->newvals = (List *) ExecInitExpr((Expr *) fstore->newvals, parent);
4798 				fstate->argdesc = NULL;
4799 				state = (ExprState *) fstate;
4800 			}
4801 			break;
4802 		case T_RelabelType:
4803 			{
4804 				RelabelType *relabel = (RelabelType *) node;
4805 				GenericExprState *gstate = makeNode(GenericExprState);
4806 
4807 				gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRelabelType;
4808 				gstate->arg = ExecInitExpr(relabel->arg, parent);
4809 				state = (ExprState *) gstate;
4810 			}
4811 			break;
4812 		case T_CoerceViaIO:
4813 			{
4814 				CoerceViaIO *iocoerce = (CoerceViaIO *) node;
4815 				CoerceViaIOState *iostate = makeNode(CoerceViaIOState);
4816 				Oid			iofunc;
4817 				bool		typisvarlena;
4818 
4819 				iostate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoerceViaIO;
4820 				iostate->arg = ExecInitExpr(iocoerce->arg, parent);
4821 				/* lookup the result type's input function */
4822 				getTypeInputInfo(iocoerce->resulttype, &iofunc,
4823 								 &iostate->intypioparam);
4824 				fmgr_info(iofunc, &iostate->infunc);
4825 				/* lookup the input type's output function */
4826 				getTypeOutputInfo(exprType((Node *) iocoerce->arg),
4827 								  &iofunc, &typisvarlena);
4828 				fmgr_info(iofunc, &iostate->outfunc);
4829 				state = (ExprState *) iostate;
4830 			}
4831 			break;
4832 		case T_ArrayCoerceExpr:
4833 			{
4834 				ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node;
4835 				ArrayCoerceExprState *astate = makeNode(ArrayCoerceExprState);
4836 
4837 				astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArrayCoerceExpr;
4838 				astate->arg = ExecInitExpr(acoerce->arg, parent);
4839 				astate->resultelemtype = get_element_type(acoerce->resulttype);
4840 				if (astate->resultelemtype == InvalidOid)
4841 					ereport(ERROR,
4842 							(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4843 							 errmsg("target type is not an array")));
4844 				/* Arrays over domains aren't supported yet */
4845 				Assert(getBaseType(astate->resultelemtype) ==
4846 					   astate->resultelemtype);
4847 				astate->elemfunc.fn_oid = InvalidOid;	/* not initialized */
4848 				astate->amstate = (ArrayMapState *) palloc0(sizeof(ArrayMapState));
4849 				state = (ExprState *) astate;
4850 			}
4851 			break;
4852 		case T_ConvertRowtypeExpr:
4853 			{
4854 				ConvertRowtypeExpr *convert = (ConvertRowtypeExpr *) node;
4855 				ConvertRowtypeExprState *cstate = makeNode(ConvertRowtypeExprState);
4856 
4857 				cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalConvertRowtype;
4858 				cstate->arg = ExecInitExpr(convert->arg, parent);
4859 				state = (ExprState *) cstate;
4860 			}
4861 			break;
4862 		case T_CaseExpr:
4863 			{
4864 				CaseExpr   *caseexpr = (CaseExpr *) node;
4865 				CaseExprState *cstate = makeNode(CaseExprState);
4866 				List	   *outlist = NIL;
4867 				ListCell   *l;
4868 
4869 				cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCase;
4870 				cstate->arg = ExecInitExpr(caseexpr->arg, parent);
4871 				foreach(l, caseexpr->args)
4872 				{
4873 					CaseWhen   *when = (CaseWhen *) lfirst(l);
4874 					CaseWhenState *wstate = makeNode(CaseWhenState);
4875 
4876 					Assert(IsA(when, CaseWhen));
4877 					wstate->xprstate.evalfunc = NULL;	/* not used */
4878 					wstate->xprstate.expr = (Expr *) when;
4879 					wstate->expr = ExecInitExpr(when->expr, parent);
4880 					wstate->result = ExecInitExpr(when->result, parent);
4881 					outlist = lappend(outlist, wstate);
4882 				}
4883 				cstate->args = outlist;
4884 				cstate->defresult = ExecInitExpr(caseexpr->defresult, parent);
4885 				if (caseexpr->arg)
4886 					cstate->argtyplen = get_typlen(exprType((Node *) caseexpr->arg));
4887 				state = (ExprState *) cstate;
4888 			}
4889 			break;
4890 		case T_ArrayExpr:
4891 			{
4892 				ArrayExpr  *arrayexpr = (ArrayExpr *) node;
4893 				ArrayExprState *astate = makeNode(ArrayExprState);
4894 				List	   *outlist = NIL;
4895 				ListCell   *l;
4896 
4897 				astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArray;
4898 				foreach(l, arrayexpr->elements)
4899 				{
4900 					Expr	   *e = (Expr *) lfirst(l);
4901 					ExprState  *estate;
4902 
4903 					estate = ExecInitExpr(e, parent);
4904 					outlist = lappend(outlist, estate);
4905 				}
4906 				astate->elements = outlist;
4907 				/* do one-time catalog lookup for type info */
4908 				get_typlenbyvalalign(arrayexpr->element_typeid,
4909 									 &astate->elemlength,
4910 									 &astate->elembyval,
4911 									 &astate->elemalign);
4912 				state = (ExprState *) astate;
4913 			}
4914 			break;
4915 		case T_RowExpr:
4916 			{
4917 				RowExpr    *rowexpr = (RowExpr *) node;
4918 				RowExprState *rstate = makeNode(RowExprState);
4919 				Form_pg_attribute *attrs;
4920 				List	   *outlist = NIL;
4921 				ListCell   *l;
4922 				int			i;
4923 
4924 				rstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRow;
4925 				/* Build tupdesc to describe result tuples */
4926 				if (rowexpr->row_typeid == RECORDOID)
4927 				{
4928 					/* generic record, use types of given expressions */
4929 					rstate->tupdesc = ExecTypeFromExprList(rowexpr->args);
4930 				}
4931 				else
4932 				{
4933 					/* it's been cast to a named type, use that */
4934 					rstate->tupdesc = lookup_rowtype_tupdesc_copy(rowexpr->row_typeid, -1);
4935 				}
4936 				/* In either case, adopt RowExpr's column aliases */
4937 				ExecTypeSetColNames(rstate->tupdesc, rowexpr->colnames);
4938 				/* Bless the tupdesc in case it's now of type RECORD */
4939 				BlessTupleDesc(rstate->tupdesc);
4940 				/* Set up evaluation, skipping any deleted columns */
4941 				Assert(list_length(rowexpr->args) <= rstate->tupdesc->natts);
4942 				attrs = rstate->tupdesc->attrs;
4943 				i = 0;
4944 				foreach(l, rowexpr->args)
4945 				{
4946 					Expr	   *e = (Expr *) lfirst(l);
4947 					ExprState  *estate;
4948 
4949 					if (!attrs[i]->attisdropped)
4950 					{
4951 						/*
4952 						 * Guard against ALTER COLUMN TYPE on rowtype since
4953 						 * the RowExpr was created.  XXX should we check
4954 						 * typmod too?	Not sure we can be sure it'll be the
4955 						 * same.
4956 						 */
4957 						if (exprType((Node *) e) != attrs[i]->atttypid)
4958 							ereport(ERROR,
4959 									(errcode(ERRCODE_DATATYPE_MISMATCH),
4960 									 errmsg("ROW() column has type %s instead of type %s",
4961 										format_type_be(exprType((Node *) e)),
4962 									   format_type_be(attrs[i]->atttypid))));
4963 					}
4964 					else
4965 					{
4966 						/*
4967 						 * Ignore original expression and insert a NULL. We
4968 						 * don't really care what type of NULL it is, so
4969 						 * always make an int4 NULL.
4970 						 */
4971 						e = (Expr *) makeNullConst(INT4OID, -1, InvalidOid);
4972 					}
4973 					estate = ExecInitExpr(e, parent);
4974 					outlist = lappend(outlist, estate);
4975 					i++;
4976 				}
4977 				rstate->args = outlist;
4978 				state = (ExprState *) rstate;
4979 			}
4980 			break;
4981 		case T_RowCompareExpr:
4982 			{
4983 				RowCompareExpr *rcexpr = (RowCompareExpr *) node;
4984 				RowCompareExprState *rstate = makeNode(RowCompareExprState);
4985 				int			nopers = list_length(rcexpr->opnos);
4986 				List	   *outlist;
4987 				ListCell   *l;
4988 				ListCell   *l2;
4989 				ListCell   *l3;
4990 				int			i;
4991 
4992 				rstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRowCompare;
4993 				Assert(list_length(rcexpr->largs) == nopers);
4994 				outlist = NIL;
4995 				foreach(l, rcexpr->largs)
4996 				{
4997 					Expr	   *e = (Expr *) lfirst(l);
4998 					ExprState  *estate;
4999 
5000 					estate = ExecInitExpr(e, parent);
5001 					outlist = lappend(outlist, estate);
5002 				}
5003 				rstate->largs = outlist;
5004 				Assert(list_length(rcexpr->rargs) == nopers);
5005 				outlist = NIL;
5006 				foreach(l, rcexpr->rargs)
5007 				{
5008 					Expr	   *e = (Expr *) lfirst(l);
5009 					ExprState  *estate;
5010 
5011 					estate = ExecInitExpr(e, parent);
5012 					outlist = lappend(outlist, estate);
5013 				}
5014 				rstate->rargs = outlist;
5015 				Assert(list_length(rcexpr->opfamilies) == nopers);
5016 				rstate->funcs = (FmgrInfo *) palloc(nopers * sizeof(FmgrInfo));
5017 				rstate->collations = (Oid *) palloc(nopers * sizeof(Oid));
5018 				i = 0;
5019 				forthree(l, rcexpr->opnos, l2, rcexpr->opfamilies, l3, rcexpr->inputcollids)
5020 				{
5021 					Oid			opno = lfirst_oid(l);
5022 					Oid			opfamily = lfirst_oid(l2);
5023 					Oid			inputcollid = lfirst_oid(l3);
5024 					int			strategy;
5025 					Oid			lefttype;
5026 					Oid			righttype;
5027 					Oid			proc;
5028 
5029 					get_op_opfamily_properties(opno, opfamily, false,
5030 											   &strategy,
5031 											   &lefttype,
5032 											   &righttype);
5033 					proc = get_opfamily_proc(opfamily,
5034 											 lefttype,
5035 											 righttype,
5036 											 BTORDER_PROC);
5037 
5038 					/*
5039 					 * If we enforced permissions checks on index support
5040 					 * functions, we'd need to make a check here.  But the
5041 					 * index support machinery doesn't do that, and neither
5042 					 * does this code.
5043 					 */
5044 					fmgr_info(proc, &(rstate->funcs[i]));
5045 					rstate->collations[i] = inputcollid;
5046 					i++;
5047 				}
5048 				state = (ExprState *) rstate;
5049 			}
5050 			break;
5051 		case T_CoalesceExpr:
5052 			{
5053 				CoalesceExpr *coalesceexpr = (CoalesceExpr *) node;
5054 				CoalesceExprState *cstate = makeNode(CoalesceExprState);
5055 				List	   *outlist = NIL;
5056 				ListCell   *l;
5057 
5058 				cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoalesce;
5059 				foreach(l, coalesceexpr->args)
5060 				{
5061 					Expr	   *e = (Expr *) lfirst(l);
5062 					ExprState  *estate;
5063 
5064 					estate = ExecInitExpr(e, parent);
5065 					outlist = lappend(outlist, estate);
5066 				}
5067 				cstate->args = outlist;
5068 				state = (ExprState *) cstate;
5069 			}
5070 			break;
5071 		case T_MinMaxExpr:
5072 			{
5073 				MinMaxExpr *minmaxexpr = (MinMaxExpr *) node;
5074 				MinMaxExprState *mstate = makeNode(MinMaxExprState);
5075 				List	   *outlist = NIL;
5076 				ListCell   *l;
5077 				TypeCacheEntry *typentry;
5078 
5079 				mstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalMinMax;
5080 				foreach(l, minmaxexpr->args)
5081 				{
5082 					Expr	   *e = (Expr *) lfirst(l);
5083 					ExprState  *estate;
5084 
5085 					estate = ExecInitExpr(e, parent);
5086 					outlist = lappend(outlist, estate);
5087 				}
5088 				mstate->args = outlist;
5089 				/* Look up the btree comparison function for the datatype */
5090 				typentry = lookup_type_cache(minmaxexpr->minmaxtype,
5091 											 TYPECACHE_CMP_PROC);
5092 				if (!OidIsValid(typentry->cmp_proc))
5093 					ereport(ERROR,
5094 							(errcode(ERRCODE_UNDEFINED_FUNCTION),
5095 							 errmsg("could not identify a comparison function for type %s",
5096 									format_type_be(minmaxexpr->minmaxtype))));
5097 
5098 				/*
5099 				 * If we enforced permissions checks on index support
5100 				 * functions, we'd need to make a check here.  But the index
5101 				 * support machinery doesn't do that, and neither does this
5102 				 * code.
5103 				 */
5104 				fmgr_info(typentry->cmp_proc, &(mstate->cfunc));
5105 				state = (ExprState *) mstate;
5106 			}
5107 			break;
5108 		case T_XmlExpr:
5109 			{
5110 				XmlExpr    *xexpr = (XmlExpr *) node;
5111 				XmlExprState *xstate = makeNode(XmlExprState);
5112 				List	   *outlist;
5113 				ListCell   *arg;
5114 
5115 				xstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalXml;
5116 				outlist = NIL;
5117 				foreach(arg, xexpr->named_args)
5118 				{
5119 					Expr	   *e = (Expr *) lfirst(arg);
5120 					ExprState  *estate;
5121 
5122 					estate = ExecInitExpr(e, parent);
5123 					outlist = lappend(outlist, estate);
5124 				}
5125 				xstate->named_args = outlist;
5126 
5127 				outlist = NIL;
5128 				foreach(arg, xexpr->args)
5129 				{
5130 					Expr	   *e = (Expr *) lfirst(arg);
5131 					ExprState  *estate;
5132 
5133 					estate = ExecInitExpr(e, parent);
5134 					outlist = lappend(outlist, estate);
5135 				}
5136 				xstate->args = outlist;
5137 
5138 				state = (ExprState *) xstate;
5139 			}
5140 			break;
5141 		case T_NullTest:
5142 			{
5143 				NullTest   *ntest = (NullTest *) node;
5144 				NullTestState *nstate = makeNode(NullTestState);
5145 
5146 				nstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNullTest;
5147 				nstate->arg = ExecInitExpr(ntest->arg, parent);
5148 				nstate->argdesc = NULL;
5149 				state = (ExprState *) nstate;
5150 			}
5151 			break;
5152 		case T_BooleanTest:
5153 			{
5154 				BooleanTest *btest = (BooleanTest *) node;
5155 				GenericExprState *gstate = makeNode(GenericExprState);
5156 
5157 				gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalBooleanTest;
5158 				gstate->arg = ExecInitExpr(btest->arg, parent);
5159 				state = (ExprState *) gstate;
5160 			}
5161 			break;
5162 		case T_CoerceToDomain:
5163 			{
5164 				CoerceToDomain *ctest = (CoerceToDomain *) node;
5165 				CoerceToDomainState *cstate = makeNode(CoerceToDomainState);
5166 
5167 				cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoerceToDomain;
5168 				cstate->arg = ExecInitExpr(ctest->arg, parent);
5169 				/* We spend an extra palloc to reduce header inclusions */
5170 				cstate->constraint_ref = (DomainConstraintRef *)
5171 					palloc(sizeof(DomainConstraintRef));
5172 				InitDomainConstraintRef(ctest->resulttype,
5173 										cstate->constraint_ref,
5174 										CurrentMemoryContext);
5175 				state = (ExprState *) cstate;
5176 			}
5177 			break;
5178 		case T_CurrentOfExpr:
5179 			state = (ExprState *) makeNode(ExprState);
5180 			state->evalfunc = ExecEvalCurrentOfExpr;
5181 			break;
5182 		case T_TargetEntry:
5183 			{
5184 				TargetEntry *tle = (TargetEntry *) node;
5185 				GenericExprState *gstate = makeNode(GenericExprState);
5186 
5187 				gstate->xprstate.evalfunc = NULL;		/* not used */
5188 				gstate->arg = ExecInitExpr(tle->expr, parent);
5189 				state = (ExprState *) gstate;
5190 			}
5191 			break;
5192 		case T_List:
5193 			{
5194 				List	   *outlist = NIL;
5195 				ListCell   *l;
5196 
5197 				foreach(l, (List *) node)
5198 				{
5199 					outlist = lappend(outlist,
5200 									  ExecInitExpr((Expr *) lfirst(l),
5201 												   parent));
5202 				}
5203 				/* Don't fall through to the "common" code below */
5204 				return (ExprState *) outlist;
5205 			}
5206 		default:
5207 			elog(ERROR, "unrecognized node type: %d",
5208 				 (int) nodeTag(node));
5209 			state = NULL;		/* keep compiler quiet */
5210 			break;
5211 	}
5212 
5213 	/* Common code for all state-node types */
5214 	state->expr = node;
5215 
5216 	return state;
5217 }
5218 
5219 /*
5220  * ExecPrepareExpr --- initialize for expression execution outside a normal
5221  * Plan tree context.
5222  *
5223  * This differs from ExecInitExpr in that we don't assume the caller is
5224  * already running in the EState's per-query context.  Also, we run the
5225  * passed expression tree through expression_planner() to prepare it for
5226  * execution.  (In ordinary Plan trees the regular planning process will have
5227  * made the appropriate transformations on expressions, but for standalone
5228  * expressions this won't have happened.)
5229  */
5230 ExprState *
ExecPrepareExpr(Expr * node,EState * estate)5231 ExecPrepareExpr(Expr *node, EState *estate)
5232 {
5233 	ExprState  *result;
5234 	MemoryContext oldcontext;
5235 
5236 	oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
5237 
5238 	node = expression_planner(node);
5239 
5240 	result = ExecInitExpr(node, NULL);
5241 
5242 	MemoryContextSwitchTo(oldcontext);
5243 
5244 	return result;
5245 }
5246 
5247 
5248 /* ----------------------------------------------------------------
5249  *					 ExecQual / ExecTargetList / ExecProject
5250  * ----------------------------------------------------------------
5251  */
5252 
5253 /* ----------------------------------------------------------------
5254  *		ExecQual
5255  *
5256  *		Evaluates a conjunctive boolean expression (qual list) and
5257  *		returns true iff none of the subexpressions are false.
5258  *		(We also return true if the list is empty.)
5259  *
5260  *	If some of the subexpressions yield NULL but none yield FALSE,
5261  *	then the result of the conjunction is NULL (ie, unknown)
5262  *	according to three-valued boolean logic.  In this case,
5263  *	we return the value specified by the "resultForNull" parameter.
5264  *
5265  *	Callers evaluating WHERE clauses should pass resultForNull=FALSE,
5266  *	since SQL specifies that tuples with null WHERE results do not
5267  *	get selected.  On the other hand, callers evaluating constraint
5268  *	conditions should pass resultForNull=TRUE, since SQL also specifies
5269  *	that NULL constraint conditions are not failures.
5270  *
5271  *	NOTE: it would not be correct to use this routine to evaluate an
5272  *	AND subclause of a boolean expression; for that purpose, a NULL
5273  *	result must be returned as NULL so that it can be properly treated
5274  *	in the next higher operator (cf. ExecEvalAnd and ExecEvalOr).
5275  *	This routine is only used in contexts where a complete expression
5276  *	is being evaluated and we know that NULL can be treated the same
5277  *	as one boolean result or the other.
5278  *
5279  * ----------------------------------------------------------------
5280  */
5281 bool
ExecQual(List * qual,ExprContext * econtext,bool resultForNull)5282 ExecQual(List *qual, ExprContext *econtext, bool resultForNull)
5283 {
5284 	bool		result;
5285 	MemoryContext oldContext;
5286 	ListCell   *l;
5287 
5288 	/*
5289 	 * debugging stuff
5290 	 */
5291 	EV_printf("ExecQual: qual is ");
5292 	EV_nodeDisplay(qual);
5293 	EV_printf("\n");
5294 
5295 	/*
5296 	 * Run in short-lived per-tuple context while computing expressions.
5297 	 */
5298 	oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
5299 
5300 	/*
5301 	 * Evaluate the qual conditions one at a time.  If we find a FALSE result,
5302 	 * we can stop evaluating and return FALSE --- the AND result must be
5303 	 * FALSE.  Also, if we find a NULL result when resultForNull is FALSE, we
5304 	 * can stop and return FALSE --- the AND result must be FALSE or NULL in
5305 	 * that case, and the caller doesn't care which.
5306 	 *
5307 	 * If we get to the end of the list, we can return TRUE.  This will happen
5308 	 * when the AND result is indeed TRUE, or when the AND result is NULL (one
5309 	 * or more NULL subresult, with all the rest TRUE) and the caller has
5310 	 * specified resultForNull = TRUE.
5311 	 */
5312 	result = true;
5313 
5314 	foreach(l, qual)
5315 	{
5316 		ExprState  *clause = (ExprState *) lfirst(l);
5317 		Datum		expr_value;
5318 		bool		isNull;
5319 
5320 		expr_value = ExecEvalExpr(clause, econtext, &isNull, NULL);
5321 
5322 		if (isNull)
5323 		{
5324 			if (resultForNull == false)
5325 			{
5326 				result = false; /* treat NULL as FALSE */
5327 				break;
5328 			}
5329 		}
5330 		else
5331 		{
5332 			if (!DatumGetBool(expr_value))
5333 			{
5334 				result = false; /* definitely FALSE */
5335 				break;
5336 			}
5337 		}
5338 	}
5339 
5340 	MemoryContextSwitchTo(oldContext);
5341 
5342 	return result;
5343 }
5344 
5345 /*
5346  * Number of items in a tlist (including any resjunk items!)
5347  */
5348 int
ExecTargetListLength(List * targetlist)5349 ExecTargetListLength(List *targetlist)
5350 {
5351 	/* This used to be more complex, but fjoins are dead */
5352 	return list_length(targetlist);
5353 }
5354 
5355 /*
5356  * Number of items in a tlist, not including any resjunk items
5357  */
5358 int
ExecCleanTargetListLength(List * targetlist)5359 ExecCleanTargetListLength(List *targetlist)
5360 {
5361 	int			len = 0;
5362 	ListCell   *tl;
5363 
5364 	foreach(tl, targetlist)
5365 	{
5366 		TargetEntry *curTle = (TargetEntry *) lfirst(tl);
5367 
5368 		Assert(IsA(curTle, TargetEntry));
5369 		if (!curTle->resjunk)
5370 			len++;
5371 	}
5372 	return len;
5373 }
5374 
5375 /*
5376  * ExecTargetList
5377  *		Evaluates a targetlist with respect to the given
5378  *		expression context.  Returns TRUE if we were able to create
5379  *		a result, FALSE if we have exhausted a set-valued expression.
5380  *
5381  * Results are stored into the passed values and isnull arrays.
5382  * The caller must provide an itemIsDone array that persists across calls.
5383  *
5384  * As with ExecEvalExpr, the caller should pass isDone = NULL if not
5385  * prepared to deal with sets of result tuples.  Otherwise, a return
5386  * of *isDone = ExprMultipleResult signifies a set element, and a return
5387  * of *isDone = ExprEndResult signifies end of the set of tuple.
5388  * We assume that *isDone has been initialized to ExprSingleResult by caller.
5389  *
5390  * Since fields of the result tuple might be multiply referenced in higher
5391  * plan nodes, we have to force any read/write expanded values to read-only
5392  * status.  It's a bit annoying to have to do that for every projected
5393  * expression; in the future, consider teaching the planner to detect
5394  * actually-multiply-referenced Vars and insert an expression node that
5395  * would do that only where really required.
5396  */
5397 static bool
ExecTargetList(List * targetlist,TupleDesc tupdesc,ExprContext * econtext,Datum * values,bool * isnull,ExprDoneCond * itemIsDone,ExprDoneCond * isDone)5398 ExecTargetList(List *targetlist,
5399 			   TupleDesc tupdesc,
5400 			   ExprContext *econtext,
5401 			   Datum *values,
5402 			   bool *isnull,
5403 			   ExprDoneCond *itemIsDone,
5404 			   ExprDoneCond *isDone)
5405 {
5406 	Form_pg_attribute *att = tupdesc->attrs;
5407 	MemoryContext oldContext;
5408 	ListCell   *tl;
5409 	bool		haveDoneSets;
5410 
5411 	/*
5412 	 * Run in short-lived per-tuple context while computing expressions.
5413 	 */
5414 	oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
5415 
5416 	/*
5417 	 * evaluate all the expressions in the target list
5418 	 */
5419 	haveDoneSets = false;		/* any exhausted set exprs in tlist? */
5420 
5421 	foreach(tl, targetlist)
5422 	{
5423 		GenericExprState *gstate = (GenericExprState *) lfirst(tl);
5424 		TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
5425 		AttrNumber	resind = tle->resno - 1;
5426 
5427 		values[resind] = ExecEvalExpr(gstate->arg,
5428 									  econtext,
5429 									  &isnull[resind],
5430 									  &itemIsDone[resind]);
5431 
5432 		values[resind] = MakeExpandedObjectReadOnly(values[resind],
5433 													isnull[resind],
5434 													att[resind]->attlen);
5435 
5436 		if (itemIsDone[resind] != ExprSingleResult)
5437 		{
5438 			/* We have a set-valued expression in the tlist */
5439 			if (isDone == NULL)
5440 				ereport(ERROR,
5441 						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5442 						 errmsg("set-valued function called in context that cannot accept a set")));
5443 			if (itemIsDone[resind] == ExprMultipleResult)
5444 			{
5445 				/* we have undone sets in the tlist, set flag */
5446 				*isDone = ExprMultipleResult;
5447 			}
5448 			else
5449 			{
5450 				/* we have done sets in the tlist, set flag for that */
5451 				haveDoneSets = true;
5452 			}
5453 		}
5454 	}
5455 
5456 	if (haveDoneSets)
5457 	{
5458 		/*
5459 		 * note: can't get here unless we verified isDone != NULL
5460 		 */
5461 		if (*isDone == ExprSingleResult)
5462 		{
5463 			/*
5464 			 * all sets are done, so report that tlist expansion is complete.
5465 			 */
5466 			*isDone = ExprEndResult;
5467 			MemoryContextSwitchTo(oldContext);
5468 			return false;
5469 		}
5470 		else
5471 		{
5472 			/*
5473 			 * We have some done and some undone sets.  Restart the done ones
5474 			 * so that we can deliver a tuple (if possible).
5475 			 */
5476 			foreach(tl, targetlist)
5477 			{
5478 				GenericExprState *gstate = (GenericExprState *) lfirst(tl);
5479 				TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
5480 				AttrNumber	resind = tle->resno - 1;
5481 
5482 				if (itemIsDone[resind] == ExprEndResult)
5483 				{
5484 					values[resind] = ExecEvalExpr(gstate->arg,
5485 												  econtext,
5486 												  &isnull[resind],
5487 												  &itemIsDone[resind]);
5488 
5489 					values[resind] = MakeExpandedObjectReadOnly(values[resind],
5490 															  isnull[resind],
5491 														att[resind]->attlen);
5492 
5493 					if (itemIsDone[resind] == ExprEndResult)
5494 					{
5495 						/*
5496 						 * Oh dear, this item is returning an empty set. Guess
5497 						 * we can't make a tuple after all.
5498 						 */
5499 						*isDone = ExprEndResult;
5500 						break;
5501 					}
5502 				}
5503 			}
5504 
5505 			/*
5506 			 * If we cannot make a tuple because some sets are empty, we still
5507 			 * have to cycle the nonempty sets to completion, else resources
5508 			 * will not be released from subplans etc.
5509 			 *
5510 			 * XXX is that still necessary?
5511 			 */
5512 			if (*isDone == ExprEndResult)
5513 			{
5514 				foreach(tl, targetlist)
5515 				{
5516 					GenericExprState *gstate = (GenericExprState *) lfirst(tl);
5517 					TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
5518 					AttrNumber	resind = tle->resno - 1;
5519 
5520 					while (itemIsDone[resind] == ExprMultipleResult)
5521 					{
5522 						values[resind] = ExecEvalExpr(gstate->arg,
5523 													  econtext,
5524 													  &isnull[resind],
5525 													  &itemIsDone[resind]);
5526 						/* no need for MakeExpandedObjectReadOnly */
5527 					}
5528 				}
5529 
5530 				MemoryContextSwitchTo(oldContext);
5531 				return false;
5532 			}
5533 		}
5534 	}
5535 
5536 	/* Report success */
5537 	MemoryContextSwitchTo(oldContext);
5538 
5539 	return true;
5540 }
5541 
5542 /*
5543  * ExecProject
5544  *
5545  *		projects a tuple based on projection info and stores
5546  *		it in the previously specified tuple table slot.
5547  *
5548  *		Note: the result is always a virtual tuple; therefore it
5549  *		may reference the contents of the exprContext's scan tuples
5550  *		and/or temporary results constructed in the exprContext.
5551  *		If the caller wishes the result to be valid longer than that
5552  *		data will be valid, he must call ExecMaterializeSlot on the
5553  *		result slot.
5554  */
5555 TupleTableSlot *
ExecProject(ProjectionInfo * projInfo,ExprDoneCond * isDone)5556 ExecProject(ProjectionInfo *projInfo, ExprDoneCond *isDone)
5557 {
5558 	TupleTableSlot *slot;
5559 	ExprContext *econtext;
5560 	int			numSimpleVars;
5561 
5562 	/*
5563 	 * sanity checks
5564 	 */
5565 	Assert(projInfo != NULL);
5566 
5567 	/*
5568 	 * get the projection info we want
5569 	 */
5570 	slot = projInfo->pi_slot;
5571 	econtext = projInfo->pi_exprContext;
5572 
5573 	/* Assume single result row until proven otherwise */
5574 	if (isDone)
5575 		*isDone = ExprSingleResult;
5576 
5577 	/*
5578 	 * Clear any former contents of the result slot.  This makes it safe for
5579 	 * us to use the slot's Datum/isnull arrays as workspace. (Also, we can
5580 	 * return the slot as-is if we decide no rows can be projected.)
5581 	 */
5582 	ExecClearTuple(slot);
5583 
5584 	/*
5585 	 * Force extraction of all input values that we'll need.  The
5586 	 * Var-extraction loops below depend on this, and we are also prefetching
5587 	 * all attributes that will be referenced in the generic expressions.
5588 	 */
5589 	if (projInfo->pi_lastInnerVar > 0)
5590 		slot_getsomeattrs(econtext->ecxt_innertuple,
5591 						  projInfo->pi_lastInnerVar);
5592 	if (projInfo->pi_lastOuterVar > 0)
5593 		slot_getsomeattrs(econtext->ecxt_outertuple,
5594 						  projInfo->pi_lastOuterVar);
5595 	if (projInfo->pi_lastScanVar > 0)
5596 		slot_getsomeattrs(econtext->ecxt_scantuple,
5597 						  projInfo->pi_lastScanVar);
5598 
5599 	/*
5600 	 * Assign simple Vars to result by direct extraction of fields from source
5601 	 * slots ... a mite ugly, but fast ...
5602 	 */
5603 	numSimpleVars = projInfo->pi_numSimpleVars;
5604 	if (numSimpleVars > 0)
5605 	{
5606 		Datum	   *values = slot->tts_values;
5607 		bool	   *isnull = slot->tts_isnull;
5608 		int		   *varSlotOffsets = projInfo->pi_varSlotOffsets;
5609 		int		   *varNumbers = projInfo->pi_varNumbers;
5610 		int			i;
5611 
5612 		if (projInfo->pi_directMap)
5613 		{
5614 			/* especially simple case where vars go to output in order */
5615 			for (i = 0; i < numSimpleVars; i++)
5616 			{
5617 				char	   *slotptr = ((char *) econtext) + varSlotOffsets[i];
5618 				TupleTableSlot *varSlot = *((TupleTableSlot **) slotptr);
5619 				int			varNumber = varNumbers[i] - 1;
5620 
5621 				values[i] = varSlot->tts_values[varNumber];
5622 				isnull[i] = varSlot->tts_isnull[varNumber];
5623 			}
5624 		}
5625 		else
5626 		{
5627 			/* we have to pay attention to varOutputCols[] */
5628 			int		   *varOutputCols = projInfo->pi_varOutputCols;
5629 
5630 			for (i = 0; i < numSimpleVars; i++)
5631 			{
5632 				char	   *slotptr = ((char *) econtext) + varSlotOffsets[i];
5633 				TupleTableSlot *varSlot = *((TupleTableSlot **) slotptr);
5634 				int			varNumber = varNumbers[i] - 1;
5635 				int			varOutputCol = varOutputCols[i] - 1;
5636 
5637 				values[varOutputCol] = varSlot->tts_values[varNumber];
5638 				isnull[varOutputCol] = varSlot->tts_isnull[varNumber];
5639 			}
5640 		}
5641 	}
5642 
5643 	/*
5644 	 * If there are any generic expressions, evaluate them.  It's possible
5645 	 * that there are set-returning functions in such expressions; if so and
5646 	 * we have reached the end of the set, we return the result slot, which we
5647 	 * already marked empty.
5648 	 */
5649 	if (projInfo->pi_targetlist)
5650 	{
5651 		if (!ExecTargetList(projInfo->pi_targetlist,
5652 							slot->tts_tupleDescriptor,
5653 							econtext,
5654 							slot->tts_values,
5655 							slot->tts_isnull,
5656 							projInfo->pi_itemIsDone,
5657 							isDone))
5658 			return slot;		/* no more result rows, return empty slot */
5659 	}
5660 
5661 	/*
5662 	 * Successfully formed a result row.  Mark the result slot as containing a
5663 	 * valid virtual tuple.
5664 	 */
5665 	return ExecStoreVirtualTuple(slot);
5666 }
5667