1 /*-------------------------------------------------------------------------
2  *
3  * execExpr.c
4  *	  Expression evaluation infrastructure.
5  *
6  *	During executor startup, we compile each expression tree (which has
7  *	previously been processed by the parser and planner) into an ExprState,
8  *	using ExecInitExpr() et al.  This converts the tree into a flat array
9  *	of ExprEvalSteps, which may be thought of as instructions in a program.
10  *	At runtime, we'll execute steps, starting with the first, until we reach
11  *	an EEOP_DONE opcode.
12  *
13  *	This file contains the "compilation" logic.  It is independent of the
14  *	specific execution technology we use (switch statement, computed goto,
15  *	JIT compilation, etc).
16  *
17  *	See src/backend/executor/README for some background, specifically the
18  *	"Expression Trees and ExprState nodes", "Expression Initialization",
19  *	and "Expression Evaluation" sections.
20  *
21  *
22  * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
23  * Portions Copyright (c) 1994, Regents of the University of California
24  *
25  *
26  * IDENTIFICATION
27  *	  src/backend/executor/execExpr.c
28  *
29  *-------------------------------------------------------------------------
30  */
31 #include "postgres.h"
32 
33 #include "access/nbtree.h"
34 #include "catalog/objectaccess.h"
35 #include "catalog/pg_type.h"
36 #include "executor/execExpr.h"
37 #include "executor/nodeSubplan.h"
38 #include "funcapi.h"
39 #include "jit/jit.h"
40 #include "miscadmin.h"
41 #include "nodes/makefuncs.h"
42 #include "nodes/nodeFuncs.h"
43 #include "optimizer/clauses.h"
44 #include "optimizer/planner.h"
45 #include "pgstat.h"
46 #include "utils/builtins.h"
47 #include "utils/datum.h"
48 #include "utils/lsyscache.h"
49 #include "utils/typcache.h"
50 
51 
52 typedef struct LastAttnumInfo
53 {
54 	AttrNumber	last_inner;
55 	AttrNumber	last_outer;
56 	AttrNumber	last_scan;
57 } LastAttnumInfo;
58 
59 static void ExecReadyExpr(ExprState *state);
60 static void ExecInitExprRec(Expr *node, ExprState *state,
61 				Datum *resv, bool *resnull);
62 static void ExecInitFunc(ExprEvalStep *scratch, Expr *node, List *args,
63 			 Oid funcid, Oid inputcollid,
64 			 ExprState *state);
65 static void ExecInitExprSlots(ExprState *state, Node *node);
66 static void ExecPushExprSlots(ExprState *state, LastAttnumInfo *info);
67 static bool get_last_attnums_walker(Node *node, LastAttnumInfo *info);
68 static void ExecInitWholeRowVar(ExprEvalStep *scratch, Var *variable,
69 					ExprState *state);
70 static void ExecInitArrayRef(ExprEvalStep *scratch, ArrayRef *aref,
71 				 ExprState *state,
72 				 Datum *resv, bool *resnull);
73 static bool isAssignmentIndirectionExpr(Expr *expr);
74 static void ExecInitCoerceToDomain(ExprEvalStep *scratch, CoerceToDomain *ctest,
75 					   ExprState *state,
76 					   Datum *resv, bool *resnull);
77 static void ExecBuildAggTransCall(ExprState *state, AggState *aggstate,
78 					  ExprEvalStep *scratch,
79 					  FunctionCallInfo fcinfo, AggStatePerTrans pertrans,
80 					  int transno, int setno, int setoff, bool ishash);
81 
82 
83 /*
84  * ExecInitExpr: prepare an expression tree for execution
85  *
86  * This function builds and returns an ExprState implementing the given
87  * Expr node tree.  The return ExprState can then be handed to ExecEvalExpr
88  * for execution.  Because the Expr tree itself is read-only as far as
89  * ExecInitExpr and ExecEvalExpr are concerned, several different executions
90  * of the same plan tree can occur concurrently.  (But note that an ExprState
91  * does mutate at runtime, so it can't be re-used concurrently.)
92  *
93  * This must be called in a memory context that will last as long as repeated
94  * executions of the expression are needed.  Typically the context will be
95  * the same as the per-query context of the associated ExprContext.
96  *
97  * Any Aggref, WindowFunc, or SubPlan nodes found in the tree are added to
98  * the lists of such nodes held by the parent PlanState (or more accurately,
99  * the AggrefExprState etc. nodes created for them are added).
100  *
101  * Note: there is no ExecEndExpr function; we assume that any resource
102  * cleanup needed will be handled by just releasing the memory context
103  * in which the state tree is built.  Functions that require additional
104  * cleanup work can register a shutdown callback in the ExprContext.
105  *
106  *	'node' is the root of the expression tree to compile.
107  *	'parent' is the PlanState node that owns the expression.
108  *
109  * 'parent' may be NULL if we are preparing an expression that is not
110  * associated with a plan tree.  (If so, it can't have aggs or subplans.)
111  * Such cases should usually come through ExecPrepareExpr, not directly here.
112  *
113  * Also, if 'node' is NULL, we just return NULL.  This is convenient for some
114  * callers that may or may not have an expression that needs to be compiled.
115  * Note that a NULL ExprState pointer *cannot* be handed to ExecEvalExpr,
116  * although ExecQual and ExecCheck will accept one (and treat it as "true").
117  */
118 ExprState *
ExecInitExpr(Expr * node,PlanState * parent)119 ExecInitExpr(Expr *node, PlanState *parent)
120 {
121 	ExprState  *state;
122 	ExprEvalStep scratch = {0};
123 
124 	/* Special case: NULL expression produces a NULL ExprState pointer */
125 	if (node == NULL)
126 		return NULL;
127 
128 	/* Initialize ExprState with empty step list */
129 	state = makeNode(ExprState);
130 	state->expr = node;
131 	state->parent = parent;
132 	state->ext_params = NULL;
133 
134 	/* Insert EEOP_*_FETCHSOME steps as needed */
135 	ExecInitExprSlots(state, (Node *) node);
136 
137 	/* Compile the expression proper */
138 	ExecInitExprRec(node, state, &state->resvalue, &state->resnull);
139 
140 	/* Finally, append a DONE step */
141 	scratch.opcode = EEOP_DONE;
142 	ExprEvalPushStep(state, &scratch);
143 
144 	ExecReadyExpr(state);
145 
146 	return state;
147 }
148 
149 /*
150  * ExecInitExprWithParams: prepare a standalone expression tree for execution
151  *
152  * This is the same as ExecInitExpr, except that there is no parent PlanState,
153  * and instead we may have a ParamListInfo describing PARAM_EXTERN Params.
154  */
155 ExprState *
ExecInitExprWithParams(Expr * node,ParamListInfo ext_params)156 ExecInitExprWithParams(Expr *node, ParamListInfo ext_params)
157 {
158 	ExprState  *state;
159 	ExprEvalStep scratch = {0};
160 
161 	/* Special case: NULL expression produces a NULL ExprState pointer */
162 	if (node == NULL)
163 		return NULL;
164 
165 	/* Initialize ExprState with empty step list */
166 	state = makeNode(ExprState);
167 	state->expr = node;
168 	state->parent = NULL;
169 	state->ext_params = ext_params;
170 
171 	/* Insert EEOP_*_FETCHSOME steps as needed */
172 	ExecInitExprSlots(state, (Node *) node);
173 
174 	/* Compile the expression proper */
175 	ExecInitExprRec(node, state, &state->resvalue, &state->resnull);
176 
177 	/* Finally, append a DONE step */
178 	scratch.opcode = EEOP_DONE;
179 	ExprEvalPushStep(state, &scratch);
180 
181 	ExecReadyExpr(state);
182 
183 	return state;
184 }
185 
186 /*
187  * ExecInitQual: prepare a qual for execution by ExecQual
188  *
189  * Prepares for the evaluation of a conjunctive boolean expression (qual list
190  * with implicit AND semantics) that returns true if none of the
191  * subexpressions are false.
192  *
193  * We must return true if the list is empty.  Since that's a very common case,
194  * we optimize it a bit further by translating to a NULL ExprState pointer
195  * rather than setting up an ExprState that computes constant TRUE.  (Some
196  * especially hot-spot callers of ExecQual detect this and avoid calling
197  * ExecQual at all.)
198  *
199  * If any of the subexpressions yield NULL, then the result of the conjunction
200  * is false.  This makes ExecQual primarily useful for evaluating WHERE
201  * clauses, since SQL specifies that tuples with null WHERE results do not
202  * get selected.
203  */
204 ExprState *
ExecInitQual(List * qual,PlanState * parent)205 ExecInitQual(List *qual, PlanState *parent)
206 {
207 	ExprState  *state;
208 	ExprEvalStep scratch = {0};
209 	List	   *adjust_jumps = NIL;
210 	ListCell   *lc;
211 
212 	/* short-circuit (here and in ExecQual) for empty restriction list */
213 	if (qual == NIL)
214 		return NULL;
215 
216 	Assert(IsA(qual, List));
217 
218 	state = makeNode(ExprState);
219 	state->expr = (Expr *) qual;
220 	state->parent = parent;
221 	state->ext_params = NULL;
222 
223 	/* mark expression as to be used with ExecQual() */
224 	state->flags = EEO_FLAG_IS_QUAL;
225 
226 	/* Insert EEOP_*_FETCHSOME steps as needed */
227 	ExecInitExprSlots(state, (Node *) qual);
228 
229 	/*
230 	 * ExecQual() needs to return false for an expression returning NULL. That
231 	 * allows us to short-circuit the evaluation the first time a NULL is
232 	 * encountered.  As qual evaluation is a hot-path this warrants using a
233 	 * special opcode for qual evaluation that's simpler than BOOL_AND (which
234 	 * has more complex NULL handling).
235 	 */
236 	scratch.opcode = EEOP_QUAL;
237 
238 	/*
239 	 * We can use ExprState's resvalue/resnull as target for each qual expr.
240 	 */
241 	scratch.resvalue = &state->resvalue;
242 	scratch.resnull = &state->resnull;
243 
244 	foreach(lc, qual)
245 	{
246 		Expr	   *node = (Expr *) lfirst(lc);
247 
248 		/* first evaluate expression */
249 		ExecInitExprRec(node, state, &state->resvalue, &state->resnull);
250 
251 		/* then emit EEOP_QUAL to detect if it's false (or null) */
252 		scratch.d.qualexpr.jumpdone = -1;
253 		ExprEvalPushStep(state, &scratch);
254 		adjust_jumps = lappend_int(adjust_jumps,
255 								   state->steps_len - 1);
256 	}
257 
258 	/* adjust jump targets */
259 	foreach(lc, adjust_jumps)
260 	{
261 		ExprEvalStep *as = &state->steps[lfirst_int(lc)];
262 
263 		Assert(as->opcode == EEOP_QUAL);
264 		Assert(as->d.qualexpr.jumpdone == -1);
265 		as->d.qualexpr.jumpdone = state->steps_len;
266 	}
267 
268 	/*
269 	 * At the end, we don't need to do anything more.  The last qual expr must
270 	 * have yielded TRUE, and since its result is stored in the desired output
271 	 * location, we're done.
272 	 */
273 	scratch.opcode = EEOP_DONE;
274 	ExprEvalPushStep(state, &scratch);
275 
276 	ExecReadyExpr(state);
277 
278 	return state;
279 }
280 
281 /*
282  * ExecInitCheck: prepare a check constraint for execution by ExecCheck
283  *
284  * This is much like ExecInitQual/ExecQual, except that a null result from
285  * the conjunction is treated as TRUE.  This behavior is appropriate for
286  * evaluating CHECK constraints, since SQL specifies that NULL constraint
287  * conditions are not failures.
288  *
289  * Note that like ExecInitQual, this expects input in implicit-AND format.
290  * Users of ExecCheck that have expressions in normal explicit-AND format
291  * can just apply ExecInitExpr to produce suitable input for ExecCheck.
292  */
293 ExprState *
ExecInitCheck(List * qual,PlanState * parent)294 ExecInitCheck(List *qual, PlanState *parent)
295 {
296 	/* short-circuit (here and in ExecCheck) for empty restriction list */
297 	if (qual == NIL)
298 		return NULL;
299 
300 	Assert(IsA(qual, List));
301 
302 	/*
303 	 * Just convert the implicit-AND list to an explicit AND (if there's more
304 	 * than one entry), and compile normally.  Unlike ExecQual, we can't
305 	 * short-circuit on NULL results, so the regular AND behavior is needed.
306 	 */
307 	return ExecInitExpr(make_ands_explicit(qual), parent);
308 }
309 
310 /*
311  * Call ExecInitExpr() on a list of expressions, return a list of ExprStates.
312  */
313 List *
ExecInitExprList(List * nodes,PlanState * parent)314 ExecInitExprList(List *nodes, PlanState *parent)
315 {
316 	List	   *result = NIL;
317 	ListCell   *lc;
318 
319 	foreach(lc, nodes)
320 	{
321 		Expr	   *e = lfirst(lc);
322 
323 		result = lappend(result, ExecInitExpr(e, parent));
324 	}
325 
326 	return result;
327 }
328 
329 /*
330  *		ExecBuildProjectionInfo
331  *
332  * Build a ProjectionInfo node for evaluating the given tlist in the given
333  * econtext, and storing the result into the tuple slot.  (Caller must have
334  * ensured that tuple slot has a descriptor matching the tlist!)
335  *
336  * inputDesc can be NULL, but if it is not, we check to see whether simple
337  * Vars in the tlist match the descriptor.  It is important to provide
338  * inputDesc for relation-scan plan nodes, as a cross check that the relation
339  * hasn't been changed since the plan was made.  At higher levels of a plan,
340  * there is no need to recheck.
341  *
342  * This is implemented by internally building an ExprState that performs the
343  * whole projection in one go.
344  *
345  * Caution: before PG v10, the targetList was a list of ExprStates; now it
346  * should be the planner-created targetlist, since we do the compilation here.
347  */
348 ProjectionInfo *
ExecBuildProjectionInfo(List * targetList,ExprContext * econtext,TupleTableSlot * slot,PlanState * parent,TupleDesc inputDesc)349 ExecBuildProjectionInfo(List *targetList,
350 						ExprContext *econtext,
351 						TupleTableSlot *slot,
352 						PlanState *parent,
353 						TupleDesc inputDesc)
354 {
355 	return ExecBuildProjectionInfoExt(targetList,
356 									  econtext,
357 									  slot,
358 									  true,
359 									  parent,
360 									  inputDesc);
361 }
362 
363 /*
364  *		ExecBuildProjectionInfoExt
365  *
366  * As above, with one additional option.
367  *
368  * If assignJunkEntries is true (the usual case), resjunk entries in the tlist
369  * are not handled specially: they are evaluated and assigned to the proper
370  * column of the result slot.  If assignJunkEntries is false, resjunk entries
371  * are evaluated, but their result is discarded without assignment.
372  */
373 ProjectionInfo *
ExecBuildProjectionInfoExt(List * targetList,ExprContext * econtext,TupleTableSlot * slot,bool assignJunkEntries,PlanState * parent,TupleDesc inputDesc)374 ExecBuildProjectionInfoExt(List *targetList,
375 						   ExprContext *econtext,
376 						   TupleTableSlot *slot,
377 						   bool assignJunkEntries,
378 						   PlanState *parent,
379 						   TupleDesc inputDesc)
380 {
381 	ProjectionInfo *projInfo = makeNode(ProjectionInfo);
382 	ExprState  *state;
383 	ExprEvalStep scratch = {0};
384 	ListCell   *lc;
385 
386 	projInfo->pi_exprContext = econtext;
387 	/* We embed ExprState into ProjectionInfo instead of doing extra palloc */
388 	projInfo->pi_state.tag.type = T_ExprState;
389 	state = &projInfo->pi_state;
390 	state->expr = (Expr *) targetList;
391 	state->parent = parent;
392 	state->ext_params = NULL;
393 
394 	state->resultslot = slot;
395 
396 	/* Insert EEOP_*_FETCHSOME steps as needed */
397 	ExecInitExprSlots(state, (Node *) targetList);
398 
399 	/* Now compile each tlist column */
400 	foreach(lc, targetList)
401 	{
402 		TargetEntry *tle = lfirst_node(TargetEntry, lc);
403 		Var		   *variable = NULL;
404 		AttrNumber	attnum = 0;
405 		bool		isSafeVar = false;
406 
407 		/*
408 		 * If tlist expression is a safe non-system Var, use the fast-path
409 		 * ASSIGN_*_VAR opcodes.  "Safe" means that we don't need to apply
410 		 * CheckVarSlotCompatibility() during plan startup.  If a source slot
411 		 * was provided, we make the equivalent tests here; if a slot was not
412 		 * provided, we assume that no check is needed because we're dealing
413 		 * with a non-relation-scan-level expression.
414 		 */
415 		if (tle->expr != NULL &&
416 			IsA(tle->expr, Var) &&
417 			((Var *) tle->expr)->varattno > 0 &&
418 			(assignJunkEntries || !tle->resjunk))
419 		{
420 			/* Non-system Var, but how safe is it? */
421 			variable = (Var *) tle->expr;
422 			attnum = variable->varattno;
423 
424 			if (inputDesc == NULL)
425 				isSafeVar = true;	/* can't check, just assume OK */
426 			else if (attnum <= inputDesc->natts)
427 			{
428 				Form_pg_attribute attr = TupleDescAttr(inputDesc, attnum - 1);
429 
430 				/*
431 				 * If user attribute is dropped or has a type mismatch, don't
432 				 * use ASSIGN_*_VAR.  Instead let the normal expression
433 				 * machinery handle it (which'll possibly error out).
434 				 */
435 				if (!attr->attisdropped && variable->vartype == attr->atttypid)
436 				{
437 					isSafeVar = true;
438 				}
439 			}
440 		}
441 
442 		if (isSafeVar)
443 		{
444 			/* Fast-path: just generate an EEOP_ASSIGN_*_VAR step */
445 			switch (variable->varno)
446 			{
447 				case INNER_VAR:
448 					/* get the tuple from the inner node */
449 					scratch.opcode = EEOP_ASSIGN_INNER_VAR;
450 					break;
451 
452 				case OUTER_VAR:
453 					/* get the tuple from the outer node */
454 					scratch.opcode = EEOP_ASSIGN_OUTER_VAR;
455 					break;
456 
457 					/* INDEX_VAR is handled by default case */
458 
459 				default:
460 					/* get the tuple from the relation being scanned */
461 					scratch.opcode = EEOP_ASSIGN_SCAN_VAR;
462 					break;
463 			}
464 
465 			scratch.d.assign_var.attnum = attnum - 1;
466 			scratch.d.assign_var.resultnum = tle->resno - 1;
467 			ExprEvalPushStep(state, &scratch);
468 		}
469 		else
470 		{
471 			/*
472 			 * Otherwise, compile the column expression normally.
473 			 *
474 			 * We can't tell the expression to evaluate directly into the
475 			 * result slot, as the result slot (and the exprstate for that
476 			 * matter) can change between executions.  We instead evaluate
477 			 * into the ExprState's resvalue/resnull and then move.
478 			 */
479 			ExecInitExprRec(tle->expr, state,
480 							&state->resvalue, &state->resnull);
481 
482 			/* This makes it easy to discard resjunk results when told to. */
483 			if (!assignJunkEntries && tle->resjunk)
484 				continue;
485 
486 			/*
487 			 * Column might be referenced multiple times in upper nodes, so
488 			 * force value to R/O - but only if it could be an expanded datum.
489 			 */
490 			if (get_typlen(exprType((Node *) tle->expr)) == -1)
491 				scratch.opcode = EEOP_ASSIGN_TMP_MAKE_RO;
492 			else
493 				scratch.opcode = EEOP_ASSIGN_TMP;
494 			scratch.d.assign_tmp.resultnum = tle->resno - 1;
495 			ExprEvalPushStep(state, &scratch);
496 		}
497 	}
498 
499 	scratch.opcode = EEOP_DONE;
500 	ExprEvalPushStep(state, &scratch);
501 
502 	ExecReadyExpr(state);
503 
504 	return projInfo;
505 }
506 
507 /*
508  * ExecPrepareExpr --- initialize for expression execution outside a normal
509  * Plan tree context.
510  *
511  * This differs from ExecInitExpr in that we don't assume the caller is
512  * already running in the EState's per-query context.  Also, we run the
513  * passed expression tree through expression_planner() to prepare it for
514  * execution.  (In ordinary Plan trees the regular planning process will have
515  * made the appropriate transformations on expressions, but for standalone
516  * expressions this won't have happened.)
517  */
518 ExprState *
ExecPrepareExpr(Expr * node,EState * estate)519 ExecPrepareExpr(Expr *node, EState *estate)
520 {
521 	ExprState  *result;
522 	MemoryContext oldcontext;
523 
524 	oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
525 
526 	node = expression_planner(node);
527 
528 	result = ExecInitExpr(node, NULL);
529 
530 	MemoryContextSwitchTo(oldcontext);
531 
532 	return result;
533 }
534 
535 /*
536  * ExecPrepareQual --- initialize for qual execution outside a normal
537  * Plan tree context.
538  *
539  * This differs from ExecInitQual in that we don't assume the caller is
540  * already running in the EState's per-query context.  Also, we run the
541  * passed expression tree through expression_planner() to prepare it for
542  * execution.  (In ordinary Plan trees the regular planning process will have
543  * made the appropriate transformations on expressions, but for standalone
544  * expressions this won't have happened.)
545  */
546 ExprState *
ExecPrepareQual(List * qual,EState * estate)547 ExecPrepareQual(List *qual, EState *estate)
548 {
549 	ExprState  *result;
550 	MemoryContext oldcontext;
551 
552 	oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
553 
554 	qual = (List *) expression_planner((Expr *) qual);
555 
556 	result = ExecInitQual(qual, NULL);
557 
558 	MemoryContextSwitchTo(oldcontext);
559 
560 	return result;
561 }
562 
563 /*
564  * ExecPrepareCheck -- initialize check constraint for execution outside a
565  * normal Plan tree context.
566  *
567  * See ExecPrepareExpr() and ExecInitCheck() for details.
568  */
569 ExprState *
ExecPrepareCheck(List * qual,EState * estate)570 ExecPrepareCheck(List *qual, EState *estate)
571 {
572 	ExprState  *result;
573 	MemoryContext oldcontext;
574 
575 	oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
576 
577 	qual = (List *) expression_planner((Expr *) qual);
578 
579 	result = ExecInitCheck(qual, NULL);
580 
581 	MemoryContextSwitchTo(oldcontext);
582 
583 	return result;
584 }
585 
586 /*
587  * Call ExecPrepareExpr() on each member of a list of Exprs, and return
588  * a list of ExprStates.
589  *
590  * See ExecPrepareExpr() for details.
591  */
592 List *
ExecPrepareExprList(List * nodes,EState * estate)593 ExecPrepareExprList(List *nodes, EState *estate)
594 {
595 	List	   *result = NIL;
596 	MemoryContext oldcontext;
597 	ListCell   *lc;
598 
599 	/* Ensure that the list cell nodes are in the right context too */
600 	oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
601 
602 	foreach(lc, nodes)
603 	{
604 		Expr	   *e = (Expr *) lfirst(lc);
605 
606 		result = lappend(result, ExecPrepareExpr(e, estate));
607 	}
608 
609 	MemoryContextSwitchTo(oldcontext);
610 
611 	return result;
612 }
613 
614 /*
615  * ExecCheck - evaluate a check constraint
616  *
617  * For check constraints, a null result is taken as TRUE, ie the constraint
618  * passes.
619  *
620  * The check constraint may have been prepared with ExecInitCheck
621  * (possibly via ExecPrepareCheck) if the caller had it in implicit-AND
622  * format, but a regular boolean expression prepared with ExecInitExpr or
623  * ExecPrepareExpr works too.
624  */
625 bool
ExecCheck(ExprState * state,ExprContext * econtext)626 ExecCheck(ExprState *state, ExprContext *econtext)
627 {
628 	Datum		ret;
629 	bool		isnull;
630 
631 	/* short-circuit (here and in ExecInitCheck) for empty restriction list */
632 	if (state == NULL)
633 		return true;
634 
635 	/* verify that expression was not compiled using ExecInitQual */
636 	Assert(!(state->flags & EEO_FLAG_IS_QUAL));
637 
638 	ret = ExecEvalExprSwitchContext(state, econtext, &isnull);
639 
640 	if (isnull)
641 		return true;
642 
643 	return DatumGetBool(ret);
644 }
645 
646 /*
647  * Prepare a compiled expression for execution.  This has to be called for
648  * every ExprState before it can be executed.
649  *
650  * NB: While this currently only calls ExecReadyInterpretedExpr(),
651  * this will likely get extended to further expression evaluation methods.
652  * Therefore this should be used instead of directly calling
653  * ExecReadyInterpretedExpr().
654  */
655 static void
ExecReadyExpr(ExprState * state)656 ExecReadyExpr(ExprState *state)
657 {
658 	if (jit_compile_expr(state))
659 		return;
660 
661 	ExecReadyInterpretedExpr(state);
662 }
663 
664 /*
665  * Append the steps necessary for the evaluation of node to ExprState->steps,
666  * possibly recursing into sub-expressions of node.
667  *
668  * node - expression to evaluate
669  * state - ExprState to whose ->steps to append the necessary operations
670  * resv / resnull - where to store the result of the node into
671  */
672 static void
ExecInitExprRec(Expr * node,ExprState * state,Datum * resv,bool * resnull)673 ExecInitExprRec(Expr *node, ExprState *state,
674 				Datum *resv, bool *resnull)
675 {
676 	ExprEvalStep scratch = {0};
677 
678 	/* Guard against stack overflow due to overly complex expressions */
679 	check_stack_depth();
680 
681 	/* Step's output location is always what the caller gave us */
682 	Assert(resv != NULL && resnull != NULL);
683 	scratch.resvalue = resv;
684 	scratch.resnull = resnull;
685 
686 	/* cases should be ordered as they are in enum NodeTag */
687 	switch (nodeTag(node))
688 	{
689 		case T_Var:
690 			{
691 				Var		   *variable = (Var *) node;
692 
693 				if (variable->varattno == InvalidAttrNumber)
694 				{
695 					/* whole-row Var */
696 					ExecInitWholeRowVar(&scratch, variable, state);
697 				}
698 				else if (variable->varattno <= 0)
699 				{
700 					/* system column */
701 					scratch.d.var.attnum = variable->varattno;
702 					scratch.d.var.vartype = variable->vartype;
703 					switch (variable->varno)
704 					{
705 						case INNER_VAR:
706 							scratch.opcode = EEOP_INNER_SYSVAR;
707 							break;
708 						case OUTER_VAR:
709 							scratch.opcode = EEOP_OUTER_SYSVAR;
710 							break;
711 
712 							/* INDEX_VAR is handled by default case */
713 
714 						default:
715 							scratch.opcode = EEOP_SCAN_SYSVAR;
716 							break;
717 					}
718 				}
719 				else
720 				{
721 					/* regular user column */
722 					scratch.d.var.attnum = variable->varattno - 1;
723 					scratch.d.var.vartype = variable->vartype;
724 					switch (variable->varno)
725 					{
726 						case INNER_VAR:
727 							scratch.opcode = EEOP_INNER_VAR;
728 							break;
729 						case OUTER_VAR:
730 							scratch.opcode = EEOP_OUTER_VAR;
731 							break;
732 
733 							/* INDEX_VAR is handled by default case */
734 
735 						default:
736 							scratch.opcode = EEOP_SCAN_VAR;
737 							break;
738 					}
739 				}
740 
741 				ExprEvalPushStep(state, &scratch);
742 				break;
743 			}
744 
745 		case T_Const:
746 			{
747 				Const	   *con = (Const *) node;
748 
749 				scratch.opcode = EEOP_CONST;
750 				scratch.d.constval.value = con->constvalue;
751 				scratch.d.constval.isnull = con->constisnull;
752 
753 				ExprEvalPushStep(state, &scratch);
754 				break;
755 			}
756 
757 		case T_Param:
758 			{
759 				Param	   *param = (Param *) node;
760 				ParamListInfo params;
761 
762 				switch (param->paramkind)
763 				{
764 					case PARAM_EXEC:
765 						scratch.opcode = EEOP_PARAM_EXEC;
766 						scratch.d.param.paramid = param->paramid;
767 						scratch.d.param.paramtype = param->paramtype;
768 						ExprEvalPushStep(state, &scratch);
769 						break;
770 					case PARAM_EXTERN:
771 
772 						/*
773 						 * If we have a relevant ParamCompileHook, use it;
774 						 * otherwise compile a standard EEOP_PARAM_EXTERN
775 						 * step.  ext_params, if supplied, takes precedence
776 						 * over info from the parent node's EState (if any).
777 						 */
778 						if (state->ext_params)
779 							params = state->ext_params;
780 						else if (state->parent &&
781 								 state->parent->state)
782 							params = state->parent->state->es_param_list_info;
783 						else
784 							params = NULL;
785 						if (params && params->paramCompile)
786 						{
787 							params->paramCompile(params, param, state,
788 												 resv, resnull);
789 						}
790 						else
791 						{
792 							scratch.opcode = EEOP_PARAM_EXTERN;
793 							scratch.d.param.paramid = param->paramid;
794 							scratch.d.param.paramtype = param->paramtype;
795 							ExprEvalPushStep(state, &scratch);
796 						}
797 						break;
798 					default:
799 						elog(ERROR, "unrecognized paramkind: %d",
800 							 (int) param->paramkind);
801 						break;
802 				}
803 				break;
804 			}
805 
806 		case T_Aggref:
807 			{
808 				Aggref	   *aggref = (Aggref *) node;
809 				AggrefExprState *astate = makeNode(AggrefExprState);
810 
811 				scratch.opcode = EEOP_AGGREF;
812 				scratch.d.aggref.astate = astate;
813 				astate->aggref = aggref;
814 
815 				if (state->parent && IsA(state->parent, AggState))
816 				{
817 					AggState   *aggstate = (AggState *) state->parent;
818 
819 					aggstate->aggs = lcons(astate, aggstate->aggs);
820 					aggstate->numaggs++;
821 				}
822 				else
823 				{
824 					/* planner messed up */
825 					elog(ERROR, "Aggref found in non-Agg plan node");
826 				}
827 
828 				ExprEvalPushStep(state, &scratch);
829 				break;
830 			}
831 
832 		case T_GroupingFunc:
833 			{
834 				GroupingFunc *grp_node = (GroupingFunc *) node;
835 				Agg		   *agg;
836 
837 				if (!state->parent || !IsA(state->parent, AggState) ||
838 					!IsA(state->parent->plan, Agg))
839 					elog(ERROR, "GroupingFunc found in non-Agg plan node");
840 
841 				scratch.opcode = EEOP_GROUPING_FUNC;
842 				scratch.d.grouping_func.parent = (AggState *) state->parent;
843 
844 				agg = (Agg *) (state->parent->plan);
845 
846 				if (agg->groupingSets)
847 					scratch.d.grouping_func.clauses = grp_node->cols;
848 				else
849 					scratch.d.grouping_func.clauses = NIL;
850 
851 				ExprEvalPushStep(state, &scratch);
852 				break;
853 			}
854 
855 		case T_WindowFunc:
856 			{
857 				WindowFunc *wfunc = (WindowFunc *) node;
858 				WindowFuncExprState *wfstate = makeNode(WindowFuncExprState);
859 
860 				wfstate->wfunc = wfunc;
861 
862 				if (state->parent && IsA(state->parent, WindowAggState))
863 				{
864 					WindowAggState *winstate = (WindowAggState *) state->parent;
865 					int			nfuncs;
866 
867 					winstate->funcs = lcons(wfstate, winstate->funcs);
868 					nfuncs = ++winstate->numfuncs;
869 					if (wfunc->winagg)
870 						winstate->numaggs++;
871 
872 					/* for now initialize agg using old style expressions */
873 					wfstate->args = ExecInitExprList(wfunc->args,
874 													 state->parent);
875 					wfstate->aggfilter = ExecInitExpr(wfunc->aggfilter,
876 													  state->parent);
877 
878 					/*
879 					 * Complain if the windowfunc's arguments contain any
880 					 * windowfuncs; nested window functions are semantically
881 					 * nonsensical.  (This should have been caught earlier,
882 					 * but we defend against it here anyway.)
883 					 */
884 					if (nfuncs != winstate->numfuncs)
885 						ereport(ERROR,
886 								(errcode(ERRCODE_WINDOWING_ERROR),
887 								 errmsg("window function calls cannot be nested")));
888 				}
889 				else
890 				{
891 					/* planner messed up */
892 					elog(ERROR, "WindowFunc found in non-WindowAgg plan node");
893 				}
894 
895 				scratch.opcode = EEOP_WINDOW_FUNC;
896 				scratch.d.window_func.wfstate = wfstate;
897 				ExprEvalPushStep(state, &scratch);
898 				break;
899 			}
900 
901 		case T_ArrayRef:
902 			{
903 				ArrayRef   *aref = (ArrayRef *) node;
904 
905 				ExecInitArrayRef(&scratch, aref, state, resv, resnull);
906 				break;
907 			}
908 
909 		case T_FuncExpr:
910 			{
911 				FuncExpr   *func = (FuncExpr *) node;
912 
913 				ExecInitFunc(&scratch, node,
914 							 func->args, func->funcid, func->inputcollid,
915 							 state);
916 				ExprEvalPushStep(state, &scratch);
917 				break;
918 			}
919 
920 		case T_OpExpr:
921 			{
922 				OpExpr	   *op = (OpExpr *) node;
923 
924 				ExecInitFunc(&scratch, node,
925 							 op->args, op->opfuncid, op->inputcollid,
926 							 state);
927 				ExprEvalPushStep(state, &scratch);
928 				break;
929 			}
930 
931 		case T_DistinctExpr:
932 			{
933 				DistinctExpr *op = (DistinctExpr *) node;
934 
935 				ExecInitFunc(&scratch, node,
936 							 op->args, op->opfuncid, op->inputcollid,
937 							 state);
938 
939 				/*
940 				 * Change opcode of call instruction to EEOP_DISTINCT.
941 				 *
942 				 * XXX: historically we've not called the function usage
943 				 * pgstat infrastructure - that seems inconsistent given that
944 				 * we do so for normal function *and* operator evaluation.  If
945 				 * we decided to do that here, we'd probably want separate
946 				 * opcodes for FUSAGE or not.
947 				 */
948 				scratch.opcode = EEOP_DISTINCT;
949 				ExprEvalPushStep(state, &scratch);
950 				break;
951 			}
952 
953 		case T_NullIfExpr:
954 			{
955 				NullIfExpr *op = (NullIfExpr *) node;
956 
957 				ExecInitFunc(&scratch, node,
958 							 op->args, op->opfuncid, op->inputcollid,
959 							 state);
960 
961 				/*
962 				 * Change opcode of call instruction to EEOP_NULLIF.
963 				 *
964 				 * XXX: historically we've not called the function usage
965 				 * pgstat infrastructure - that seems inconsistent given that
966 				 * we do so for normal function *and* operator evaluation.  If
967 				 * we decided to do that here, we'd probably want separate
968 				 * opcodes for FUSAGE or not.
969 				 */
970 				scratch.opcode = EEOP_NULLIF;
971 				ExprEvalPushStep(state, &scratch);
972 				break;
973 			}
974 
975 		case T_ScalarArrayOpExpr:
976 			{
977 				ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) node;
978 				Expr	   *scalararg;
979 				Expr	   *arrayarg;
980 				FmgrInfo   *finfo;
981 				FunctionCallInfo fcinfo;
982 				AclResult	aclresult;
983 
984 				Assert(list_length(opexpr->args) == 2);
985 				scalararg = (Expr *) linitial(opexpr->args);
986 				arrayarg = (Expr *) lsecond(opexpr->args);
987 
988 				/* Check permission to call function */
989 				aclresult = pg_proc_aclcheck(opexpr->opfuncid,
990 											 GetUserId(),
991 											 ACL_EXECUTE);
992 				if (aclresult != ACLCHECK_OK)
993 					aclcheck_error(aclresult, OBJECT_FUNCTION,
994 								   get_func_name(opexpr->opfuncid));
995 				InvokeFunctionExecuteHook(opexpr->opfuncid);
996 
997 				/* Set up the primary fmgr lookup information */
998 				finfo = palloc0(sizeof(FmgrInfo));
999 				fcinfo = palloc0(sizeof(FunctionCallInfoData));
1000 				fmgr_info(opexpr->opfuncid, finfo);
1001 				fmgr_info_set_expr((Node *) node, finfo);
1002 				InitFunctionCallInfoData(*fcinfo, finfo, 2,
1003 										 opexpr->inputcollid, NULL, NULL);
1004 
1005 				/* Evaluate scalar directly into left function argument */
1006 				ExecInitExprRec(scalararg, state,
1007 								&fcinfo->arg[0], &fcinfo->argnull[0]);
1008 
1009 				/*
1010 				 * Evaluate array argument into our return value.  There's no
1011 				 * danger in that, because the return value is guaranteed to
1012 				 * be overwritten by EEOP_SCALARARRAYOP, and will not be
1013 				 * passed to any other expression.
1014 				 */
1015 				ExecInitExprRec(arrayarg, state, resv, resnull);
1016 
1017 				/* And perform the operation */
1018 				scratch.opcode = EEOP_SCALARARRAYOP;
1019 				scratch.d.scalararrayop.element_type = InvalidOid;
1020 				scratch.d.scalararrayop.useOr = opexpr->useOr;
1021 				scratch.d.scalararrayop.finfo = finfo;
1022 				scratch.d.scalararrayop.fcinfo_data = fcinfo;
1023 				scratch.d.scalararrayop.fn_addr = finfo->fn_addr;
1024 				ExprEvalPushStep(state, &scratch);
1025 				break;
1026 			}
1027 
1028 		case T_BoolExpr:
1029 			{
1030 				BoolExpr   *boolexpr = (BoolExpr *) node;
1031 				int			nargs = list_length(boolexpr->args);
1032 				List	   *adjust_jumps = NIL;
1033 				int			off;
1034 				ListCell   *lc;
1035 
1036 				/* allocate scratch memory used by all steps of AND/OR */
1037 				if (boolexpr->boolop != NOT_EXPR)
1038 					scratch.d.boolexpr.anynull = (bool *) palloc(sizeof(bool));
1039 
1040 				/*
1041 				 * For each argument evaluate the argument itself, then
1042 				 * perform the bool operation's appropriate handling.
1043 				 *
1044 				 * We can evaluate each argument into our result area, since
1045 				 * the short-circuiting logic means we only need to remember
1046 				 * previous NULL values.
1047 				 *
1048 				 * AND/OR is split into separate STEP_FIRST (one) / STEP (zero
1049 				 * or more) / STEP_LAST (one) steps, as each of those has to
1050 				 * perform different work.  The FIRST/LAST split is valid
1051 				 * because AND/OR have at least two arguments.
1052 				 */
1053 				off = 0;
1054 				foreach(lc, boolexpr->args)
1055 				{
1056 					Expr	   *arg = (Expr *) lfirst(lc);
1057 
1058 					/* Evaluate argument into our output variable */
1059 					ExecInitExprRec(arg, state, resv, resnull);
1060 
1061 					/* Perform the appropriate step type */
1062 					switch (boolexpr->boolop)
1063 					{
1064 						case AND_EXPR:
1065 							Assert(nargs >= 2);
1066 
1067 							if (off == 0)
1068 								scratch.opcode = EEOP_BOOL_AND_STEP_FIRST;
1069 							else if (off + 1 == nargs)
1070 								scratch.opcode = EEOP_BOOL_AND_STEP_LAST;
1071 							else
1072 								scratch.opcode = EEOP_BOOL_AND_STEP;
1073 							break;
1074 						case OR_EXPR:
1075 							Assert(nargs >= 2);
1076 
1077 							if (off == 0)
1078 								scratch.opcode = EEOP_BOOL_OR_STEP_FIRST;
1079 							else if (off + 1 == nargs)
1080 								scratch.opcode = EEOP_BOOL_OR_STEP_LAST;
1081 							else
1082 								scratch.opcode = EEOP_BOOL_OR_STEP;
1083 							break;
1084 						case NOT_EXPR:
1085 							Assert(nargs == 1);
1086 
1087 							scratch.opcode = EEOP_BOOL_NOT_STEP;
1088 							break;
1089 						default:
1090 							elog(ERROR, "unrecognized boolop: %d",
1091 								 (int) boolexpr->boolop);
1092 							break;
1093 					}
1094 
1095 					scratch.d.boolexpr.jumpdone = -1;
1096 					ExprEvalPushStep(state, &scratch);
1097 					adjust_jumps = lappend_int(adjust_jumps,
1098 											   state->steps_len - 1);
1099 					off++;
1100 				}
1101 
1102 				/* adjust jump targets */
1103 				foreach(lc, adjust_jumps)
1104 				{
1105 					ExprEvalStep *as = &state->steps[lfirst_int(lc)];
1106 
1107 					Assert(as->d.boolexpr.jumpdone == -1);
1108 					as->d.boolexpr.jumpdone = state->steps_len;
1109 				}
1110 
1111 				break;
1112 			}
1113 
1114 		case T_SubPlan:
1115 			{
1116 				SubPlan    *subplan = (SubPlan *) node;
1117 				SubPlanState *sstate;
1118 
1119 				if (!state->parent)
1120 					elog(ERROR, "SubPlan found with no parent plan");
1121 
1122 				sstate = ExecInitSubPlan(subplan, state->parent);
1123 
1124 				/* add SubPlanState nodes to state->parent->subPlan */
1125 				state->parent->subPlan = lappend(state->parent->subPlan,
1126 												 sstate);
1127 
1128 				scratch.opcode = EEOP_SUBPLAN;
1129 				scratch.d.subplan.sstate = sstate;
1130 
1131 				ExprEvalPushStep(state, &scratch);
1132 				break;
1133 			}
1134 
1135 		case T_AlternativeSubPlan:
1136 			{
1137 				AlternativeSubPlan *asplan = (AlternativeSubPlan *) node;
1138 				AlternativeSubPlanState *asstate;
1139 
1140 				if (!state->parent)
1141 					elog(ERROR, "AlternativeSubPlan found with no parent plan");
1142 
1143 				asstate = ExecInitAlternativeSubPlan(asplan, state->parent);
1144 
1145 				scratch.opcode = EEOP_ALTERNATIVE_SUBPLAN;
1146 				scratch.d.alternative_subplan.asstate = asstate;
1147 
1148 				ExprEvalPushStep(state, &scratch);
1149 				break;
1150 			}
1151 
1152 		case T_FieldSelect:
1153 			{
1154 				FieldSelect *fselect = (FieldSelect *) node;
1155 
1156 				/* evaluate row/record argument into result area */
1157 				ExecInitExprRec(fselect->arg, state, resv, resnull);
1158 
1159 				/* and extract field */
1160 				scratch.opcode = EEOP_FIELDSELECT;
1161 				scratch.d.fieldselect.fieldnum = fselect->fieldnum;
1162 				scratch.d.fieldselect.resulttype = fselect->resulttype;
1163 				scratch.d.fieldselect.rowcache.cacheptr = NULL;
1164 
1165 				ExprEvalPushStep(state, &scratch);
1166 				break;
1167 			}
1168 
1169 		case T_FieldStore:
1170 			{
1171 				FieldStore *fstore = (FieldStore *) node;
1172 				TupleDesc	tupDesc;
1173 				ExprEvalRowtypeCache *rowcachep;
1174 				Datum	   *values;
1175 				bool	   *nulls;
1176 				int			ncolumns;
1177 				ListCell   *l1,
1178 						   *l2;
1179 
1180 				/* find out the number of columns in the composite type */
1181 				tupDesc = lookup_rowtype_tupdesc(fstore->resulttype, -1);
1182 				ncolumns = tupDesc->natts;
1183 				DecrTupleDescRefCount(tupDesc);
1184 
1185 				/* create workspace for column values */
1186 				values = (Datum *) palloc(sizeof(Datum) * ncolumns);
1187 				nulls = (bool *) palloc(sizeof(bool) * ncolumns);
1188 
1189 				/* create shared composite-type-lookup cache struct */
1190 				rowcachep = palloc(sizeof(ExprEvalRowtypeCache));
1191 				rowcachep->cacheptr = NULL;
1192 
1193 				/* emit code to evaluate the composite input value */
1194 				ExecInitExprRec(fstore->arg, state, resv, resnull);
1195 
1196 				/* next, deform the input tuple into our workspace */
1197 				scratch.opcode = EEOP_FIELDSTORE_DEFORM;
1198 				scratch.d.fieldstore.fstore = fstore;
1199 				scratch.d.fieldstore.rowcache = rowcachep;
1200 				scratch.d.fieldstore.values = values;
1201 				scratch.d.fieldstore.nulls = nulls;
1202 				scratch.d.fieldstore.ncolumns = ncolumns;
1203 				ExprEvalPushStep(state, &scratch);
1204 
1205 				/* evaluate new field values, store in workspace columns */
1206 				forboth(l1, fstore->newvals, l2, fstore->fieldnums)
1207 				{
1208 					Expr	   *e = (Expr *) lfirst(l1);
1209 					AttrNumber	fieldnum = lfirst_int(l2);
1210 					Datum	   *save_innermost_caseval;
1211 					bool	   *save_innermost_casenull;
1212 
1213 					if (fieldnum <= 0 || fieldnum > ncolumns)
1214 						elog(ERROR, "field number %d is out of range in FieldStore",
1215 							 fieldnum);
1216 
1217 					/*
1218 					 * Use the CaseTestExpr mechanism to pass down the old
1219 					 * value of the field being replaced; this is needed in
1220 					 * case the newval is itself a FieldStore or ArrayRef that
1221 					 * has to obtain and modify the old value.  It's safe to
1222 					 * reuse the CASE mechanism because there cannot be a CASE
1223 					 * between here and where the value would be needed, and a
1224 					 * field assignment can't be within a CASE either.  (So
1225 					 * saving and restoring innermost_caseval is just
1226 					 * paranoia, but let's do it anyway.)
1227 					 *
1228 					 * Another non-obvious point is that it's safe to use the
1229 					 * field's values[]/nulls[] entries as both the caseval
1230 					 * source and the result address for this subexpression.
1231 					 * That's okay only because (1) both FieldStore and
1232 					 * ArrayRef evaluate their arg or refexpr inputs first,
1233 					 * and (2) any such CaseTestExpr is directly the arg or
1234 					 * refexpr input.  So any read of the caseval will occur
1235 					 * before there's a chance to overwrite it.  Also, if
1236 					 * multiple entries in the newvals/fieldnums lists target
1237 					 * the same field, they'll effectively be applied
1238 					 * left-to-right which is what we want.
1239 					 */
1240 					save_innermost_caseval = state->innermost_caseval;
1241 					save_innermost_casenull = state->innermost_casenull;
1242 					state->innermost_caseval = &values[fieldnum - 1];
1243 					state->innermost_casenull = &nulls[fieldnum - 1];
1244 
1245 					ExecInitExprRec(e, state,
1246 									&values[fieldnum - 1],
1247 									&nulls[fieldnum - 1]);
1248 
1249 					state->innermost_caseval = save_innermost_caseval;
1250 					state->innermost_casenull = save_innermost_casenull;
1251 				}
1252 
1253 				/* finally, form result tuple */
1254 				scratch.opcode = EEOP_FIELDSTORE_FORM;
1255 				scratch.d.fieldstore.fstore = fstore;
1256 				scratch.d.fieldstore.rowcache = rowcachep;
1257 				scratch.d.fieldstore.values = values;
1258 				scratch.d.fieldstore.nulls = nulls;
1259 				scratch.d.fieldstore.ncolumns = ncolumns;
1260 				ExprEvalPushStep(state, &scratch);
1261 				break;
1262 			}
1263 
1264 		case T_RelabelType:
1265 			{
1266 				/* relabel doesn't need to do anything at runtime */
1267 				RelabelType *relabel = (RelabelType *) node;
1268 
1269 				ExecInitExprRec(relabel->arg, state, resv, resnull);
1270 				break;
1271 			}
1272 
1273 		case T_CoerceViaIO:
1274 			{
1275 				CoerceViaIO *iocoerce = (CoerceViaIO *) node;
1276 				Oid			iofunc;
1277 				bool		typisvarlena;
1278 				Oid			typioparam;
1279 				FunctionCallInfo fcinfo_in;
1280 
1281 				/* evaluate argument into step's result area */
1282 				ExecInitExprRec(iocoerce->arg, state, resv, resnull);
1283 
1284 				/*
1285 				 * Prepare both output and input function calls, to be
1286 				 * evaluated inside a single evaluation step for speed - this
1287 				 * can be a very common operation.
1288 				 *
1289 				 * We don't check permissions here as a type's input/output
1290 				 * function are assumed to be executable by everyone.
1291 				 */
1292 				scratch.opcode = EEOP_IOCOERCE;
1293 
1294 				/* lookup the source type's output function */
1295 				scratch.d.iocoerce.finfo_out = palloc0(sizeof(FmgrInfo));
1296 				scratch.d.iocoerce.fcinfo_data_out = palloc0(sizeof(FunctionCallInfoData));
1297 
1298 				getTypeOutputInfo(exprType((Node *) iocoerce->arg),
1299 								  &iofunc, &typisvarlena);
1300 				fmgr_info(iofunc, scratch.d.iocoerce.finfo_out);
1301 				fmgr_info_set_expr((Node *) node, scratch.d.iocoerce.finfo_out);
1302 				InitFunctionCallInfoData(*scratch.d.iocoerce.fcinfo_data_out,
1303 										 scratch.d.iocoerce.finfo_out,
1304 										 1, InvalidOid, NULL, NULL);
1305 
1306 				/* lookup the result type's input function */
1307 				scratch.d.iocoerce.finfo_in = palloc0(sizeof(FmgrInfo));
1308 				scratch.d.iocoerce.fcinfo_data_in = palloc0(sizeof(FunctionCallInfoData));
1309 
1310 				getTypeInputInfo(iocoerce->resulttype,
1311 								 &iofunc, &typioparam);
1312 				fmgr_info(iofunc, scratch.d.iocoerce.finfo_in);
1313 				fmgr_info_set_expr((Node *) node, scratch.d.iocoerce.finfo_in);
1314 				InitFunctionCallInfoData(*scratch.d.iocoerce.fcinfo_data_in,
1315 										 scratch.d.iocoerce.finfo_in,
1316 										 3, InvalidOid, NULL, NULL);
1317 
1318 				/*
1319 				 * We can preload the second and third arguments for the input
1320 				 * function, since they're constants.
1321 				 */
1322 				fcinfo_in = scratch.d.iocoerce.fcinfo_data_in;
1323 				fcinfo_in->arg[1] = ObjectIdGetDatum(typioparam);
1324 				fcinfo_in->argnull[1] = false;
1325 				fcinfo_in->arg[2] = Int32GetDatum(-1);
1326 				fcinfo_in->argnull[2] = false;
1327 
1328 				ExprEvalPushStep(state, &scratch);
1329 				break;
1330 			}
1331 
1332 		case T_ArrayCoerceExpr:
1333 			{
1334 				ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node;
1335 				Oid			resultelemtype;
1336 				ExprState  *elemstate;
1337 
1338 				/* evaluate argument into step's result area */
1339 				ExecInitExprRec(acoerce->arg, state, resv, resnull);
1340 
1341 				resultelemtype = get_element_type(acoerce->resulttype);
1342 				if (!OidIsValid(resultelemtype))
1343 					ereport(ERROR,
1344 							(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1345 							 errmsg("target type is not an array")));
1346 
1347 				/*
1348 				 * Construct a sub-expression for the per-element expression;
1349 				 * but don't ready it until after we check it for triviality.
1350 				 * We assume it hasn't any Var references, but does have a
1351 				 * CaseTestExpr representing the source array element values.
1352 				 */
1353 				elemstate = makeNode(ExprState);
1354 				elemstate->expr = acoerce->elemexpr;
1355 				elemstate->parent = state->parent;
1356 				elemstate->ext_params = state->ext_params;
1357 
1358 				elemstate->innermost_caseval = (Datum *) palloc(sizeof(Datum));
1359 				elemstate->innermost_casenull = (bool *) palloc(sizeof(bool));
1360 
1361 				ExecInitExprRec(acoerce->elemexpr, elemstate,
1362 								&elemstate->resvalue, &elemstate->resnull);
1363 
1364 				if (elemstate->steps_len == 1 &&
1365 					elemstate->steps[0].opcode == EEOP_CASE_TESTVAL)
1366 				{
1367 					/* Trivial, so we need no per-element work at runtime */
1368 					elemstate = NULL;
1369 				}
1370 				else
1371 				{
1372 					/* Not trivial, so append a DONE step */
1373 					scratch.opcode = EEOP_DONE;
1374 					ExprEvalPushStep(elemstate, &scratch);
1375 					/* and ready the subexpression */
1376 					ExecReadyExpr(elemstate);
1377 				}
1378 
1379 				scratch.opcode = EEOP_ARRAYCOERCE;
1380 				scratch.d.arraycoerce.elemexprstate = elemstate;
1381 				scratch.d.arraycoerce.resultelemtype = resultelemtype;
1382 
1383 				if (elemstate)
1384 				{
1385 					/* Set up workspace for array_map */
1386 					scratch.d.arraycoerce.amstate =
1387 						(ArrayMapState *) palloc0(sizeof(ArrayMapState));
1388 				}
1389 				else
1390 				{
1391 					/* Don't need workspace if there's no subexpression */
1392 					scratch.d.arraycoerce.amstate = NULL;
1393 				}
1394 
1395 				ExprEvalPushStep(state, &scratch);
1396 				break;
1397 			}
1398 
1399 		case T_ConvertRowtypeExpr:
1400 			{
1401 				ConvertRowtypeExpr *convert = (ConvertRowtypeExpr *) node;
1402 				ExprEvalRowtypeCache *rowcachep;
1403 
1404 				/* cache structs must be out-of-line for space reasons */
1405 				rowcachep = palloc(2 * sizeof(ExprEvalRowtypeCache));
1406 				rowcachep[0].cacheptr = NULL;
1407 				rowcachep[1].cacheptr = NULL;
1408 
1409 				/* evaluate argument into step's result area */
1410 				ExecInitExprRec(convert->arg, state, resv, resnull);
1411 
1412 				/* and push conversion step */
1413 				scratch.opcode = EEOP_CONVERT_ROWTYPE;
1414 				scratch.d.convert_rowtype.inputtype =
1415 					exprType((Node *) convert->arg);
1416 				scratch.d.convert_rowtype.outputtype = convert->resulttype;
1417 				scratch.d.convert_rowtype.incache = &rowcachep[0];
1418 				scratch.d.convert_rowtype.outcache = &rowcachep[1];
1419 				scratch.d.convert_rowtype.map = NULL;
1420 
1421 				ExprEvalPushStep(state, &scratch);
1422 				break;
1423 			}
1424 
1425 			/* note that CaseWhen expressions are handled within this block */
1426 		case T_CaseExpr:
1427 			{
1428 				CaseExpr   *caseExpr = (CaseExpr *) node;
1429 				List	   *adjust_jumps = NIL;
1430 				Datum	   *caseval = NULL;
1431 				bool	   *casenull = NULL;
1432 				ListCell   *lc;
1433 
1434 				/*
1435 				 * If there's a test expression, we have to evaluate it and
1436 				 * save the value where the CaseTestExpr placeholders can find
1437 				 * it.
1438 				 */
1439 				if (caseExpr->arg != NULL)
1440 				{
1441 					/* Evaluate testexpr into caseval/casenull workspace */
1442 					caseval = palloc(sizeof(Datum));
1443 					casenull = palloc(sizeof(bool));
1444 
1445 					ExecInitExprRec(caseExpr->arg, state,
1446 									caseval, casenull);
1447 
1448 					/*
1449 					 * Since value might be read multiple times, force to R/O
1450 					 * - but only if it could be an expanded datum.
1451 					 */
1452 					if (get_typlen(exprType((Node *) caseExpr->arg)) == -1)
1453 					{
1454 						/* change caseval in-place */
1455 						scratch.opcode = EEOP_MAKE_READONLY;
1456 						scratch.resvalue = caseval;
1457 						scratch.resnull = casenull;
1458 						scratch.d.make_readonly.value = caseval;
1459 						scratch.d.make_readonly.isnull = casenull;
1460 						ExprEvalPushStep(state, &scratch);
1461 						/* restore normal settings of scratch fields */
1462 						scratch.resvalue = resv;
1463 						scratch.resnull = resnull;
1464 					}
1465 				}
1466 
1467 				/*
1468 				 * Prepare to evaluate each of the WHEN clauses in turn; as
1469 				 * soon as one is true we return the value of the
1470 				 * corresponding THEN clause.  If none are true then we return
1471 				 * the value of the ELSE clause, or NULL if there is none.
1472 				 */
1473 				foreach(lc, caseExpr->args)
1474 				{
1475 					CaseWhen   *when = (CaseWhen *) lfirst(lc);
1476 					Datum	   *save_innermost_caseval;
1477 					bool	   *save_innermost_casenull;
1478 					int			whenstep;
1479 
1480 					/*
1481 					 * Make testexpr result available to CaseTestExpr nodes
1482 					 * within the condition.  We must save and restore prior
1483 					 * setting of innermost_caseval fields, in case this node
1484 					 * is itself within a larger CASE.
1485 					 *
1486 					 * If there's no test expression, we don't actually need
1487 					 * to save and restore these fields; but it's less code to
1488 					 * just do so unconditionally.
1489 					 */
1490 					save_innermost_caseval = state->innermost_caseval;
1491 					save_innermost_casenull = state->innermost_casenull;
1492 					state->innermost_caseval = caseval;
1493 					state->innermost_casenull = casenull;
1494 
1495 					/* evaluate condition into CASE's result variables */
1496 					ExecInitExprRec(when->expr, state, resv, resnull);
1497 
1498 					state->innermost_caseval = save_innermost_caseval;
1499 					state->innermost_casenull = save_innermost_casenull;
1500 
1501 					/* If WHEN result isn't true, jump to next CASE arm */
1502 					scratch.opcode = EEOP_JUMP_IF_NOT_TRUE;
1503 					scratch.d.jump.jumpdone = -1;	/* computed later */
1504 					ExprEvalPushStep(state, &scratch);
1505 					whenstep = state->steps_len - 1;
1506 
1507 					/*
1508 					 * If WHEN result is true, evaluate THEN result, storing
1509 					 * it into the CASE's result variables.
1510 					 */
1511 					ExecInitExprRec(when->result, state, resv, resnull);
1512 
1513 					/* Emit JUMP step to jump to end of CASE's code */
1514 					scratch.opcode = EEOP_JUMP;
1515 					scratch.d.jump.jumpdone = -1;	/* computed later */
1516 					ExprEvalPushStep(state, &scratch);
1517 
1518 					/*
1519 					 * Don't know address for that jump yet, compute once the
1520 					 * whole CASE expression is built.
1521 					 */
1522 					adjust_jumps = lappend_int(adjust_jumps,
1523 											   state->steps_len - 1);
1524 
1525 					/*
1526 					 * But we can set WHEN test's jump target now, to make it
1527 					 * jump to the next WHEN subexpression or the ELSE.
1528 					 */
1529 					state->steps[whenstep].d.jump.jumpdone = state->steps_len;
1530 				}
1531 
1532 				/* transformCaseExpr always adds a default */
1533 				Assert(caseExpr->defresult);
1534 
1535 				/* evaluate ELSE expr into CASE's result variables */
1536 				ExecInitExprRec(caseExpr->defresult, state,
1537 								resv, resnull);
1538 
1539 				/* adjust jump targets */
1540 				foreach(lc, adjust_jumps)
1541 				{
1542 					ExprEvalStep *as = &state->steps[lfirst_int(lc)];
1543 
1544 					Assert(as->opcode == EEOP_JUMP);
1545 					Assert(as->d.jump.jumpdone == -1);
1546 					as->d.jump.jumpdone = state->steps_len;
1547 				}
1548 
1549 				break;
1550 			}
1551 
1552 		case T_CaseTestExpr:
1553 			{
1554 				/*
1555 				 * Read from location identified by innermost_caseval.  Note
1556 				 * that innermost_caseval could be NULL, if this node isn't
1557 				 * actually within a CaseExpr, ArrayCoerceExpr, etc structure.
1558 				 * That can happen because some parts of the system abuse
1559 				 * CaseTestExpr to cause a read of a value externally supplied
1560 				 * in econtext->caseValue_datum.  We'll take care of that
1561 				 * scenario at runtime.
1562 				 */
1563 				scratch.opcode = EEOP_CASE_TESTVAL;
1564 				scratch.d.casetest.value = state->innermost_caseval;
1565 				scratch.d.casetest.isnull = state->innermost_casenull;
1566 
1567 				ExprEvalPushStep(state, &scratch);
1568 				break;
1569 			}
1570 
1571 		case T_ArrayExpr:
1572 			{
1573 				ArrayExpr  *arrayexpr = (ArrayExpr *) node;
1574 				int			nelems = list_length(arrayexpr->elements);
1575 				ListCell   *lc;
1576 				int			elemoff;
1577 
1578 				/*
1579 				 * Evaluate by computing each element, and then forming the
1580 				 * array.  Elements are computed into scratch arrays
1581 				 * associated with the ARRAYEXPR step.
1582 				 */
1583 				scratch.opcode = EEOP_ARRAYEXPR;
1584 				scratch.d.arrayexpr.elemvalues =
1585 					(Datum *) palloc(sizeof(Datum) * nelems);
1586 				scratch.d.arrayexpr.elemnulls =
1587 					(bool *) palloc(sizeof(bool) * nelems);
1588 				scratch.d.arrayexpr.nelems = nelems;
1589 
1590 				/* fill remaining fields of step */
1591 				scratch.d.arrayexpr.multidims = arrayexpr->multidims;
1592 				scratch.d.arrayexpr.elemtype = arrayexpr->element_typeid;
1593 
1594 				/* do one-time catalog lookup for type info */
1595 				get_typlenbyvalalign(arrayexpr->element_typeid,
1596 									 &scratch.d.arrayexpr.elemlength,
1597 									 &scratch.d.arrayexpr.elembyval,
1598 									 &scratch.d.arrayexpr.elemalign);
1599 
1600 				/* prepare to evaluate all arguments */
1601 				elemoff = 0;
1602 				foreach(lc, arrayexpr->elements)
1603 				{
1604 					Expr	   *e = (Expr *) lfirst(lc);
1605 
1606 					ExecInitExprRec(e, state,
1607 									&scratch.d.arrayexpr.elemvalues[elemoff],
1608 									&scratch.d.arrayexpr.elemnulls[elemoff]);
1609 					elemoff++;
1610 				}
1611 
1612 				/* and then collect all into an array */
1613 				ExprEvalPushStep(state, &scratch);
1614 				break;
1615 			}
1616 
1617 		case T_RowExpr:
1618 			{
1619 				RowExpr    *rowexpr = (RowExpr *) node;
1620 				int			nelems = list_length(rowexpr->args);
1621 				TupleDesc	tupdesc;
1622 				int			i;
1623 				ListCell   *l;
1624 
1625 				/* Build tupdesc to describe result tuples */
1626 				if (rowexpr->row_typeid == RECORDOID)
1627 				{
1628 					/* generic record, use types of given expressions */
1629 					tupdesc = ExecTypeFromExprList(rowexpr->args);
1630 				}
1631 				else
1632 				{
1633 					/* it's been cast to a named type, use that */
1634 					tupdesc = lookup_rowtype_tupdesc_copy(rowexpr->row_typeid, -1);
1635 				}
1636 				/* In either case, adopt RowExpr's column aliases */
1637 				ExecTypeSetColNames(tupdesc, rowexpr->colnames);
1638 				/* Bless the tupdesc in case it's now of type RECORD */
1639 				BlessTupleDesc(tupdesc);
1640 
1641 				/*
1642 				 * In the named-type case, the tupdesc could have more columns
1643 				 * than are in the args list, since the type might have had
1644 				 * columns added since the ROW() was parsed.  We want those
1645 				 * extra columns to go to nulls, so we make sure that the
1646 				 * workspace arrays are large enough and then initialize any
1647 				 * extra columns to read as NULLs.
1648 				 */
1649 				Assert(nelems <= tupdesc->natts);
1650 				nelems = Max(nelems, tupdesc->natts);
1651 
1652 				/*
1653 				 * Evaluate by first building datums for each field, and then
1654 				 * a final step forming the composite datum.
1655 				 */
1656 				scratch.opcode = EEOP_ROW;
1657 				scratch.d.row.tupdesc = tupdesc;
1658 
1659 				/* space for the individual field datums */
1660 				scratch.d.row.elemvalues =
1661 					(Datum *) palloc(sizeof(Datum) * nelems);
1662 				scratch.d.row.elemnulls =
1663 					(bool *) palloc(sizeof(bool) * nelems);
1664 				/* as explained above, make sure any extra columns are null */
1665 				memset(scratch.d.row.elemnulls, true, sizeof(bool) * nelems);
1666 
1667 				/* Set up evaluation, skipping any deleted columns */
1668 				i = 0;
1669 				foreach(l, rowexpr->args)
1670 				{
1671 					Form_pg_attribute att = TupleDescAttr(tupdesc, i);
1672 					Expr	   *e = (Expr *) lfirst(l);
1673 
1674 					if (!att->attisdropped)
1675 					{
1676 						/*
1677 						 * Guard against ALTER COLUMN TYPE on rowtype since
1678 						 * the RowExpr was created.  XXX should we check
1679 						 * typmod too?	Not sure we can be sure it'll be the
1680 						 * same.
1681 						 */
1682 						if (exprType((Node *) e) != att->atttypid)
1683 							ereport(ERROR,
1684 									(errcode(ERRCODE_DATATYPE_MISMATCH),
1685 									 errmsg("ROW() column has type %s instead of type %s",
1686 											format_type_be(exprType((Node *) e)),
1687 											format_type_be(att->atttypid))));
1688 					}
1689 					else
1690 					{
1691 						/*
1692 						 * Ignore original expression and insert a NULL. We
1693 						 * don't really care what type of NULL it is, so
1694 						 * always make an int4 NULL.
1695 						 */
1696 						e = (Expr *) makeNullConst(INT4OID, -1, InvalidOid);
1697 					}
1698 
1699 					/* Evaluate column expr into appropriate workspace slot */
1700 					ExecInitExprRec(e, state,
1701 									&scratch.d.row.elemvalues[i],
1702 									&scratch.d.row.elemnulls[i]);
1703 					i++;
1704 				}
1705 
1706 				/* And finally build the row value */
1707 				ExprEvalPushStep(state, &scratch);
1708 				break;
1709 			}
1710 
1711 		case T_RowCompareExpr:
1712 			{
1713 				RowCompareExpr *rcexpr = (RowCompareExpr *) node;
1714 				int			nopers = list_length(rcexpr->opnos);
1715 				List	   *adjust_jumps = NIL;
1716 				ListCell   *l_left_expr,
1717 						   *l_right_expr,
1718 						   *l_opno,
1719 						   *l_opfamily,
1720 						   *l_inputcollid;
1721 				ListCell   *lc;
1722 				int			off;
1723 
1724 				/*
1725 				 * Iterate over each field, prepare comparisons.  To handle
1726 				 * NULL results, prepare jumps to after the expression.  If a
1727 				 * comparison yields a != 0 result, jump to the final step.
1728 				 */
1729 				Assert(list_length(rcexpr->largs) == nopers);
1730 				Assert(list_length(rcexpr->rargs) == nopers);
1731 				Assert(list_length(rcexpr->opfamilies) == nopers);
1732 				Assert(list_length(rcexpr->inputcollids) == nopers);
1733 
1734 				off = 0;
1735 				for (off = 0,
1736 					 l_left_expr = list_head(rcexpr->largs),
1737 					 l_right_expr = list_head(rcexpr->rargs),
1738 					 l_opno = list_head(rcexpr->opnos),
1739 					 l_opfamily = list_head(rcexpr->opfamilies),
1740 					 l_inputcollid = list_head(rcexpr->inputcollids);
1741 					 off < nopers;
1742 					 off++,
1743 					 l_left_expr = lnext(l_left_expr),
1744 					 l_right_expr = lnext(l_right_expr),
1745 					 l_opno = lnext(l_opno),
1746 					 l_opfamily = lnext(l_opfamily),
1747 					 l_inputcollid = lnext(l_inputcollid))
1748 				{
1749 					Expr	   *left_expr = (Expr *) lfirst(l_left_expr);
1750 					Expr	   *right_expr = (Expr *) lfirst(l_right_expr);
1751 					Oid			opno = lfirst_oid(l_opno);
1752 					Oid			opfamily = lfirst_oid(l_opfamily);
1753 					Oid			inputcollid = lfirst_oid(l_inputcollid);
1754 					int			strategy;
1755 					Oid			lefttype;
1756 					Oid			righttype;
1757 					Oid			proc;
1758 					FmgrInfo   *finfo;
1759 					FunctionCallInfo fcinfo;
1760 
1761 					get_op_opfamily_properties(opno, opfamily, false,
1762 											   &strategy,
1763 											   &lefttype,
1764 											   &righttype);
1765 					proc = get_opfamily_proc(opfamily,
1766 											 lefttype,
1767 											 righttype,
1768 											 BTORDER_PROC);
1769 					if (!OidIsValid(proc))
1770 						elog(ERROR, "missing support function %d(%u,%u) in opfamily %u",
1771 							 BTORDER_PROC, lefttype, righttype, opfamily);
1772 
1773 					/* Set up the primary fmgr lookup information */
1774 					finfo = palloc0(sizeof(FmgrInfo));
1775 					fcinfo = palloc0(sizeof(FunctionCallInfoData));
1776 					fmgr_info(proc, finfo);
1777 					fmgr_info_set_expr((Node *) node, finfo);
1778 					InitFunctionCallInfoData(*fcinfo, finfo, 2,
1779 											 inputcollid, NULL, NULL);
1780 
1781 					/*
1782 					 * If we enforced permissions checks on index support
1783 					 * functions, we'd need to make a check here.  But the
1784 					 * index support machinery doesn't do that, and thus
1785 					 * neither does this code.
1786 					 */
1787 
1788 					/* evaluate left and right args directly into fcinfo */
1789 					ExecInitExprRec(left_expr, state,
1790 									&fcinfo->arg[0], &fcinfo->argnull[0]);
1791 					ExecInitExprRec(right_expr, state,
1792 									&fcinfo->arg[1], &fcinfo->argnull[1]);
1793 
1794 					scratch.opcode = EEOP_ROWCOMPARE_STEP;
1795 					scratch.d.rowcompare_step.finfo = finfo;
1796 					scratch.d.rowcompare_step.fcinfo_data = fcinfo;
1797 					scratch.d.rowcompare_step.fn_addr = finfo->fn_addr;
1798 					/* jump targets filled below */
1799 					scratch.d.rowcompare_step.jumpnull = -1;
1800 					scratch.d.rowcompare_step.jumpdone = -1;
1801 
1802 					ExprEvalPushStep(state, &scratch);
1803 					adjust_jumps = lappend_int(adjust_jumps,
1804 											   state->steps_len - 1);
1805 				}
1806 
1807 				/*
1808 				 * We could have a zero-column rowtype, in which case the rows
1809 				 * necessarily compare equal.
1810 				 */
1811 				if (nopers == 0)
1812 				{
1813 					scratch.opcode = EEOP_CONST;
1814 					scratch.d.constval.value = Int32GetDatum(0);
1815 					scratch.d.constval.isnull = false;
1816 					ExprEvalPushStep(state, &scratch);
1817 				}
1818 
1819 				/* Finally, examine the last comparison result */
1820 				scratch.opcode = EEOP_ROWCOMPARE_FINAL;
1821 				scratch.d.rowcompare_final.rctype = rcexpr->rctype;
1822 				ExprEvalPushStep(state, &scratch);
1823 
1824 				/* adjust jump targetss */
1825 				foreach(lc, adjust_jumps)
1826 				{
1827 					ExprEvalStep *as = &state->steps[lfirst_int(lc)];
1828 
1829 					Assert(as->opcode == EEOP_ROWCOMPARE_STEP);
1830 					Assert(as->d.rowcompare_step.jumpdone == -1);
1831 					Assert(as->d.rowcompare_step.jumpnull == -1);
1832 
1833 					/* jump to comparison evaluation */
1834 					as->d.rowcompare_step.jumpdone = state->steps_len - 1;
1835 					/* jump to the following expression */
1836 					as->d.rowcompare_step.jumpnull = state->steps_len;
1837 				}
1838 
1839 				break;
1840 			}
1841 
1842 		case T_CoalesceExpr:
1843 			{
1844 				CoalesceExpr *coalesce = (CoalesceExpr *) node;
1845 				List	   *adjust_jumps = NIL;
1846 				ListCell   *lc;
1847 
1848 				/* We assume there's at least one arg */
1849 				Assert(coalesce->args != NIL);
1850 
1851 				/*
1852 				 * Prepare evaluation of all coalesced arguments, after each
1853 				 * one push a step that short-circuits if not null.
1854 				 */
1855 				foreach(lc, coalesce->args)
1856 				{
1857 					Expr	   *e = (Expr *) lfirst(lc);
1858 
1859 					/* evaluate argument, directly into result datum */
1860 					ExecInitExprRec(e, state, resv, resnull);
1861 
1862 					/* if it's not null, skip to end of COALESCE expr */
1863 					scratch.opcode = EEOP_JUMP_IF_NOT_NULL;
1864 					scratch.d.jump.jumpdone = -1;	/* adjust later */
1865 					ExprEvalPushStep(state, &scratch);
1866 
1867 					adjust_jumps = lappend_int(adjust_jumps,
1868 											   state->steps_len - 1);
1869 				}
1870 
1871 				/*
1872 				 * No need to add a constant NULL return - we only can get to
1873 				 * the end of the expression if a NULL already is being
1874 				 * returned.
1875 				 */
1876 
1877 				/* adjust jump targets */
1878 				foreach(lc, adjust_jumps)
1879 				{
1880 					ExprEvalStep *as = &state->steps[lfirst_int(lc)];
1881 
1882 					Assert(as->opcode == EEOP_JUMP_IF_NOT_NULL);
1883 					Assert(as->d.jump.jumpdone == -1);
1884 					as->d.jump.jumpdone = state->steps_len;
1885 				}
1886 
1887 				break;
1888 			}
1889 
1890 		case T_MinMaxExpr:
1891 			{
1892 				MinMaxExpr *minmaxexpr = (MinMaxExpr *) node;
1893 				int			nelems = list_length(minmaxexpr->args);
1894 				TypeCacheEntry *typentry;
1895 				FmgrInfo   *finfo;
1896 				FunctionCallInfo fcinfo;
1897 				ListCell   *lc;
1898 				int			off;
1899 
1900 				/* Look up the btree comparison function for the datatype */
1901 				typentry = lookup_type_cache(minmaxexpr->minmaxtype,
1902 											 TYPECACHE_CMP_PROC);
1903 				if (!OidIsValid(typentry->cmp_proc))
1904 					ereport(ERROR,
1905 							(errcode(ERRCODE_UNDEFINED_FUNCTION),
1906 							 errmsg("could not identify a comparison function for type %s",
1907 									format_type_be(minmaxexpr->minmaxtype))));
1908 
1909 				/*
1910 				 * If we enforced permissions checks on index support
1911 				 * functions, we'd need to make a check here.  But the index
1912 				 * support machinery doesn't do that, and thus neither does
1913 				 * this code.
1914 				 */
1915 
1916 				/* Perform function lookup */
1917 				finfo = palloc0(sizeof(FmgrInfo));
1918 				fcinfo = palloc0(sizeof(FunctionCallInfoData));
1919 				fmgr_info(typentry->cmp_proc, finfo);
1920 				fmgr_info_set_expr((Node *) node, finfo);
1921 				InitFunctionCallInfoData(*fcinfo, finfo, 2,
1922 										 minmaxexpr->inputcollid, NULL, NULL);
1923 
1924 				scratch.opcode = EEOP_MINMAX;
1925 				/* allocate space to store arguments */
1926 				scratch.d.minmax.values =
1927 					(Datum *) palloc(sizeof(Datum) * nelems);
1928 				scratch.d.minmax.nulls =
1929 					(bool *) palloc(sizeof(bool) * nelems);
1930 				scratch.d.minmax.nelems = nelems;
1931 
1932 				scratch.d.minmax.op = minmaxexpr->op;
1933 				scratch.d.minmax.finfo = finfo;
1934 				scratch.d.minmax.fcinfo_data = fcinfo;
1935 
1936 				/* evaluate expressions into minmax->values/nulls */
1937 				off = 0;
1938 				foreach(lc, minmaxexpr->args)
1939 				{
1940 					Expr	   *e = (Expr *) lfirst(lc);
1941 
1942 					ExecInitExprRec(e, state,
1943 									&scratch.d.minmax.values[off],
1944 									&scratch.d.minmax.nulls[off]);
1945 					off++;
1946 				}
1947 
1948 				/* and push the final comparison */
1949 				ExprEvalPushStep(state, &scratch);
1950 				break;
1951 			}
1952 
1953 		case T_SQLValueFunction:
1954 			{
1955 				SQLValueFunction *svf = (SQLValueFunction *) node;
1956 
1957 				scratch.opcode = EEOP_SQLVALUEFUNCTION;
1958 				scratch.d.sqlvaluefunction.svf = svf;
1959 
1960 				ExprEvalPushStep(state, &scratch);
1961 				break;
1962 			}
1963 
1964 		case T_XmlExpr:
1965 			{
1966 				XmlExpr    *xexpr = (XmlExpr *) node;
1967 				int			nnamed = list_length(xexpr->named_args);
1968 				int			nargs = list_length(xexpr->args);
1969 				int			off;
1970 				ListCell   *arg;
1971 
1972 				scratch.opcode = EEOP_XMLEXPR;
1973 				scratch.d.xmlexpr.xexpr = xexpr;
1974 
1975 				/* allocate space for storing all the arguments */
1976 				if (nnamed)
1977 				{
1978 					scratch.d.xmlexpr.named_argvalue =
1979 						(Datum *) palloc(sizeof(Datum) * nnamed);
1980 					scratch.d.xmlexpr.named_argnull =
1981 						(bool *) palloc(sizeof(bool) * nnamed);
1982 				}
1983 				else
1984 				{
1985 					scratch.d.xmlexpr.named_argvalue = NULL;
1986 					scratch.d.xmlexpr.named_argnull = NULL;
1987 				}
1988 
1989 				if (nargs)
1990 				{
1991 					scratch.d.xmlexpr.argvalue =
1992 						(Datum *) palloc(sizeof(Datum) * nargs);
1993 					scratch.d.xmlexpr.argnull =
1994 						(bool *) palloc(sizeof(bool) * nargs);
1995 				}
1996 				else
1997 				{
1998 					scratch.d.xmlexpr.argvalue = NULL;
1999 					scratch.d.xmlexpr.argnull = NULL;
2000 				}
2001 
2002 				/* prepare argument execution */
2003 				off = 0;
2004 				foreach(arg, xexpr->named_args)
2005 				{
2006 					Expr	   *e = (Expr *) lfirst(arg);
2007 
2008 					ExecInitExprRec(e, state,
2009 									&scratch.d.xmlexpr.named_argvalue[off],
2010 									&scratch.d.xmlexpr.named_argnull[off]);
2011 					off++;
2012 				}
2013 
2014 				off = 0;
2015 				foreach(arg, xexpr->args)
2016 				{
2017 					Expr	   *e = (Expr *) lfirst(arg);
2018 
2019 					ExecInitExprRec(e, state,
2020 									&scratch.d.xmlexpr.argvalue[off],
2021 									&scratch.d.xmlexpr.argnull[off]);
2022 					off++;
2023 				}
2024 
2025 				/* and evaluate the actual XML expression */
2026 				ExprEvalPushStep(state, &scratch);
2027 				break;
2028 			}
2029 
2030 		case T_NullTest:
2031 			{
2032 				NullTest   *ntest = (NullTest *) node;
2033 
2034 				if (ntest->nulltesttype == IS_NULL)
2035 				{
2036 					if (ntest->argisrow)
2037 						scratch.opcode = EEOP_NULLTEST_ROWISNULL;
2038 					else
2039 						scratch.opcode = EEOP_NULLTEST_ISNULL;
2040 				}
2041 				else if (ntest->nulltesttype == IS_NOT_NULL)
2042 				{
2043 					if (ntest->argisrow)
2044 						scratch.opcode = EEOP_NULLTEST_ROWISNOTNULL;
2045 					else
2046 						scratch.opcode = EEOP_NULLTEST_ISNOTNULL;
2047 				}
2048 				else
2049 				{
2050 					elog(ERROR, "unrecognized nulltesttype: %d",
2051 						 (int) ntest->nulltesttype);
2052 				}
2053 				/* initialize cache in case it's a row test */
2054 				scratch.d.nulltest_row.rowcache.cacheptr = NULL;
2055 
2056 				/* first evaluate argument into result variable */
2057 				ExecInitExprRec(ntest->arg, state,
2058 								resv, resnull);
2059 
2060 				/* then push the test of that argument */
2061 				ExprEvalPushStep(state, &scratch);
2062 				break;
2063 			}
2064 
2065 		case T_BooleanTest:
2066 			{
2067 				BooleanTest *btest = (BooleanTest *) node;
2068 
2069 				/*
2070 				 * Evaluate argument, directly into result datum.  That's ok,
2071 				 * because resv/resnull is definitely not used anywhere else,
2072 				 * and will get overwritten by the below EEOP_BOOLTEST_IS_*
2073 				 * step.
2074 				 */
2075 				ExecInitExprRec(btest->arg, state, resv, resnull);
2076 
2077 				switch (btest->booltesttype)
2078 				{
2079 					case IS_TRUE:
2080 						scratch.opcode = EEOP_BOOLTEST_IS_TRUE;
2081 						break;
2082 					case IS_NOT_TRUE:
2083 						scratch.opcode = EEOP_BOOLTEST_IS_NOT_TRUE;
2084 						break;
2085 					case IS_FALSE:
2086 						scratch.opcode = EEOP_BOOLTEST_IS_FALSE;
2087 						break;
2088 					case IS_NOT_FALSE:
2089 						scratch.opcode = EEOP_BOOLTEST_IS_NOT_FALSE;
2090 						break;
2091 					case IS_UNKNOWN:
2092 						/* Same as scalar IS NULL test */
2093 						scratch.opcode = EEOP_NULLTEST_ISNULL;
2094 						break;
2095 					case IS_NOT_UNKNOWN:
2096 						/* Same as scalar IS NOT NULL test */
2097 						scratch.opcode = EEOP_NULLTEST_ISNOTNULL;
2098 						break;
2099 					default:
2100 						elog(ERROR, "unrecognized booltesttype: %d",
2101 							 (int) btest->booltesttype);
2102 				}
2103 
2104 				ExprEvalPushStep(state, &scratch);
2105 				break;
2106 			}
2107 
2108 		case T_CoerceToDomain:
2109 			{
2110 				CoerceToDomain *ctest = (CoerceToDomain *) node;
2111 
2112 				ExecInitCoerceToDomain(&scratch, ctest, state,
2113 									   resv, resnull);
2114 				break;
2115 			}
2116 
2117 		case T_CoerceToDomainValue:
2118 			{
2119 				/*
2120 				 * Read from location identified by innermost_domainval.  Note
2121 				 * that innermost_domainval could be NULL, if we're compiling
2122 				 * a standalone domain check rather than one embedded in a
2123 				 * larger expression.  In that case we must read from
2124 				 * econtext->domainValue_datum.  We'll take care of that
2125 				 * scenario at runtime.
2126 				 */
2127 				scratch.opcode = EEOP_DOMAIN_TESTVAL;
2128 				/* we share instruction union variant with case testval */
2129 				scratch.d.casetest.value = state->innermost_domainval;
2130 				scratch.d.casetest.isnull = state->innermost_domainnull;
2131 
2132 				ExprEvalPushStep(state, &scratch);
2133 				break;
2134 			}
2135 
2136 		case T_CurrentOfExpr:
2137 			{
2138 				scratch.opcode = EEOP_CURRENTOFEXPR;
2139 				ExprEvalPushStep(state, &scratch);
2140 				break;
2141 			}
2142 
2143 		case T_NextValueExpr:
2144 			{
2145 				NextValueExpr *nve = (NextValueExpr *) node;
2146 
2147 				scratch.opcode = EEOP_NEXTVALUEEXPR;
2148 				scratch.d.nextvalueexpr.seqid = nve->seqid;
2149 				scratch.d.nextvalueexpr.seqtypid = nve->typeId;
2150 
2151 				ExprEvalPushStep(state, &scratch);
2152 				break;
2153 			}
2154 
2155 		default:
2156 			elog(ERROR, "unrecognized node type: %d",
2157 				 (int) nodeTag(node));
2158 			break;
2159 	}
2160 }
2161 
2162 /*
2163  * Add another expression evaluation step to ExprState->steps.
2164  *
2165  * Note that this potentially re-allocates es->steps, therefore no pointer
2166  * into that array may be used while the expression is still being built.
2167  */
2168 void
ExprEvalPushStep(ExprState * es,const ExprEvalStep * s)2169 ExprEvalPushStep(ExprState *es, const ExprEvalStep *s)
2170 {
2171 	if (es->steps_alloc == 0)
2172 	{
2173 		es->steps_alloc = 16;
2174 		es->steps = palloc(sizeof(ExprEvalStep) * es->steps_alloc);
2175 	}
2176 	else if (es->steps_alloc == es->steps_len)
2177 	{
2178 		es->steps_alloc *= 2;
2179 		es->steps = repalloc(es->steps,
2180 							 sizeof(ExprEvalStep) * es->steps_alloc);
2181 	}
2182 
2183 	memcpy(&es->steps[es->steps_len++], s, sizeof(ExprEvalStep));
2184 }
2185 
2186 /*
2187  * Perform setup necessary for the evaluation of a function-like expression,
2188  * appending argument evaluation steps to the steps list in *state, and
2189  * setting up *scratch so it is ready to be pushed.
2190  *
2191  * *scratch is not pushed here, so that callers may override the opcode,
2192  * which is useful for function-like cases like DISTINCT.
2193  */
2194 static void
ExecInitFunc(ExprEvalStep * scratch,Expr * node,List * args,Oid funcid,Oid inputcollid,ExprState * state)2195 ExecInitFunc(ExprEvalStep *scratch, Expr *node, List *args, Oid funcid,
2196 			 Oid inputcollid, ExprState *state)
2197 {
2198 	int			nargs = list_length(args);
2199 	AclResult	aclresult;
2200 	FmgrInfo   *flinfo;
2201 	FunctionCallInfo fcinfo;
2202 	int			argno;
2203 	ListCell   *lc;
2204 
2205 	/* Check permission to call function */
2206 	aclresult = pg_proc_aclcheck(funcid, GetUserId(), ACL_EXECUTE);
2207 	if (aclresult != ACLCHECK_OK)
2208 		aclcheck_error(aclresult, OBJECT_FUNCTION, get_func_name(funcid));
2209 	InvokeFunctionExecuteHook(funcid);
2210 
2211 	/*
2212 	 * Safety check on nargs.  Under normal circumstances this should never
2213 	 * fail, as parser should check sooner.  But possibly it might fail if
2214 	 * server has been compiled with FUNC_MAX_ARGS smaller than some functions
2215 	 * declared in pg_proc?
2216 	 */
2217 	if (nargs > FUNC_MAX_ARGS)
2218 		ereport(ERROR,
2219 				(errcode(ERRCODE_TOO_MANY_ARGUMENTS),
2220 				 errmsg_plural("cannot pass more than %d argument to a function",
2221 							   "cannot pass more than %d arguments to a function",
2222 							   FUNC_MAX_ARGS,
2223 							   FUNC_MAX_ARGS)));
2224 
2225 	/* Allocate function lookup data and parameter workspace for this call */
2226 	scratch->d.func.finfo = palloc0(sizeof(FmgrInfo));
2227 	scratch->d.func.fcinfo_data = palloc0(sizeof(FunctionCallInfoData));
2228 	flinfo = scratch->d.func.finfo;
2229 	fcinfo = scratch->d.func.fcinfo_data;
2230 
2231 	/* Set up the primary fmgr lookup information */
2232 	fmgr_info(funcid, flinfo);
2233 	fmgr_info_set_expr((Node *) node, flinfo);
2234 
2235 	/* Initialize function call parameter structure too */
2236 	InitFunctionCallInfoData(*fcinfo, flinfo,
2237 							 nargs, inputcollid, NULL, NULL);
2238 
2239 	/* Keep extra copies of this info to save an indirection at runtime */
2240 	scratch->d.func.fn_addr = flinfo->fn_addr;
2241 	scratch->d.func.nargs = nargs;
2242 
2243 	/* We only support non-set functions here */
2244 	if (flinfo->fn_retset)
2245 		ereport(ERROR,
2246 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2247 				 errmsg("set-valued function called in context that cannot accept a set"),
2248 				 state->parent ?
2249 				 executor_errposition(state->parent->state,
2250 									  exprLocation((Node *) node)) : 0));
2251 
2252 	/* Build code to evaluate arguments directly into the fcinfo struct */
2253 	argno = 0;
2254 	foreach(lc, args)
2255 	{
2256 		Expr	   *arg = (Expr *) lfirst(lc);
2257 
2258 		if (IsA(arg, Const))
2259 		{
2260 			/*
2261 			 * Don't evaluate const arguments every round; especially
2262 			 * interesting for constants in comparisons.
2263 			 */
2264 			Const	   *con = (Const *) arg;
2265 
2266 			fcinfo->arg[argno] = con->constvalue;
2267 			fcinfo->argnull[argno] = con->constisnull;
2268 		}
2269 		else
2270 		{
2271 			ExecInitExprRec(arg, state,
2272 							&fcinfo->arg[argno], &fcinfo->argnull[argno]);
2273 		}
2274 		argno++;
2275 	}
2276 
2277 	/* Insert appropriate opcode depending on strictness and stats level */
2278 	if (pgstat_track_functions <= flinfo->fn_stats)
2279 	{
2280 		if (flinfo->fn_strict && nargs > 0)
2281 			scratch->opcode = EEOP_FUNCEXPR_STRICT;
2282 		else
2283 			scratch->opcode = EEOP_FUNCEXPR;
2284 	}
2285 	else
2286 	{
2287 		if (flinfo->fn_strict && nargs > 0)
2288 			scratch->opcode = EEOP_FUNCEXPR_STRICT_FUSAGE;
2289 		else
2290 			scratch->opcode = EEOP_FUNCEXPR_FUSAGE;
2291 	}
2292 }
2293 
2294 /*
2295  * Add expression steps deforming the ExprState's inner/outer/scan slots
2296  * as much as required by the expression.
2297  */
2298 static void
ExecInitExprSlots(ExprState * state,Node * node)2299 ExecInitExprSlots(ExprState *state, Node *node)
2300 {
2301 	LastAttnumInfo info = {0, 0, 0};
2302 
2303 	/*
2304 	 * Figure out which attributes we're going to need.
2305 	 */
2306 	get_last_attnums_walker(node, &info);
2307 
2308 	ExecPushExprSlots(state, &info);
2309 }
2310 
2311 /*
2312  * Add steps deforming the ExprState's inner/out/scan slots as much as
2313  * indicated by info. This is useful when building an ExprState covering more
2314  * than one expression.
2315  */
2316 static void
ExecPushExprSlots(ExprState * state,LastAttnumInfo * info)2317 ExecPushExprSlots(ExprState *state, LastAttnumInfo *info)
2318 {
2319 	ExprEvalStep scratch = {0};
2320 
2321 	scratch.resvalue = NULL;
2322 	scratch.resnull = NULL;
2323 
2324 	/* Emit steps as needed */
2325 	if (info->last_inner > 0)
2326 	{
2327 		scratch.opcode = EEOP_INNER_FETCHSOME;
2328 		scratch.d.fetch.last_var = info->last_inner;
2329 		scratch.d.fetch.known_desc = NULL;
2330 		ExprEvalPushStep(state, &scratch);
2331 	}
2332 	if (info->last_outer > 0)
2333 	{
2334 		scratch.opcode = EEOP_OUTER_FETCHSOME;
2335 		scratch.d.fetch.last_var = info->last_outer;
2336 		scratch.d.fetch.known_desc = NULL;
2337 		ExprEvalPushStep(state, &scratch);
2338 	}
2339 	if (info->last_scan > 0)
2340 	{
2341 		scratch.opcode = EEOP_SCAN_FETCHSOME;
2342 		scratch.d.fetch.last_var = info->last_scan;
2343 		scratch.d.fetch.known_desc = NULL;
2344 		ExprEvalPushStep(state, &scratch);
2345 	}
2346 }
2347 
2348 /*
2349  * get_last_attnums_walker: expression walker for ExecInitExprSlots
2350  */
2351 static bool
get_last_attnums_walker(Node * node,LastAttnumInfo * info)2352 get_last_attnums_walker(Node *node, LastAttnumInfo *info)
2353 {
2354 	if (node == NULL)
2355 		return false;
2356 	if (IsA(node, Var))
2357 	{
2358 		Var		   *variable = (Var *) node;
2359 		AttrNumber	attnum = variable->varattno;
2360 
2361 		switch (variable->varno)
2362 		{
2363 			case INNER_VAR:
2364 				info->last_inner = Max(info->last_inner, attnum);
2365 				break;
2366 
2367 			case OUTER_VAR:
2368 				info->last_outer = Max(info->last_outer, attnum);
2369 				break;
2370 
2371 				/* INDEX_VAR is handled by default case */
2372 
2373 			default:
2374 				info->last_scan = Max(info->last_scan, attnum);
2375 				break;
2376 		}
2377 		return false;
2378 	}
2379 
2380 	/*
2381 	 * Don't examine the arguments or filters of Aggrefs or WindowFuncs,
2382 	 * because those do not represent expressions to be evaluated within the
2383 	 * calling expression's econtext.  GroupingFunc arguments are never
2384 	 * evaluated at all.
2385 	 */
2386 	if (IsA(node, Aggref))
2387 		return false;
2388 	if (IsA(node, WindowFunc))
2389 		return false;
2390 	if (IsA(node, GroupingFunc))
2391 		return false;
2392 	return expression_tree_walker(node, get_last_attnums_walker,
2393 								  (void *) info);
2394 }
2395 
2396 /*
2397  * Prepare step for the evaluation of a whole-row variable.
2398  * The caller still has to push the step.
2399  */
2400 static void
ExecInitWholeRowVar(ExprEvalStep * scratch,Var * variable,ExprState * state)2401 ExecInitWholeRowVar(ExprEvalStep *scratch, Var *variable, ExprState *state)
2402 {
2403 	PlanState  *parent = state->parent;
2404 
2405 	/* fill in all but the target */
2406 	scratch->opcode = EEOP_WHOLEROW;
2407 	scratch->d.wholerow.var = variable;
2408 	scratch->d.wholerow.first = true;
2409 	scratch->d.wholerow.slow = false;
2410 	scratch->d.wholerow.tupdesc = NULL; /* filled at runtime */
2411 	scratch->d.wholerow.junkFilter = NULL;
2412 
2413 	/*
2414 	 * If the input tuple came from a subquery, it might contain "resjunk"
2415 	 * columns (such as GROUP BY or ORDER BY columns), which we don't want to
2416 	 * keep in the whole-row result.  We can get rid of such columns by
2417 	 * passing the tuple through a JunkFilter --- but to make one, we have to
2418 	 * lay our hands on the subquery's targetlist.  Fortunately, there are not
2419 	 * very many cases where this can happen, and we can identify all of them
2420 	 * by examining our parent PlanState.  We assume this is not an issue in
2421 	 * standalone expressions that don't have parent plans.  (Whole-row Vars
2422 	 * can occur in such expressions, but they will always be referencing
2423 	 * table rows.)
2424 	 */
2425 	if (parent)
2426 	{
2427 		PlanState  *subplan = NULL;
2428 
2429 		switch (nodeTag(parent))
2430 		{
2431 			case T_SubqueryScanState:
2432 				subplan = ((SubqueryScanState *) parent)->subplan;
2433 				break;
2434 			case T_CteScanState:
2435 				subplan = ((CteScanState *) parent)->cteplanstate;
2436 				break;
2437 			default:
2438 				break;
2439 		}
2440 
2441 		if (subplan)
2442 		{
2443 			bool		junk_filter_needed = false;
2444 			ListCell   *tlist;
2445 
2446 			/* Detect whether subplan tlist actually has any junk columns */
2447 			foreach(tlist, subplan->plan->targetlist)
2448 			{
2449 				TargetEntry *tle = (TargetEntry *) lfirst(tlist);
2450 
2451 				if (tle->resjunk)
2452 				{
2453 					junk_filter_needed = true;
2454 					break;
2455 				}
2456 			}
2457 
2458 			/* If so, build the junkfilter now */
2459 			if (junk_filter_needed)
2460 			{
2461 				scratch->d.wholerow.junkFilter =
2462 					ExecInitJunkFilter(subplan->plan->targetlist,
2463 									   ExecGetResultType(subplan)->tdhasoid,
2464 									   ExecInitExtraTupleSlot(parent->state, NULL));
2465 			}
2466 		}
2467 	}
2468 }
2469 
2470 /*
2471  * Prepare evaluation of an ArrayRef expression.
2472  */
2473 static void
ExecInitArrayRef(ExprEvalStep * scratch,ArrayRef * aref,ExprState * state,Datum * resv,bool * resnull)2474 ExecInitArrayRef(ExprEvalStep *scratch, ArrayRef *aref,
2475 				 ExprState *state, Datum *resv, bool *resnull)
2476 {
2477 	bool		isAssignment = (aref->refassgnexpr != NULL);
2478 	ArrayRefState *arefstate = palloc0(sizeof(ArrayRefState));
2479 	List	   *adjust_jumps = NIL;
2480 	ListCell   *lc;
2481 	int			i;
2482 
2483 	/* Fill constant fields of ArrayRefState */
2484 	arefstate->isassignment = isAssignment;
2485 	arefstate->refelemtype = aref->refelemtype;
2486 	arefstate->refattrlength = get_typlen(aref->refarraytype);
2487 	get_typlenbyvalalign(aref->refelemtype,
2488 						 &arefstate->refelemlength,
2489 						 &arefstate->refelembyval,
2490 						 &arefstate->refelemalign);
2491 
2492 	/*
2493 	 * Evaluate array input.  It's safe to do so into resv/resnull, because we
2494 	 * won't use that as target for any of the other subexpressions, and it'll
2495 	 * be overwritten by the final EEOP_ARRAYREF_FETCH/ASSIGN step, which is
2496 	 * pushed last.
2497 	 */
2498 	ExecInitExprRec(aref->refexpr, state, resv, resnull);
2499 
2500 	/*
2501 	 * If refexpr yields NULL, and it's a fetch, then result is NULL.  We can
2502 	 * implement this with just JUMP_IF_NULL, since we evaluated the array
2503 	 * into the desired target location.
2504 	 */
2505 	if (!isAssignment)
2506 	{
2507 		scratch->opcode = EEOP_JUMP_IF_NULL;
2508 		scratch->d.jump.jumpdone = -1;	/* adjust later */
2509 		ExprEvalPushStep(state, scratch);
2510 		adjust_jumps = lappend_int(adjust_jumps,
2511 								   state->steps_len - 1);
2512 	}
2513 
2514 	/* Verify subscript list lengths are within limit */
2515 	if (list_length(aref->refupperindexpr) > MAXDIM)
2516 		ereport(ERROR,
2517 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2518 				 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
2519 						list_length(aref->refupperindexpr), MAXDIM)));
2520 
2521 	if (list_length(aref->reflowerindexpr) > MAXDIM)
2522 		ereport(ERROR,
2523 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2524 				 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
2525 						list_length(aref->reflowerindexpr), MAXDIM)));
2526 
2527 	/* Evaluate upper subscripts */
2528 	i = 0;
2529 	foreach(lc, aref->refupperindexpr)
2530 	{
2531 		Expr	   *e = (Expr *) lfirst(lc);
2532 
2533 		/* When slicing, individual subscript bounds can be omitted */
2534 		if (!e)
2535 		{
2536 			arefstate->upperprovided[i] = false;
2537 			i++;
2538 			continue;
2539 		}
2540 
2541 		arefstate->upperprovided[i] = true;
2542 
2543 		/* Each subscript is evaluated into subscriptvalue/subscriptnull */
2544 		ExecInitExprRec(e, state,
2545 						&arefstate->subscriptvalue, &arefstate->subscriptnull);
2546 
2547 		/* ... and then ARRAYREF_SUBSCRIPT saves it into step's workspace */
2548 		scratch->opcode = EEOP_ARRAYREF_SUBSCRIPT;
2549 		scratch->d.arrayref_subscript.state = arefstate;
2550 		scratch->d.arrayref_subscript.off = i;
2551 		scratch->d.arrayref_subscript.isupper = true;
2552 		scratch->d.arrayref_subscript.jumpdone = -1;	/* adjust later */
2553 		ExprEvalPushStep(state, scratch);
2554 		adjust_jumps = lappend_int(adjust_jumps,
2555 								   state->steps_len - 1);
2556 		i++;
2557 	}
2558 	arefstate->numupper = i;
2559 
2560 	/* Evaluate lower subscripts similarly */
2561 	i = 0;
2562 	foreach(lc, aref->reflowerindexpr)
2563 	{
2564 		Expr	   *e = (Expr *) lfirst(lc);
2565 
2566 		/* When slicing, individual subscript bounds can be omitted */
2567 		if (!e)
2568 		{
2569 			arefstate->lowerprovided[i] = false;
2570 			i++;
2571 			continue;
2572 		}
2573 
2574 		arefstate->lowerprovided[i] = true;
2575 
2576 		/* Each subscript is evaluated into subscriptvalue/subscriptnull */
2577 		ExecInitExprRec(e, state,
2578 						&arefstate->subscriptvalue, &arefstate->subscriptnull);
2579 
2580 		/* ... and then ARRAYREF_SUBSCRIPT saves it into step's workspace */
2581 		scratch->opcode = EEOP_ARRAYREF_SUBSCRIPT;
2582 		scratch->d.arrayref_subscript.state = arefstate;
2583 		scratch->d.arrayref_subscript.off = i;
2584 		scratch->d.arrayref_subscript.isupper = false;
2585 		scratch->d.arrayref_subscript.jumpdone = -1;	/* adjust later */
2586 		ExprEvalPushStep(state, scratch);
2587 		adjust_jumps = lappend_int(adjust_jumps,
2588 								   state->steps_len - 1);
2589 		i++;
2590 	}
2591 	arefstate->numlower = i;
2592 
2593 	/* Should be impossible if parser is sane, but check anyway: */
2594 	if (arefstate->numlower != 0 &&
2595 		arefstate->numupper != arefstate->numlower)
2596 		elog(ERROR, "upper and lower index lists are not same length");
2597 
2598 	if (isAssignment)
2599 	{
2600 		Datum	   *save_innermost_caseval;
2601 		bool	   *save_innermost_casenull;
2602 
2603 		/*
2604 		 * We might have a nested-assignment situation, in which the
2605 		 * refassgnexpr is itself a FieldStore or ArrayRef that needs to
2606 		 * obtain and modify the previous value of the array element or slice
2607 		 * being replaced.  If so, we have to extract that value from the
2608 		 * array and pass it down via the CaseTestExpr mechanism.  It's safe
2609 		 * to reuse the CASE mechanism because there cannot be a CASE between
2610 		 * here and where the value would be needed, and an array assignment
2611 		 * can't be within a CASE either.  (So saving and restoring
2612 		 * innermost_caseval is just paranoia, but let's do it anyway.)
2613 		 *
2614 		 * Since fetching the old element might be a nontrivial expense, do it
2615 		 * only if the argument actually needs it.
2616 		 */
2617 		if (isAssignmentIndirectionExpr(aref->refassgnexpr))
2618 		{
2619 			scratch->opcode = EEOP_ARRAYREF_OLD;
2620 			scratch->d.arrayref.state = arefstate;
2621 			ExprEvalPushStep(state, scratch);
2622 		}
2623 
2624 		/* ARRAYREF_OLD puts extracted value into prevvalue/prevnull */
2625 		save_innermost_caseval = state->innermost_caseval;
2626 		save_innermost_casenull = state->innermost_casenull;
2627 		state->innermost_caseval = &arefstate->prevvalue;
2628 		state->innermost_casenull = &arefstate->prevnull;
2629 
2630 		/* evaluate replacement value into replacevalue/replacenull */
2631 		ExecInitExprRec(aref->refassgnexpr, state,
2632 						&arefstate->replacevalue, &arefstate->replacenull);
2633 
2634 		state->innermost_caseval = save_innermost_caseval;
2635 		state->innermost_casenull = save_innermost_casenull;
2636 
2637 		/* and perform the assignment */
2638 		scratch->opcode = EEOP_ARRAYREF_ASSIGN;
2639 		scratch->d.arrayref.state = arefstate;
2640 		ExprEvalPushStep(state, scratch);
2641 	}
2642 	else
2643 	{
2644 		/* array fetch is much simpler */
2645 		scratch->opcode = EEOP_ARRAYREF_FETCH;
2646 		scratch->d.arrayref.state = arefstate;
2647 		ExprEvalPushStep(state, scratch);
2648 	}
2649 
2650 	/* adjust jump targets */
2651 	foreach(lc, adjust_jumps)
2652 	{
2653 		ExprEvalStep *as = &state->steps[lfirst_int(lc)];
2654 
2655 		if (as->opcode == EEOP_ARRAYREF_SUBSCRIPT)
2656 		{
2657 			Assert(as->d.arrayref_subscript.jumpdone == -1);
2658 			as->d.arrayref_subscript.jumpdone = state->steps_len;
2659 		}
2660 		else
2661 		{
2662 			Assert(as->opcode == EEOP_JUMP_IF_NULL);
2663 			Assert(as->d.jump.jumpdone == -1);
2664 			as->d.jump.jumpdone = state->steps_len;
2665 		}
2666 	}
2667 }
2668 
2669 /*
2670  * Helper for preparing ArrayRef expressions for evaluation: is expr a nested
2671  * FieldStore or ArrayRef that needs the old element value passed down?
2672  *
2673  * (We could use this in FieldStore too, but in that case passing the old
2674  * value is so cheap there's no need.)
2675  *
2676  * Note: it might seem that this needs to recurse, but in most cases it does
2677  * not; the CaseTestExpr, if any, will be directly the arg or refexpr of the
2678  * top-level node.  Nested-assignment situations give rise to expression
2679  * trees in which each level of assignment has its own CaseTestExpr, and the
2680  * recursive structure appears within the newvals or refassgnexpr field.
2681  * There is an exception, though: if the array is an array-of-domain, we will
2682  * have a CoerceToDomain as the refassgnexpr, and we need to be able to look
2683  * through that.
2684  */
2685 static bool
isAssignmentIndirectionExpr(Expr * expr)2686 isAssignmentIndirectionExpr(Expr *expr)
2687 {
2688 	if (expr == NULL)
2689 		return false;			/* just paranoia */
2690 	if (IsA(expr, FieldStore))
2691 	{
2692 		FieldStore *fstore = (FieldStore *) expr;
2693 
2694 		if (fstore->arg && IsA(fstore->arg, CaseTestExpr))
2695 			return true;
2696 	}
2697 	else if (IsA(expr, ArrayRef))
2698 	{
2699 		ArrayRef   *arrayRef = (ArrayRef *) expr;
2700 
2701 		if (arrayRef->refexpr && IsA(arrayRef->refexpr, CaseTestExpr))
2702 			return true;
2703 	}
2704 	else if (IsA(expr, CoerceToDomain))
2705 	{
2706 		CoerceToDomain *cd = (CoerceToDomain *) expr;
2707 
2708 		return isAssignmentIndirectionExpr(cd->arg);
2709 	}
2710 	return false;
2711 }
2712 
2713 /*
2714  * Prepare evaluation of a CoerceToDomain expression.
2715  */
2716 static void
ExecInitCoerceToDomain(ExprEvalStep * scratch,CoerceToDomain * ctest,ExprState * state,Datum * resv,bool * resnull)2717 ExecInitCoerceToDomain(ExprEvalStep *scratch, CoerceToDomain *ctest,
2718 					   ExprState *state, Datum *resv, bool *resnull)
2719 {
2720 	ExprEvalStep scratch2 = {0};
2721 	DomainConstraintRef *constraint_ref;
2722 	Datum	   *domainval = NULL;
2723 	bool	   *domainnull = NULL;
2724 	Datum	   *save_innermost_domainval;
2725 	bool	   *save_innermost_domainnull;
2726 	ListCell   *l;
2727 
2728 	scratch->d.domaincheck.resulttype = ctest->resulttype;
2729 	/* we'll allocate workspace only if needed */
2730 	scratch->d.domaincheck.checkvalue = NULL;
2731 	scratch->d.domaincheck.checknull = NULL;
2732 
2733 	/*
2734 	 * Evaluate argument - it's fine to directly store it into resv/resnull,
2735 	 * if there's constraint failures there'll be errors, otherwise it's what
2736 	 * needs to be returned.
2737 	 */
2738 	ExecInitExprRec(ctest->arg, state, resv, resnull);
2739 
2740 	/*
2741 	 * Note: if the argument is of varlena type, it could be a R/W expanded
2742 	 * object.  We want to return the R/W pointer as the final result, but we
2743 	 * have to pass a R/O pointer as the value to be tested by any functions
2744 	 * in check expressions.  We don't bother to emit a MAKE_READONLY step
2745 	 * unless there's actually at least one check expression, though.  Until
2746 	 * we've tested that, domainval/domainnull are NULL.
2747 	 */
2748 
2749 	/*
2750 	 * Collect the constraints associated with the domain.
2751 	 *
2752 	 * Note: before PG v10 we'd recheck the set of constraints during each
2753 	 * evaluation of the expression.  Now we bake them into the ExprState
2754 	 * during executor initialization.  That means we don't need typcache.c to
2755 	 * provide compiled exprs.
2756 	 */
2757 	constraint_ref = (DomainConstraintRef *)
2758 		palloc(sizeof(DomainConstraintRef));
2759 	InitDomainConstraintRef(ctest->resulttype,
2760 							constraint_ref,
2761 							CurrentMemoryContext,
2762 							false);
2763 
2764 	/*
2765 	 * Compile code to check each domain constraint.  NOTNULL constraints can
2766 	 * just be applied on the resv/resnull value, but for CHECK constraints we
2767 	 * need more pushups.
2768 	 */
2769 	foreach(l, constraint_ref->constraints)
2770 	{
2771 		DomainConstraintState *con = (DomainConstraintState *) lfirst(l);
2772 
2773 		scratch->d.domaincheck.constraintname = con->name;
2774 
2775 		switch (con->constrainttype)
2776 		{
2777 			case DOM_CONSTRAINT_NOTNULL:
2778 				scratch->opcode = EEOP_DOMAIN_NOTNULL;
2779 				ExprEvalPushStep(state, scratch);
2780 				break;
2781 			case DOM_CONSTRAINT_CHECK:
2782 				/* Allocate workspace for CHECK output if we didn't yet */
2783 				if (scratch->d.domaincheck.checkvalue == NULL)
2784 				{
2785 					scratch->d.domaincheck.checkvalue =
2786 						(Datum *) palloc(sizeof(Datum));
2787 					scratch->d.domaincheck.checknull =
2788 						(bool *) palloc(sizeof(bool));
2789 				}
2790 
2791 				/*
2792 				 * If first time through, determine where CoerceToDomainValue
2793 				 * nodes should read from.
2794 				 */
2795 				if (domainval == NULL)
2796 				{
2797 					/*
2798 					 * Since value might be read multiple times, force to R/O
2799 					 * - but only if it could be an expanded datum.
2800 					 */
2801 					if (get_typlen(ctest->resulttype) == -1)
2802 					{
2803 						/* Yes, so make output workspace for MAKE_READONLY */
2804 						domainval = (Datum *) palloc(sizeof(Datum));
2805 						domainnull = (bool *) palloc(sizeof(bool));
2806 
2807 						/* Emit MAKE_READONLY */
2808 						scratch2.opcode = EEOP_MAKE_READONLY;
2809 						scratch2.resvalue = domainval;
2810 						scratch2.resnull = domainnull;
2811 						scratch2.d.make_readonly.value = resv;
2812 						scratch2.d.make_readonly.isnull = resnull;
2813 						ExprEvalPushStep(state, &scratch2);
2814 					}
2815 					else
2816 					{
2817 						/* No, so it's fine to read from resv/resnull */
2818 						domainval = resv;
2819 						domainnull = resnull;
2820 					}
2821 				}
2822 
2823 				/*
2824 				 * Set up value to be returned by CoerceToDomainValue nodes.
2825 				 * We must save and restore innermost_domainval/null fields,
2826 				 * in case this node is itself within a check expression for
2827 				 * another domain.
2828 				 */
2829 				save_innermost_domainval = state->innermost_domainval;
2830 				save_innermost_domainnull = state->innermost_domainnull;
2831 				state->innermost_domainval = domainval;
2832 				state->innermost_domainnull = domainnull;
2833 
2834 				/* evaluate check expression value */
2835 				ExecInitExprRec(con->check_expr, state,
2836 								scratch->d.domaincheck.checkvalue,
2837 								scratch->d.domaincheck.checknull);
2838 
2839 				state->innermost_domainval = save_innermost_domainval;
2840 				state->innermost_domainnull = save_innermost_domainnull;
2841 
2842 				/* now test result */
2843 				scratch->opcode = EEOP_DOMAIN_CHECK;
2844 				ExprEvalPushStep(state, scratch);
2845 
2846 				break;
2847 			default:
2848 				elog(ERROR, "unrecognized constraint type: %d",
2849 					 (int) con->constrainttype);
2850 				break;
2851 		}
2852 	}
2853 }
2854 
2855 /*
2856  * Build transition/combine function invocations for all aggregate transition
2857  * / combination function invocations in a grouping sets phase. This has to
2858  * invoke all sort based transitions in a phase (if doSort is true), all hash
2859  * based transitions (if doHash is true), or both (both true).
2860  *
2861  * The resulting expression will, for each set of transition values, first
2862  * check for filters, evaluate aggregate input, check that that input is not
2863  * NULL for a strict transition function, and then finally invoke the
2864  * transition for each of the concurrently computed grouping sets.
2865  */
2866 ExprState *
ExecBuildAggTrans(AggState * aggstate,AggStatePerPhase phase,bool doSort,bool doHash)2867 ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase,
2868 				  bool doSort, bool doHash)
2869 {
2870 	ExprState  *state = makeNode(ExprState);
2871 	PlanState  *parent = &aggstate->ss.ps;
2872 	ExprEvalStep scratch = {0};
2873 	int			transno = 0;
2874 	int			setoff = 0;
2875 	bool		isCombine = DO_AGGSPLIT_COMBINE(aggstate->aggsplit);
2876 	LastAttnumInfo deform = {0, 0, 0};
2877 
2878 	state->expr = (Expr *) aggstate;
2879 	state->parent = parent;
2880 
2881 	scratch.resvalue = &state->resvalue;
2882 	scratch.resnull = &state->resnull;
2883 
2884 	/*
2885 	 * First figure out which slots, and how many columns from each, we're
2886 	 * going to need.
2887 	 */
2888 	for (transno = 0; transno < aggstate->numtrans; transno++)
2889 	{
2890 		AggStatePerTrans pertrans = &aggstate->pertrans[transno];
2891 
2892 		get_last_attnums_walker((Node *) pertrans->aggref->aggdirectargs,
2893 								&deform);
2894 		get_last_attnums_walker((Node *) pertrans->aggref->args,
2895 								&deform);
2896 		get_last_attnums_walker((Node *) pertrans->aggref->aggorder,
2897 								&deform);
2898 		get_last_attnums_walker((Node *) pertrans->aggref->aggdistinct,
2899 								&deform);
2900 		get_last_attnums_walker((Node *) pertrans->aggref->aggfilter,
2901 								&deform);
2902 	}
2903 	ExecPushExprSlots(state, &deform);
2904 
2905 	/*
2906 	 * Emit instructions for each transition value / grouping set combination.
2907 	 */
2908 	for (transno = 0; transno < aggstate->numtrans; transno++)
2909 	{
2910 		AggStatePerTrans pertrans = &aggstate->pertrans[transno];
2911 		int			argno;
2912 		int			setno;
2913 		FunctionCallInfo trans_fcinfo = &pertrans->transfn_fcinfo;
2914 		ListCell   *arg;
2915 		ListCell   *bail;
2916 		List	   *adjust_bailout = NIL;
2917 		bool	   *strictnulls = NULL;
2918 
2919 		/*
2920 		 * If filter present, emit. Do so before evaluating the input, to
2921 		 * avoid potentially unneeded computations, or even worse, unintended
2922 		 * side-effects.  When combining, all the necessary filtering has
2923 		 * already been done.
2924 		 */
2925 		if (pertrans->aggref->aggfilter && !isCombine)
2926 		{
2927 			/* evaluate filter expression */
2928 			ExecInitExprRec(pertrans->aggref->aggfilter, state,
2929 							&state->resvalue, &state->resnull);
2930 			/* and jump out if false */
2931 			scratch.opcode = EEOP_JUMP_IF_NOT_TRUE;
2932 			scratch.d.jump.jumpdone = -1;	/* adjust later */
2933 			ExprEvalPushStep(state, &scratch);
2934 			adjust_bailout = lappend_int(adjust_bailout,
2935 										 state->steps_len - 1);
2936 		}
2937 
2938 		/*
2939 		 * Evaluate arguments to aggregate/combine function.
2940 		 */
2941 		argno = 0;
2942 		if (isCombine)
2943 		{
2944 			/*
2945 			 * Combining two aggregate transition values. Instead of directly
2946 			 * coming from a tuple the input is a, potentially deserialized,
2947 			 * transition value.
2948 			 */
2949 			TargetEntry *source_tle;
2950 
2951 			Assert(pertrans->numSortCols == 0);
2952 			Assert(list_length(pertrans->aggref->args) == 1);
2953 
2954 			strictnulls = trans_fcinfo->argnull + 1;
2955 			source_tle = (TargetEntry *) linitial(pertrans->aggref->args);
2956 
2957 			/*
2958 			 * deserialfn_oid will be set if we must deserialize the input
2959 			 * state before calling the combine function.
2960 			 */
2961 			if (!OidIsValid(pertrans->deserialfn_oid))
2962 			{
2963 				/*
2964 				 * Start from 1, since the 0th arg will be the transition
2965 				 * value
2966 				 */
2967 				ExecInitExprRec(source_tle->expr, state,
2968 								&trans_fcinfo->arg[argno + 1],
2969 								&trans_fcinfo->argnull[argno + 1]);
2970 			}
2971 			else
2972 			{
2973 				FunctionCallInfo ds_fcinfo = &pertrans->deserialfn_fcinfo;
2974 
2975 				/* evaluate argument */
2976 				ExecInitExprRec(source_tle->expr, state,
2977 								&ds_fcinfo->arg[0],
2978 								&ds_fcinfo->argnull[0]);
2979 
2980 				/* Dummy second argument for type-safety reasons */
2981 				ds_fcinfo->arg[1] = PointerGetDatum(NULL);
2982 				ds_fcinfo->argnull[1] = false;
2983 
2984 				/*
2985 				 * Don't call a strict deserialization function with NULL
2986 				 * input
2987 				 */
2988 				if (pertrans->deserialfn.fn_strict)
2989 					scratch.opcode = EEOP_AGG_STRICT_DESERIALIZE;
2990 				else
2991 					scratch.opcode = EEOP_AGG_DESERIALIZE;
2992 
2993 				scratch.d.agg_deserialize.aggstate = aggstate;
2994 				scratch.d.agg_deserialize.fcinfo_data = ds_fcinfo;
2995 				scratch.d.agg_deserialize.jumpnull = -1;	/* adjust later */
2996 				scratch.resvalue = &trans_fcinfo->arg[argno + 1];
2997 				scratch.resnull = &trans_fcinfo->argnull[argno + 1];
2998 
2999 				ExprEvalPushStep(state, &scratch);
3000 				/* don't add an adjustment unless the function is strict */
3001 				if (pertrans->deserialfn.fn_strict)
3002 					adjust_bailout = lappend_int(adjust_bailout,
3003 												 state->steps_len - 1);
3004 
3005 				/* restore normal settings of scratch fields */
3006 				scratch.resvalue = &state->resvalue;
3007 				scratch.resnull = &state->resnull;
3008 			}
3009 			argno++;
3010 		}
3011 		else if (pertrans->numSortCols == 0)
3012 		{
3013 			/*
3014 			 * Normal transition function without ORDER BY / DISTINCT.
3015 			 */
3016 			strictnulls = trans_fcinfo->argnull + 1;
3017 
3018 			foreach(arg, pertrans->aggref->args)
3019 			{
3020 				TargetEntry *source_tle = (TargetEntry *) lfirst(arg);
3021 
3022 				/*
3023 				 * Start from 1, since the 0th arg will be the transition
3024 				 * value
3025 				 */
3026 				ExecInitExprRec(source_tle->expr, state,
3027 								&trans_fcinfo->arg[argno + 1],
3028 								&trans_fcinfo->argnull[argno + 1]);
3029 				argno++;
3030 			}
3031 		}
3032 		else if (pertrans->numInputs == 1)
3033 		{
3034 			/*
3035 			 * DISTINCT and/or ORDER BY case, with a single column sorted on.
3036 			 */
3037 			TargetEntry *source_tle =
3038 			(TargetEntry *) linitial(pertrans->aggref->args);
3039 
3040 			Assert(list_length(pertrans->aggref->args) == 1);
3041 
3042 			ExecInitExprRec(source_tle->expr, state,
3043 							&state->resvalue,
3044 							&state->resnull);
3045 			strictnulls = &state->resnull;
3046 			argno++;
3047 		}
3048 		else
3049 		{
3050 			/*
3051 			 * DISTINCT and/or ORDER BY case, with multiple columns sorted on.
3052 			 */
3053 			Datum	   *values = pertrans->sortslot->tts_values;
3054 			bool	   *nulls = pertrans->sortslot->tts_isnull;
3055 
3056 			strictnulls = nulls;
3057 
3058 			foreach(arg, pertrans->aggref->args)
3059 			{
3060 				TargetEntry *source_tle = (TargetEntry *) lfirst(arg);
3061 
3062 				ExecInitExprRec(source_tle->expr, state,
3063 								&values[argno], &nulls[argno]);
3064 				argno++;
3065 			}
3066 		}
3067 		Assert(pertrans->numInputs == argno);
3068 
3069 		/*
3070 		 * For a strict transfn, nothing happens when there's a NULL input; we
3071 		 * just keep the prior transValue. This is true for both plain and
3072 		 * sorted/distinct aggregates.
3073 		 */
3074 		if (trans_fcinfo->flinfo->fn_strict && pertrans->numTransInputs > 0)
3075 		{
3076 			scratch.opcode = EEOP_AGG_STRICT_INPUT_CHECK;
3077 			scratch.d.agg_strict_input_check.nulls = strictnulls;
3078 			scratch.d.agg_strict_input_check.jumpnull = -1; /* adjust later */
3079 			scratch.d.agg_strict_input_check.nargs = pertrans->numTransInputs;
3080 			ExprEvalPushStep(state, &scratch);
3081 			adjust_bailout = lappend_int(adjust_bailout,
3082 										 state->steps_len - 1);
3083 		}
3084 
3085 		/*
3086 		 * Call transition function (once for each concurrently evaluated
3087 		 * grouping set). Do so for both sort and hash based computations, as
3088 		 * applicable.
3089 		 */
3090 		setoff = 0;
3091 		if (doSort)
3092 		{
3093 			int			processGroupingSets = Max(phase->numsets, 1);
3094 
3095 			for (setno = 0; setno < processGroupingSets; setno++)
3096 			{
3097 				ExecBuildAggTransCall(state, aggstate, &scratch, trans_fcinfo,
3098 									  pertrans, transno, setno, setoff, false);
3099 				setoff++;
3100 			}
3101 		}
3102 
3103 		if (doHash)
3104 		{
3105 			int			numHashes = aggstate->num_hashes;
3106 
3107 			/* in MIXED mode, there'll be preceding transition values */
3108 			if (aggstate->aggstrategy != AGG_HASHED)
3109 				setoff = aggstate->maxsets;
3110 			else
3111 				setoff = 0;
3112 
3113 			for (setno = 0; setno < numHashes; setno++)
3114 			{
3115 				ExecBuildAggTransCall(state, aggstate, &scratch, trans_fcinfo,
3116 									  pertrans, transno, setno, setoff, true);
3117 				setoff++;
3118 			}
3119 		}
3120 
3121 		/* adjust early bail out jump target(s) */
3122 		foreach(bail, adjust_bailout)
3123 		{
3124 			ExprEvalStep *as = &state->steps[lfirst_int(bail)];
3125 
3126 			if (as->opcode == EEOP_JUMP_IF_NOT_TRUE)
3127 			{
3128 				Assert(as->d.jump.jumpdone == -1);
3129 				as->d.jump.jumpdone = state->steps_len;
3130 			}
3131 			else if (as->opcode == EEOP_AGG_STRICT_INPUT_CHECK)
3132 			{
3133 				Assert(as->d.agg_strict_input_check.jumpnull == -1);
3134 				as->d.agg_strict_input_check.jumpnull = state->steps_len;
3135 			}
3136 			else if (as->opcode == EEOP_AGG_STRICT_DESERIALIZE)
3137 			{
3138 				Assert(as->d.agg_deserialize.jumpnull == -1);
3139 				as->d.agg_deserialize.jumpnull = state->steps_len;
3140 			}
3141 		}
3142 	}
3143 
3144 	scratch.resvalue = NULL;
3145 	scratch.resnull = NULL;
3146 	scratch.opcode = EEOP_DONE;
3147 	ExprEvalPushStep(state, &scratch);
3148 
3149 	ExecReadyExpr(state);
3150 
3151 	return state;
3152 }
3153 
3154 /*
3155  * Build transition/combine function invocation for a single transition
3156  * value. This is separated from ExecBuildAggTrans() because there are
3157  * multiple callsites (hash and sort in some grouping set cases).
3158  */
3159 static void
ExecBuildAggTransCall(ExprState * state,AggState * aggstate,ExprEvalStep * scratch,FunctionCallInfo fcinfo,AggStatePerTrans pertrans,int transno,int setno,int setoff,bool ishash)3160 ExecBuildAggTransCall(ExprState *state, AggState *aggstate,
3161 					  ExprEvalStep *scratch,
3162 					  FunctionCallInfo fcinfo, AggStatePerTrans pertrans,
3163 					  int transno, int setno, int setoff, bool ishash)
3164 {
3165 	int			adjust_init_jumpnull = -1;
3166 	int			adjust_strict_jumpnull = -1;
3167 	ExprContext *aggcontext;
3168 
3169 	if (ishash)
3170 		aggcontext = aggstate->hashcontext;
3171 	else
3172 		aggcontext = aggstate->aggcontexts[setno];
3173 
3174 	/*
3175 	 * If the initial value for the transition state doesn't exist in the
3176 	 * pg_aggregate table then we will let the first non-NULL value returned
3177 	 * from the outer procNode become the initial value. (This is useful for
3178 	 * aggregates like max() and min().) The noTransValue flag signals that we
3179 	 * still need to do this.
3180 	 */
3181 	if (pertrans->numSortCols == 0 &&
3182 		fcinfo->flinfo->fn_strict &&
3183 		pertrans->initValueIsNull)
3184 	{
3185 		scratch->opcode = EEOP_AGG_INIT_TRANS;
3186 		scratch->d.agg_init_trans.aggstate = aggstate;
3187 		scratch->d.agg_init_trans.pertrans = pertrans;
3188 		scratch->d.agg_init_trans.setno = setno;
3189 		scratch->d.agg_init_trans.setoff = setoff;
3190 		scratch->d.agg_init_trans.transno = transno;
3191 		scratch->d.agg_init_trans.aggcontext = aggcontext;
3192 		scratch->d.agg_init_trans.jumpnull = -1;	/* adjust later */
3193 		ExprEvalPushStep(state, scratch);
3194 
3195 		/* see comment about jumping out below */
3196 		adjust_init_jumpnull = state->steps_len - 1;
3197 	}
3198 
3199 	if (pertrans->numSortCols == 0 &&
3200 		fcinfo->flinfo->fn_strict)
3201 	{
3202 		scratch->opcode = EEOP_AGG_STRICT_TRANS_CHECK;
3203 		scratch->d.agg_strict_trans_check.aggstate = aggstate;
3204 		scratch->d.agg_strict_trans_check.setno = setno;
3205 		scratch->d.agg_strict_trans_check.setoff = setoff;
3206 		scratch->d.agg_strict_trans_check.transno = transno;
3207 		scratch->d.agg_strict_trans_check.jumpnull = -1;	/* adjust later */
3208 		ExprEvalPushStep(state, scratch);
3209 
3210 		/*
3211 		 * Note, we don't push into adjust_bailout here - those jump to the
3212 		 * end of all transition value computations. Here a single transition
3213 		 * value is NULL, so just skip processing the individual value.
3214 		 */
3215 		adjust_strict_jumpnull = state->steps_len - 1;
3216 	}
3217 
3218 	/* invoke appropriate transition implementation */
3219 	if (pertrans->numSortCols == 0 && pertrans->transtypeByVal)
3220 		scratch->opcode = EEOP_AGG_PLAIN_TRANS_BYVAL;
3221 	else if (pertrans->numSortCols == 0)
3222 		scratch->opcode = EEOP_AGG_PLAIN_TRANS;
3223 	else if (pertrans->numInputs == 1)
3224 		scratch->opcode = EEOP_AGG_ORDERED_TRANS_DATUM;
3225 	else
3226 		scratch->opcode = EEOP_AGG_ORDERED_TRANS_TUPLE;
3227 
3228 	scratch->d.agg_trans.aggstate = aggstate;
3229 	scratch->d.agg_trans.pertrans = pertrans;
3230 	scratch->d.agg_trans.setno = setno;
3231 	scratch->d.agg_trans.setoff = setoff;
3232 	scratch->d.agg_trans.transno = transno;
3233 	scratch->d.agg_trans.aggcontext = aggcontext;
3234 	ExprEvalPushStep(state, scratch);
3235 
3236 	/* adjust jumps so they jump till after transition invocation */
3237 	if (adjust_init_jumpnull != -1)
3238 	{
3239 		ExprEvalStep *as = &state->steps[adjust_init_jumpnull];
3240 
3241 		Assert(as->d.agg_init_trans.jumpnull == -1);
3242 		as->d.agg_init_trans.jumpnull = state->steps_len;
3243 	}
3244 	if (adjust_strict_jumpnull != -1)
3245 	{
3246 		ExprEvalStep *as = &state->steps[adjust_strict_jumpnull];
3247 
3248 		Assert(as->d.agg_strict_trans_check.jumpnull == -1);
3249 		as->d.agg_strict_trans_check.jumpnull = state->steps_len;
3250 	}
3251 }
3252 
3253 /*
3254  * Build equality expression that can be evaluated using ExecQual(), returning
3255  * true if the expression context's inner/outer tuple are NOT DISTINCT. I.e
3256  * two nulls match, a null and a not-null don't match.
3257  *
3258  * desc: tuple descriptor of the to-be-compared tuples
3259  * numCols: the number of attributes to be examined
3260  * keyColIdx: array of attribute column numbers
3261  * eqFunctions: array of function oids of the equality functions to use
3262  * parent: parent executor node
3263  */
3264 ExprState *
ExecBuildGroupingEqual(TupleDesc ldesc,TupleDesc rdesc,int numCols,AttrNumber * keyColIdx,Oid * eqfunctions,PlanState * parent)3265 ExecBuildGroupingEqual(TupleDesc ldesc, TupleDesc rdesc,
3266 					   int numCols,
3267 					   AttrNumber *keyColIdx,
3268 					   Oid *eqfunctions,
3269 					   PlanState *parent)
3270 {
3271 	ExprState  *state = makeNode(ExprState);
3272 	ExprEvalStep scratch = {0};
3273 	int			natt;
3274 	int			maxatt = -1;
3275 	List	   *adjust_jumps = NIL;
3276 	ListCell   *lc;
3277 
3278 	/*
3279 	 * When no columns are actually compared, the result's always true. See
3280 	 * special case in ExecQual().
3281 	 */
3282 	if (numCols == 0)
3283 		return NULL;
3284 
3285 	state->expr = NULL;
3286 	state->flags = EEO_FLAG_IS_QUAL;
3287 	state->parent = parent;
3288 
3289 	scratch.resvalue = &state->resvalue;
3290 	scratch.resnull = &state->resnull;
3291 
3292 	/* compute max needed attribute */
3293 	for (natt = 0; natt < numCols; natt++)
3294 	{
3295 		int			attno = keyColIdx[natt];
3296 
3297 		if (attno > maxatt)
3298 			maxatt = attno;
3299 	}
3300 	Assert(maxatt >= 0);
3301 
3302 	/* push deform steps */
3303 	scratch.opcode = EEOP_INNER_FETCHSOME;
3304 	scratch.d.fetch.last_var = maxatt;
3305 	scratch.d.fetch.known_desc = ldesc;
3306 	ExprEvalPushStep(state, &scratch);
3307 
3308 	scratch.opcode = EEOP_OUTER_FETCHSOME;
3309 	scratch.d.fetch.last_var = maxatt;
3310 	scratch.d.fetch.known_desc = rdesc;
3311 	ExprEvalPushStep(state, &scratch);
3312 
3313 	/*
3314 	 * Start comparing at the last field (least significant sort key). That's
3315 	 * the most likely to be different if we are dealing with sorted input.
3316 	 */
3317 	for (natt = numCols; --natt >= 0;)
3318 	{
3319 		int			attno = keyColIdx[natt];
3320 		Form_pg_attribute latt = TupleDescAttr(ldesc, attno - 1);
3321 		Form_pg_attribute ratt = TupleDescAttr(rdesc, attno - 1);
3322 		Oid			foid = eqfunctions[natt];
3323 		FmgrInfo   *finfo;
3324 		FunctionCallInfo fcinfo;
3325 		AclResult	aclresult;
3326 
3327 		/* Check permission to call function */
3328 		aclresult = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE);
3329 		if (aclresult != ACLCHECK_OK)
3330 			aclcheck_error(aclresult, OBJECT_FUNCTION, get_func_name(foid));
3331 
3332 		InvokeFunctionExecuteHook(foid);
3333 
3334 		/* Set up the primary fmgr lookup information */
3335 		finfo = palloc0(sizeof(FmgrInfo));
3336 		fcinfo = palloc0(sizeof(FunctionCallInfoData));
3337 		fmgr_info(foid, finfo);
3338 		fmgr_info_set_expr(NULL, finfo);
3339 		InitFunctionCallInfoData(*fcinfo, finfo, 2,
3340 								 InvalidOid, NULL, NULL);
3341 
3342 		/* left arg */
3343 		scratch.opcode = EEOP_INNER_VAR;
3344 		scratch.d.var.attnum = attno - 1;
3345 		scratch.d.var.vartype = latt->atttypid;
3346 		scratch.resvalue = &fcinfo->arg[0];
3347 		scratch.resnull = &fcinfo->argnull[0];
3348 		ExprEvalPushStep(state, &scratch);
3349 
3350 		/* right arg */
3351 		scratch.opcode = EEOP_OUTER_VAR;
3352 		scratch.d.var.attnum = attno - 1;
3353 		scratch.d.var.vartype = ratt->atttypid;
3354 		scratch.resvalue = &fcinfo->arg[1];
3355 		scratch.resnull = &fcinfo->argnull[1];
3356 		ExprEvalPushStep(state, &scratch);
3357 
3358 		/* evaluate distinctness */
3359 		scratch.opcode = EEOP_NOT_DISTINCT;
3360 		scratch.d.func.finfo = finfo;
3361 		scratch.d.func.fcinfo_data = fcinfo;
3362 		scratch.d.func.fn_addr = finfo->fn_addr;
3363 		scratch.d.func.nargs = 2;
3364 		scratch.resvalue = &state->resvalue;
3365 		scratch.resnull = &state->resnull;
3366 		ExprEvalPushStep(state, &scratch);
3367 
3368 		/* then emit EEOP_QUAL to detect if result is false (or null) */
3369 		scratch.opcode = EEOP_QUAL;
3370 		scratch.d.qualexpr.jumpdone = -1;
3371 		scratch.resvalue = &state->resvalue;
3372 		scratch.resnull = &state->resnull;
3373 		ExprEvalPushStep(state, &scratch);
3374 		adjust_jumps = lappend_int(adjust_jumps,
3375 								   state->steps_len - 1);
3376 	}
3377 
3378 	/* adjust jump targets */
3379 	foreach(lc, adjust_jumps)
3380 	{
3381 		ExprEvalStep *as = &state->steps[lfirst_int(lc)];
3382 
3383 		Assert(as->opcode == EEOP_QUAL);
3384 		Assert(as->d.qualexpr.jumpdone == -1);
3385 		as->d.qualexpr.jumpdone = state->steps_len;
3386 	}
3387 
3388 	scratch.resvalue = NULL;
3389 	scratch.resnull = NULL;
3390 	scratch.opcode = EEOP_DONE;
3391 	ExprEvalPushStep(state, &scratch);
3392 
3393 	ExecReadyExpr(state);
3394 
3395 	return state;
3396 }
3397