1 /*-------------------------------------------------------------------------
2  *
3  * execExprInterp.c
4  *	  Interpreted evaluation of an expression step list.
5  *
6  * This file provides either a "direct threaded" (for gcc, clang and
7  * compatible) or a "switch threaded" (for all compilers) implementation of
8  * expression evaluation.  The former is amongst the fastest known methods
9  * of interpreting programs without resorting to assembly level work, or
10  * just-in-time compilation, but it requires support for computed gotos.
11  * The latter is amongst the fastest approaches doable in standard C.
12  *
13  * In either case we use ExprEvalStep->opcode to dispatch to the code block
14  * within ExecInterpExpr() that implements the specific opcode type.
15  *
16  * Switch-threading uses a plain switch() statement to perform the
17  * dispatch.  This has the advantages of being plain C and allowing the
18  * compiler to warn if implementation of a specific opcode has been forgotten.
19  * The disadvantage is that dispatches will, as commonly implemented by
20  * compilers, happen from a single location, requiring more jumps and causing
21  * bad branch prediction.
22  *
23  * In direct threading, we use gcc's label-as-values extension - also adopted
24  * by some other compilers - to replace ExprEvalStep->opcode with the address
25  * of the block implementing the instruction. Dispatch to the next instruction
26  * is done by a "computed goto".  This allows for better branch prediction
27  * (as the jumps are happening from different locations) and fewer jumps
28  * (as no preparatory jump to a common dispatch location is needed).
29  *
30  * When using direct threading, ExecReadyInterpretedExpr will replace
31  * each step's opcode field with the address of the relevant code block and
32  * ExprState->flags will contain EEO_FLAG_DIRECT_THREADED to remember that
33  * that's been done.
34  *
35  * For very simple instructions the overhead of the full interpreter
36  * "startup", as minimal as it is, is noticeable.  Therefore
37  * ExecReadyInterpretedExpr will choose to implement simple scalar Var
38  * and Const expressions using special fast-path routines (ExecJust*).
39  * Benchmarking shows anything more complex than those may as well use the
40  * "full interpreter".
41  *
42  * Complex or uncommon instructions are not implemented in-line in
43  * ExecInterpExpr(), rather we call out to a helper function appearing later
44  * in this file.  For one reason, there'd not be a noticeable performance
45  * benefit, but more importantly those complex routines are intended to be
46  * shared between different expression evaluation approaches.  For instance
47  * a JIT compiler would generate calls to them.  (This is why they are
48  * exported rather than being "static" in this file.)
49  *
50  *
51  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
52  * Portions Copyright (c) 1994, Regents of the University of California
53  *
54  * IDENTIFICATION
55  *	  src/backend/executor/execExprInterp.c
56  *
57  *-------------------------------------------------------------------------
58  */
59 #include "postgres.h"
60 
61 #include "access/tuptoaster.h"
62 #include "catalog/pg_type.h"
63 #include "commands/sequence.h"
64 #include "executor/execExpr.h"
65 #include "executor/nodeSubplan.h"
66 #include "funcapi.h"
67 #include "miscadmin.h"
68 #include "nodes/nodeFuncs.h"
69 #include "parser/parsetree.h"
70 #include "pgstat.h"
71 #include "utils/builtins.h"
72 #include "utils/date.h"
73 #include "utils/lsyscache.h"
74 #include "utils/timestamp.h"
75 #include "utils/typcache.h"
76 #include "utils/xml.h"
77 
78 
79 /*
80  * Use computed-goto-based opcode dispatch when computed gotos are available.
81  * But use a separate symbol so that it's easy to adjust locally in this file
82  * for development and testing.
83  */
84 #ifdef HAVE_COMPUTED_GOTO
85 #define EEO_USE_COMPUTED_GOTO
86 #endif							/* HAVE_COMPUTED_GOTO */
87 
88 /*
89  * Macros for opcode dispatch.
90  *
91  * EEO_SWITCH - just hides the switch if not in use.
92  * EEO_CASE - labels the implementation of named expression step type.
93  * EEO_DISPATCH - jump to the implementation of the step type for 'op'.
94  * EEO_OPCODE - compute opcode required by used expression evaluation method.
95  * EEO_NEXT - increment 'op' and jump to correct next step type.
96  * EEO_JUMP - jump to the specified step number within the current expression.
97  */
98 #if defined(EEO_USE_COMPUTED_GOTO)
99 
100 /* to make dispatch_table accessible outside ExecInterpExpr() */
101 static const void **dispatch_table = NULL;
102 
103 #define EEO_SWITCH()
104 #define EEO_CASE(name)		CASE_##name:
105 #define EEO_DISPATCH()		goto *((void *) op->opcode)
106 #define EEO_OPCODE(opcode)	((intptr_t) dispatch_table[opcode])
107 
108 #else							/* !EEO_USE_COMPUTED_GOTO */
109 
110 #define EEO_SWITCH()		starteval: switch ((ExprEvalOp) op->opcode)
111 #define EEO_CASE(name)		case name:
112 #define EEO_DISPATCH()		goto starteval
113 #define EEO_OPCODE(opcode)	(opcode)
114 
115 #endif							/* EEO_USE_COMPUTED_GOTO */
116 
117 #define EEO_NEXT() \
118 	do { \
119 		op++; \
120 		EEO_DISPATCH(); \
121 	} while (0)
122 
123 #define EEO_JUMP(stepno) \
124 	do { \
125 		op = &state->steps[stepno]; \
126 		EEO_DISPATCH(); \
127 	} while (0)
128 
129 
130 static Datum ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull);
131 static void ExecInitInterpreter(void);
132 
133 /* support functions */
134 static void CheckVarSlotCompatibility(TupleTableSlot *slot, int attnum, Oid vartype);
135 static TupleDesc get_cached_rowtype(Oid type_id, int32 typmod,
136 				   TupleDesc *cache_field, ExprContext *econtext);
137 static void ShutdownTupleDescRef(Datum arg);
138 static void ExecEvalRowNullInt(ExprState *state, ExprEvalStep *op,
139 				   ExprContext *econtext, bool checkisnull);
140 
141 /* fast-path evaluation functions */
142 static Datum ExecJustInnerVarFirst(ExprState *state, ExprContext *econtext, bool *isnull);
143 static Datum ExecJustInnerVar(ExprState *state, ExprContext *econtext, bool *isnull);
144 static Datum ExecJustOuterVarFirst(ExprState *state, ExprContext *econtext, bool *isnull);
145 static Datum ExecJustOuterVar(ExprState *state, ExprContext *econtext, bool *isnull);
146 static Datum ExecJustScanVarFirst(ExprState *state, ExprContext *econtext, bool *isnull);
147 static Datum ExecJustScanVar(ExprState *state, ExprContext *econtext, bool *isnull);
148 static Datum ExecJustConst(ExprState *state, ExprContext *econtext, bool *isnull);
149 static Datum ExecJustAssignInnerVar(ExprState *state, ExprContext *econtext, bool *isnull);
150 static Datum ExecJustAssignOuterVar(ExprState *state, ExprContext *econtext, bool *isnull);
151 static Datum ExecJustAssignScanVar(ExprState *state, ExprContext *econtext, bool *isnull);
152 
153 
154 /*
155  * Prepare ExprState for interpreted execution.
156  */
157 void
ExecReadyInterpretedExpr(ExprState * state)158 ExecReadyInterpretedExpr(ExprState *state)
159 {
160 	/* Ensure one-time interpreter setup has been done */
161 	ExecInitInterpreter();
162 
163 	/* Simple validity checks on expression */
164 	Assert(state->steps_len >= 1);
165 	Assert(state->steps[state->steps_len - 1].opcode == EEOP_DONE);
166 
167 	/*
168 	 * Don't perform redundant initialization. This is unreachable in current
169 	 * cases, but might be hit if there's additional expression evaluation
170 	 * methods that rely on interpreted execution to work.
171 	 */
172 	if (state->flags & EEO_FLAG_INTERPRETER_INITIALIZED)
173 		return;
174 
175 	/* DIRECT_THREADED should not already be set */
176 	Assert((state->flags & EEO_FLAG_DIRECT_THREADED) == 0);
177 
178 	/*
179 	 * There shouldn't be any errors before the expression is fully
180 	 * initialized, and even if so, it'd lead to the expression being
181 	 * abandoned.  So we can set the flag now and save some code.
182 	 */
183 	state->flags |= EEO_FLAG_INTERPRETER_INITIALIZED;
184 
185 	/*
186 	 * Select fast-path evalfuncs for very simple expressions.  "Starting up"
187 	 * the full interpreter is a measurable overhead for these.  Plain Vars
188 	 * and Const seem to be the only ones where the intrinsic cost is small
189 	 * enough that the overhead of ExecInterpExpr matters.  For more complex
190 	 * expressions it's cheaper to use ExecInterpExpr always.
191 	 */
192 	if (state->steps_len == 3)
193 	{
194 		ExprEvalOp	step0 = state->steps[0].opcode;
195 		ExprEvalOp	step1 = state->steps[1].opcode;
196 
197 		if (step0 == EEOP_INNER_FETCHSOME &&
198 			step1 == EEOP_INNER_VAR_FIRST)
199 		{
200 			state->evalfunc = ExecJustInnerVarFirst;
201 			return;
202 		}
203 		else if (step0 == EEOP_OUTER_FETCHSOME &&
204 				 step1 == EEOP_OUTER_VAR_FIRST)
205 		{
206 			state->evalfunc = ExecJustOuterVarFirst;
207 			return;
208 		}
209 		else if (step0 == EEOP_SCAN_FETCHSOME &&
210 				 step1 == EEOP_SCAN_VAR_FIRST)
211 		{
212 			state->evalfunc = ExecJustScanVarFirst;
213 			return;
214 		}
215 		else if (step0 == EEOP_INNER_FETCHSOME &&
216 				 step1 == EEOP_ASSIGN_INNER_VAR)
217 		{
218 			state->evalfunc = ExecJustAssignInnerVar;
219 			return;
220 		}
221 		else if (step0 == EEOP_OUTER_FETCHSOME &&
222 				 step1 == EEOP_ASSIGN_OUTER_VAR)
223 		{
224 			state->evalfunc = ExecJustAssignOuterVar;
225 			return;
226 		}
227 		else if (step0 == EEOP_SCAN_FETCHSOME &&
228 				 step1 == EEOP_ASSIGN_SCAN_VAR)
229 		{
230 			state->evalfunc = ExecJustAssignScanVar;
231 			return;
232 		}
233 	}
234 	else if (state->steps_len == 2 &&
235 			 state->steps[0].opcode == EEOP_CONST)
236 	{
237 		state->evalfunc = ExecJustConst;
238 		return;
239 	}
240 
241 #if defined(EEO_USE_COMPUTED_GOTO)
242 
243 	/*
244 	 * In the direct-threaded implementation, replace each opcode with the
245 	 * address to jump to.  (Use ExecEvalStepOp() to get back the opcode.)
246 	 */
247 	{
248 		int			off;
249 
250 		for (off = 0; off < state->steps_len; off++)
251 		{
252 			ExprEvalStep *op = &state->steps[off];
253 
254 			op->opcode = EEO_OPCODE(op->opcode);
255 		}
256 
257 		state->flags |= EEO_FLAG_DIRECT_THREADED;
258 	}
259 #endif							/* EEO_USE_COMPUTED_GOTO */
260 
261 	state->evalfunc = ExecInterpExpr;
262 }
263 
264 
265 /*
266  * Evaluate expression identified by "state" in the execution context
267  * given by "econtext".  *isnull is set to the is-null flag for the result,
268  * and the Datum value is the function result.
269  *
270  * As a special case, return the dispatch table's address if state is NULL.
271  * This is used by ExecInitInterpreter to set up the dispatch_table global.
272  * (Only applies when EEO_USE_COMPUTED_GOTO is defined.)
273  */
274 static Datum
ExecInterpExpr(ExprState * state,ExprContext * econtext,bool * isnull)275 ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
276 {
277 	ExprEvalStep *op;
278 	TupleTableSlot *resultslot;
279 	TupleTableSlot *innerslot;
280 	TupleTableSlot *outerslot;
281 	TupleTableSlot *scanslot;
282 
283 	/*
284 	 * This array has to be in the same order as enum ExprEvalOp.
285 	 */
286 #if defined(EEO_USE_COMPUTED_GOTO)
287 	static const void *const dispatch_table[] = {
288 		&&CASE_EEOP_DONE,
289 		&&CASE_EEOP_INNER_FETCHSOME,
290 		&&CASE_EEOP_OUTER_FETCHSOME,
291 		&&CASE_EEOP_SCAN_FETCHSOME,
292 		&&CASE_EEOP_INNER_VAR_FIRST,
293 		&&CASE_EEOP_INNER_VAR,
294 		&&CASE_EEOP_OUTER_VAR_FIRST,
295 		&&CASE_EEOP_OUTER_VAR,
296 		&&CASE_EEOP_SCAN_VAR_FIRST,
297 		&&CASE_EEOP_SCAN_VAR,
298 		&&CASE_EEOP_INNER_SYSVAR,
299 		&&CASE_EEOP_OUTER_SYSVAR,
300 		&&CASE_EEOP_SCAN_SYSVAR,
301 		&&CASE_EEOP_WHOLEROW,
302 		&&CASE_EEOP_ASSIGN_INNER_VAR,
303 		&&CASE_EEOP_ASSIGN_OUTER_VAR,
304 		&&CASE_EEOP_ASSIGN_SCAN_VAR,
305 		&&CASE_EEOP_ASSIGN_TMP,
306 		&&CASE_EEOP_ASSIGN_TMP_MAKE_RO,
307 		&&CASE_EEOP_CONST,
308 		&&CASE_EEOP_FUNCEXPR,
309 		&&CASE_EEOP_FUNCEXPR_STRICT,
310 		&&CASE_EEOP_FUNCEXPR_FUSAGE,
311 		&&CASE_EEOP_FUNCEXPR_STRICT_FUSAGE,
312 		&&CASE_EEOP_BOOL_AND_STEP_FIRST,
313 		&&CASE_EEOP_BOOL_AND_STEP,
314 		&&CASE_EEOP_BOOL_AND_STEP_LAST,
315 		&&CASE_EEOP_BOOL_OR_STEP_FIRST,
316 		&&CASE_EEOP_BOOL_OR_STEP,
317 		&&CASE_EEOP_BOOL_OR_STEP_LAST,
318 		&&CASE_EEOP_BOOL_NOT_STEP,
319 		&&CASE_EEOP_QUAL,
320 		&&CASE_EEOP_JUMP,
321 		&&CASE_EEOP_JUMP_IF_NULL,
322 		&&CASE_EEOP_JUMP_IF_NOT_NULL,
323 		&&CASE_EEOP_JUMP_IF_NOT_TRUE,
324 		&&CASE_EEOP_NULLTEST_ISNULL,
325 		&&CASE_EEOP_NULLTEST_ISNOTNULL,
326 		&&CASE_EEOP_NULLTEST_ROWISNULL,
327 		&&CASE_EEOP_NULLTEST_ROWISNOTNULL,
328 		&&CASE_EEOP_BOOLTEST_IS_TRUE,
329 		&&CASE_EEOP_BOOLTEST_IS_NOT_TRUE,
330 		&&CASE_EEOP_BOOLTEST_IS_FALSE,
331 		&&CASE_EEOP_BOOLTEST_IS_NOT_FALSE,
332 		&&CASE_EEOP_PARAM_EXEC,
333 		&&CASE_EEOP_PARAM_EXTERN,
334 		&&CASE_EEOP_CASE_TESTVAL,
335 		&&CASE_EEOP_MAKE_READONLY,
336 		&&CASE_EEOP_IOCOERCE,
337 		&&CASE_EEOP_DISTINCT,
338 		&&CASE_EEOP_NULLIF,
339 		&&CASE_EEOP_SQLVALUEFUNCTION,
340 		&&CASE_EEOP_CURRENTOFEXPR,
341 		&&CASE_EEOP_NEXTVALUEEXPR,
342 		&&CASE_EEOP_ARRAYEXPR,
343 		&&CASE_EEOP_ARRAYCOERCE,
344 		&&CASE_EEOP_ROW,
345 		&&CASE_EEOP_ROWCOMPARE_STEP,
346 		&&CASE_EEOP_ROWCOMPARE_FINAL,
347 		&&CASE_EEOP_MINMAX,
348 		&&CASE_EEOP_FIELDSELECT,
349 		&&CASE_EEOP_FIELDSTORE_DEFORM,
350 		&&CASE_EEOP_FIELDSTORE_FORM,
351 		&&CASE_EEOP_ARRAYREF_SUBSCRIPT,
352 		&&CASE_EEOP_ARRAYREF_OLD,
353 		&&CASE_EEOP_ARRAYREF_ASSIGN,
354 		&&CASE_EEOP_ARRAYREF_FETCH,
355 		&&CASE_EEOP_DOMAIN_TESTVAL,
356 		&&CASE_EEOP_DOMAIN_NOTNULL,
357 		&&CASE_EEOP_DOMAIN_CHECK,
358 		&&CASE_EEOP_CONVERT_ROWTYPE,
359 		&&CASE_EEOP_SCALARARRAYOP,
360 		&&CASE_EEOP_XMLEXPR,
361 		&&CASE_EEOP_AGGREF,
362 		&&CASE_EEOP_GROUPING_FUNC,
363 		&&CASE_EEOP_WINDOW_FUNC,
364 		&&CASE_EEOP_SUBPLAN,
365 		&&CASE_EEOP_ALTERNATIVE_SUBPLAN,
366 		&&CASE_EEOP_LAST
367 	};
368 
369 	StaticAssertStmt(EEOP_LAST + 1 == lengthof(dispatch_table),
370 					 "dispatch_table out of whack with ExprEvalOp");
371 
372 	if (unlikely(state == NULL))
373 		return PointerGetDatum(dispatch_table);
374 #else
375 	Assert(state != NULL);
376 #endif							/* EEO_USE_COMPUTED_GOTO */
377 
378 	/* setup state */
379 	op = state->steps;
380 	resultslot = state->resultslot;
381 	innerslot = econtext->ecxt_innertuple;
382 	outerslot = econtext->ecxt_outertuple;
383 	scanslot = econtext->ecxt_scantuple;
384 
385 #if defined(EEO_USE_COMPUTED_GOTO)
386 	EEO_DISPATCH();
387 #endif
388 
389 	EEO_SWITCH()
390 	{
391 		EEO_CASE(EEOP_DONE)
392 		{
393 			goto out;
394 		}
395 
396 		EEO_CASE(EEOP_INNER_FETCHSOME)
397 		{
398 			/* XXX: worthwhile to check tts_nvalid inline first? */
399 			slot_getsomeattrs(innerslot, op->d.fetch.last_var);
400 
401 			EEO_NEXT();
402 		}
403 
404 		EEO_CASE(EEOP_OUTER_FETCHSOME)
405 		{
406 			slot_getsomeattrs(outerslot, op->d.fetch.last_var);
407 
408 			EEO_NEXT();
409 		}
410 
411 		EEO_CASE(EEOP_SCAN_FETCHSOME)
412 		{
413 			slot_getsomeattrs(scanslot, op->d.fetch.last_var);
414 
415 			EEO_NEXT();
416 		}
417 
418 		EEO_CASE(EEOP_INNER_VAR_FIRST)
419 		{
420 			int			attnum = op->d.var.attnum;
421 
422 			/*
423 			 * First time through, check whether attribute matches Var.  Might
424 			 * not be ok anymore, due to schema changes.
425 			 */
426 			CheckVarSlotCompatibility(innerslot, attnum + 1, op->d.var.vartype);
427 
428 			/* Skip that check on subsequent evaluations */
429 			op->opcode = EEO_OPCODE(EEOP_INNER_VAR);
430 
431 			/* FALL THROUGH to EEOP_INNER_VAR */
432 		}
433 
434 		EEO_CASE(EEOP_INNER_VAR)
435 		{
436 			int			attnum = op->d.var.attnum;
437 
438 			/*
439 			 * Since we already extracted all referenced columns from the
440 			 * tuple with a FETCHSOME step, we can just grab the value
441 			 * directly out of the slot's decomposed-data arrays.  But let's
442 			 * have an Assert to check that that did happen.
443 			 */
444 			Assert(attnum >= 0 && attnum < innerslot->tts_nvalid);
445 			*op->resvalue = innerslot->tts_values[attnum];
446 			*op->resnull = innerslot->tts_isnull[attnum];
447 
448 			EEO_NEXT();
449 		}
450 
451 		EEO_CASE(EEOP_OUTER_VAR_FIRST)
452 		{
453 			int			attnum = op->d.var.attnum;
454 
455 			/* See EEOP_INNER_VAR_FIRST comments */
456 
457 			CheckVarSlotCompatibility(outerslot, attnum + 1, op->d.var.vartype);
458 			op->opcode = EEO_OPCODE(EEOP_OUTER_VAR);
459 
460 			/* FALL THROUGH to EEOP_OUTER_VAR */
461 		}
462 
463 		EEO_CASE(EEOP_OUTER_VAR)
464 		{
465 			int			attnum = op->d.var.attnum;
466 
467 			/* See EEOP_INNER_VAR comments */
468 
469 			Assert(attnum >= 0 && attnum < outerslot->tts_nvalid);
470 			*op->resvalue = outerslot->tts_values[attnum];
471 			*op->resnull = outerslot->tts_isnull[attnum];
472 
473 			EEO_NEXT();
474 		}
475 
476 		EEO_CASE(EEOP_SCAN_VAR_FIRST)
477 		{
478 			int			attnum = op->d.var.attnum;
479 
480 			/* See EEOP_INNER_VAR_FIRST comments */
481 
482 			CheckVarSlotCompatibility(scanslot, attnum + 1, op->d.var.vartype);
483 			op->opcode = EEO_OPCODE(EEOP_SCAN_VAR);
484 
485 			/* FALL THROUGH to EEOP_SCAN_VAR */
486 		}
487 
488 		EEO_CASE(EEOP_SCAN_VAR)
489 		{
490 			int			attnum = op->d.var.attnum;
491 
492 			/* See EEOP_INNER_VAR comments */
493 
494 			Assert(attnum >= 0 && attnum < scanslot->tts_nvalid);
495 			*op->resvalue = scanslot->tts_values[attnum];
496 			*op->resnull = scanslot->tts_isnull[attnum];
497 
498 			EEO_NEXT();
499 		}
500 
501 		EEO_CASE(EEOP_INNER_SYSVAR)
502 		{
503 			int			attnum = op->d.var.attnum;
504 
505 			/* these asserts must match defenses in slot_getattr */
506 			Assert(innerslot->tts_tuple != NULL);
507 			Assert(innerslot->tts_tuple != &(innerslot->tts_minhdr));
508 			/* heap_getsysattr has sufficient defenses against bad attnums */
509 
510 			*op->resvalue = heap_getsysattr(innerslot->tts_tuple, attnum,
511 											innerslot->tts_tupleDescriptor,
512 											op->resnull);
513 
514 			EEO_NEXT();
515 		}
516 
517 		EEO_CASE(EEOP_OUTER_SYSVAR)
518 		{
519 			int			attnum = op->d.var.attnum;
520 
521 			/* these asserts must match defenses in slot_getattr */
522 			Assert(outerslot->tts_tuple != NULL);
523 			Assert(outerslot->tts_tuple != &(outerslot->tts_minhdr));
524 
525 			/* heap_getsysattr has sufficient defenses against bad attnums */
526 			*op->resvalue = heap_getsysattr(outerslot->tts_tuple, attnum,
527 											outerslot->tts_tupleDescriptor,
528 											op->resnull);
529 
530 			EEO_NEXT();
531 		}
532 
533 		EEO_CASE(EEOP_SCAN_SYSVAR)
534 		{
535 			int			attnum = op->d.var.attnum;
536 
537 			/* these asserts must match defenses in slot_getattr */
538 			Assert(scanslot->tts_tuple != NULL);
539 			Assert(scanslot->tts_tuple != &(scanslot->tts_minhdr));
540 			/* heap_getsysattr has sufficient defenses against bad attnums */
541 
542 			*op->resvalue = heap_getsysattr(scanslot->tts_tuple, attnum,
543 											scanslot->tts_tupleDescriptor,
544 											op->resnull);
545 
546 			EEO_NEXT();
547 		}
548 
549 		EEO_CASE(EEOP_WHOLEROW)
550 		{
551 			/* too complex for an inline implementation */
552 			ExecEvalWholeRowVar(state, op, econtext);
553 
554 			EEO_NEXT();
555 		}
556 
557 		EEO_CASE(EEOP_ASSIGN_INNER_VAR)
558 		{
559 			int			resultnum = op->d.assign_var.resultnum;
560 			int			attnum = op->d.assign_var.attnum;
561 
562 			/*
563 			 * We do not need CheckVarSlotCompatibility here; that was taken
564 			 * care of at compilation time.  But see EEOP_INNER_VAR comments.
565 			 */
566 			Assert(attnum >= 0 && attnum < innerslot->tts_nvalid);
567 			Assert(resultnum >= 0 && resultnum < resultslot->tts_tupleDescriptor->natts);
568 			resultslot->tts_values[resultnum] = innerslot->tts_values[attnum];
569 			resultslot->tts_isnull[resultnum] = innerslot->tts_isnull[attnum];
570 
571 			EEO_NEXT();
572 		}
573 
574 		EEO_CASE(EEOP_ASSIGN_OUTER_VAR)
575 		{
576 			int			resultnum = op->d.assign_var.resultnum;
577 			int			attnum = op->d.assign_var.attnum;
578 
579 			/*
580 			 * We do not need CheckVarSlotCompatibility here; that was taken
581 			 * care of at compilation time.  But see EEOP_INNER_VAR comments.
582 			 */
583 			Assert(attnum >= 0 && attnum < outerslot->tts_nvalid);
584 			Assert(resultnum >= 0 && resultnum < resultslot->tts_tupleDescriptor->natts);
585 			resultslot->tts_values[resultnum] = outerslot->tts_values[attnum];
586 			resultslot->tts_isnull[resultnum] = outerslot->tts_isnull[attnum];
587 
588 			EEO_NEXT();
589 		}
590 
591 		EEO_CASE(EEOP_ASSIGN_SCAN_VAR)
592 		{
593 			int			resultnum = op->d.assign_var.resultnum;
594 			int			attnum = op->d.assign_var.attnum;
595 
596 			/*
597 			 * We do not need CheckVarSlotCompatibility here; that was taken
598 			 * care of at compilation time.  But see EEOP_INNER_VAR comments.
599 			 */
600 			Assert(attnum >= 0 && attnum < scanslot->tts_nvalid);
601 			Assert(resultnum >= 0 && resultnum < resultslot->tts_tupleDescriptor->natts);
602 			resultslot->tts_values[resultnum] = scanslot->tts_values[attnum];
603 			resultslot->tts_isnull[resultnum] = scanslot->tts_isnull[attnum];
604 
605 			EEO_NEXT();
606 		}
607 
608 		EEO_CASE(EEOP_ASSIGN_TMP)
609 		{
610 			int			resultnum = op->d.assign_tmp.resultnum;
611 
612 			Assert(resultnum >= 0 && resultnum < resultslot->tts_tupleDescriptor->natts);
613 			resultslot->tts_values[resultnum] = state->resvalue;
614 			resultslot->tts_isnull[resultnum] = state->resnull;
615 
616 			EEO_NEXT();
617 		}
618 
619 		EEO_CASE(EEOP_ASSIGN_TMP_MAKE_RO)
620 		{
621 			int			resultnum = op->d.assign_tmp.resultnum;
622 
623 			Assert(resultnum >= 0 && resultnum < resultslot->tts_tupleDescriptor->natts);
624 			resultslot->tts_isnull[resultnum] = state->resnull;
625 			if (!resultslot->tts_isnull[resultnum])
626 				resultslot->tts_values[resultnum] =
627 					MakeExpandedObjectReadOnlyInternal(state->resvalue);
628 			else
629 				resultslot->tts_values[resultnum] = state->resvalue;
630 
631 			EEO_NEXT();
632 		}
633 
634 		EEO_CASE(EEOP_CONST)
635 		{
636 			*op->resnull = op->d.constval.isnull;
637 			*op->resvalue = op->d.constval.value;
638 
639 			EEO_NEXT();
640 		}
641 
642 		/*
643 		 * Function-call implementations. Arguments have previously been
644 		 * evaluated directly into fcinfo->args.
645 		 *
646 		 * As both STRICT checks and function-usage are noticeable performance
647 		 * wise, and function calls are a very hot-path (they also back
648 		 * operators!), it's worth having so many separate opcodes.
649 		 */
650 		EEO_CASE(EEOP_FUNCEXPR)
651 		{
652 			FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
653 
654 			fcinfo->isnull = false;
655 			*op->resvalue = (op->d.func.fn_addr) (fcinfo);
656 			*op->resnull = fcinfo->isnull;
657 
658 			EEO_NEXT();
659 		}
660 
661 		EEO_CASE(EEOP_FUNCEXPR_STRICT)
662 		{
663 			FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
664 			bool	   *argnull = fcinfo->argnull;
665 			int			argno;
666 
667 			/* strict function, so check for NULL args */
668 			for (argno = 0; argno < op->d.func.nargs; argno++)
669 			{
670 				if (argnull[argno])
671 				{
672 					*op->resnull = true;
673 					goto strictfail;
674 				}
675 			}
676 			fcinfo->isnull = false;
677 			*op->resvalue = (op->d.func.fn_addr) (fcinfo);
678 			*op->resnull = fcinfo->isnull;
679 
680 	strictfail:
681 			EEO_NEXT();
682 		}
683 
684 		EEO_CASE(EEOP_FUNCEXPR_FUSAGE)
685 		{
686 			FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
687 			PgStat_FunctionCallUsage fcusage;
688 
689 			pgstat_init_function_usage(fcinfo, &fcusage);
690 
691 			fcinfo->isnull = false;
692 			*op->resvalue = (op->d.func.fn_addr) (fcinfo);
693 			*op->resnull = fcinfo->isnull;
694 
695 			pgstat_end_function_usage(&fcusage, true);
696 
697 			EEO_NEXT();
698 		}
699 
700 		EEO_CASE(EEOP_FUNCEXPR_STRICT_FUSAGE)
701 		{
702 			FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
703 			PgStat_FunctionCallUsage fcusage;
704 			bool	   *argnull = fcinfo->argnull;
705 			int			argno;
706 
707 			/* strict function, so check for NULL args */
708 			for (argno = 0; argno < op->d.func.nargs; argno++)
709 			{
710 				if (argnull[argno])
711 				{
712 					*op->resnull = true;
713 					goto strictfail_fusage;
714 				}
715 			}
716 
717 			pgstat_init_function_usage(fcinfo, &fcusage);
718 
719 			fcinfo->isnull = false;
720 			*op->resvalue = (op->d.func.fn_addr) (fcinfo);
721 			*op->resnull = fcinfo->isnull;
722 
723 			pgstat_end_function_usage(&fcusage, true);
724 
725 	strictfail_fusage:
726 			EEO_NEXT();
727 		}
728 
729 		/*
730 		 * If any of its clauses is FALSE, an AND's result is FALSE regardless
731 		 * of the states of the rest of the clauses, so we can stop evaluating
732 		 * and return FALSE immediately.  If none are FALSE and one or more is
733 		 * NULL, we return NULL; otherwise we return TRUE.  This makes sense
734 		 * when you interpret NULL as "don't know": perhaps one of the "don't
735 		 * knows" would have been FALSE if we'd known its value.  Only when
736 		 * all the inputs are known to be TRUE can we state confidently that
737 		 * the AND's result is TRUE.
738 		 */
739 		EEO_CASE(EEOP_BOOL_AND_STEP_FIRST)
740 		{
741 			*op->d.boolexpr.anynull = false;
742 
743 			/*
744 			 * EEOP_BOOL_AND_STEP_FIRST resets anynull, otherwise it's the
745 			 * same as EEOP_BOOL_AND_STEP - so fall through to that.
746 			 */
747 
748 			/* FALL THROUGH */
749 		}
750 
751 		EEO_CASE(EEOP_BOOL_AND_STEP)
752 		{
753 			if (*op->resnull)
754 			{
755 				*op->d.boolexpr.anynull = true;
756 			}
757 			else if (!DatumGetBool(*op->resvalue))
758 			{
759 				/* result is already set to FALSE, need not change it */
760 				/* bail out early */
761 				EEO_JUMP(op->d.boolexpr.jumpdone);
762 			}
763 
764 			EEO_NEXT();
765 		}
766 
767 		EEO_CASE(EEOP_BOOL_AND_STEP_LAST)
768 		{
769 			if (*op->resnull)
770 			{
771 				/* result is already set to NULL, need not change it */
772 			}
773 			else if (!DatumGetBool(*op->resvalue))
774 			{
775 				/* result is already set to FALSE, need not change it */
776 
777 				/*
778 				 * No point jumping early to jumpdone - would be same target
779 				 * (as this is the last argument to the AND expression),
780 				 * except more expensive.
781 				 */
782 			}
783 			else if (*op->d.boolexpr.anynull)
784 			{
785 				*op->resvalue = (Datum) 0;
786 				*op->resnull = true;
787 			}
788 			else
789 			{
790 				/* result is already set to TRUE, need not change it */
791 			}
792 
793 			EEO_NEXT();
794 		}
795 
796 		/*
797 		 * If any of its clauses is TRUE, an OR's result is TRUE regardless of
798 		 * the states of the rest of the clauses, so we can stop evaluating
799 		 * and return TRUE immediately.  If none are TRUE and one or more is
800 		 * NULL, we return NULL; otherwise we return FALSE.  This makes sense
801 		 * when you interpret NULL as "don't know": perhaps one of the "don't
802 		 * knows" would have been TRUE if we'd known its value.  Only when all
803 		 * the inputs are known to be FALSE can we state confidently that the
804 		 * OR's result is FALSE.
805 		 */
806 		EEO_CASE(EEOP_BOOL_OR_STEP_FIRST)
807 		{
808 			*op->d.boolexpr.anynull = false;
809 
810 			/*
811 			 * EEOP_BOOL_OR_STEP_FIRST resets anynull, otherwise it's the same
812 			 * as EEOP_BOOL_OR_STEP - so fall through to that.
813 			 */
814 
815 			/* FALL THROUGH */
816 		}
817 
818 		EEO_CASE(EEOP_BOOL_OR_STEP)
819 		{
820 			if (*op->resnull)
821 			{
822 				*op->d.boolexpr.anynull = true;
823 			}
824 			else if (DatumGetBool(*op->resvalue))
825 			{
826 				/* result is already set to TRUE, need not change it */
827 				/* bail out early */
828 				EEO_JUMP(op->d.boolexpr.jumpdone);
829 			}
830 
831 			EEO_NEXT();
832 		}
833 
834 		EEO_CASE(EEOP_BOOL_OR_STEP_LAST)
835 		{
836 			if (*op->resnull)
837 			{
838 				/* result is already set to NULL, need not change it */
839 			}
840 			else if (DatumGetBool(*op->resvalue))
841 			{
842 				/* result is already set to TRUE, need not change it */
843 
844 				/*
845 				 * No point jumping to jumpdone - would be same target (as
846 				 * this is the last argument to the AND expression), except
847 				 * more expensive.
848 				 */
849 			}
850 			else if (*op->d.boolexpr.anynull)
851 			{
852 				*op->resvalue = (Datum) 0;
853 				*op->resnull = true;
854 			}
855 			else
856 			{
857 				/* result is already set to FALSE, need not change it */
858 			}
859 
860 			EEO_NEXT();
861 		}
862 
863 		EEO_CASE(EEOP_BOOL_NOT_STEP)
864 		{
865 			/*
866 			 * Evaluation of 'not' is simple... if expr is false, then return
867 			 * 'true' and vice versa.  It's safe to do this even on a
868 			 * nominally null value, so we ignore resnull; that means that
869 			 * NULL in produces NULL out, which is what we want.
870 			 */
871 			*op->resvalue = BoolGetDatum(!DatumGetBool(*op->resvalue));
872 
873 			EEO_NEXT();
874 		}
875 
876 		EEO_CASE(EEOP_QUAL)
877 		{
878 			/* simplified version of BOOL_AND_STEP for use by ExecQual() */
879 
880 			/* If argument (also result) is false or null ... */
881 			if (*op->resnull ||
882 				!DatumGetBool(*op->resvalue))
883 			{
884 				/* ... bail out early, returning FALSE */
885 				*op->resnull = false;
886 				*op->resvalue = BoolGetDatum(false);
887 				EEO_JUMP(op->d.qualexpr.jumpdone);
888 			}
889 
890 			/*
891 			 * Otherwise, leave the TRUE value in place, in case this is the
892 			 * last qual.  Then, TRUE is the correct answer.
893 			 */
894 
895 			EEO_NEXT();
896 		}
897 
898 		EEO_CASE(EEOP_JUMP)
899 		{
900 			/* Unconditionally jump to target step */
901 			EEO_JUMP(op->d.jump.jumpdone);
902 		}
903 
904 		EEO_CASE(EEOP_JUMP_IF_NULL)
905 		{
906 			/* Transfer control if current result is null */
907 			if (*op->resnull)
908 				EEO_JUMP(op->d.jump.jumpdone);
909 
910 			EEO_NEXT();
911 		}
912 
913 		EEO_CASE(EEOP_JUMP_IF_NOT_NULL)
914 		{
915 			/* Transfer control if current result is non-null */
916 			if (!*op->resnull)
917 				EEO_JUMP(op->d.jump.jumpdone);
918 
919 			EEO_NEXT();
920 		}
921 
922 		EEO_CASE(EEOP_JUMP_IF_NOT_TRUE)
923 		{
924 			/* Transfer control if current result is null or false */
925 			if (*op->resnull || !DatumGetBool(*op->resvalue))
926 				EEO_JUMP(op->d.jump.jumpdone);
927 
928 			EEO_NEXT();
929 		}
930 
931 		EEO_CASE(EEOP_NULLTEST_ISNULL)
932 		{
933 			*op->resvalue = BoolGetDatum(*op->resnull);
934 			*op->resnull = false;
935 
936 			EEO_NEXT();
937 		}
938 
939 		EEO_CASE(EEOP_NULLTEST_ISNOTNULL)
940 		{
941 			*op->resvalue = BoolGetDatum(!*op->resnull);
942 			*op->resnull = false;
943 
944 			EEO_NEXT();
945 		}
946 
947 		EEO_CASE(EEOP_NULLTEST_ROWISNULL)
948 		{
949 			/* out of line implementation: too large */
950 			ExecEvalRowNull(state, op, econtext);
951 
952 			EEO_NEXT();
953 		}
954 
955 		EEO_CASE(EEOP_NULLTEST_ROWISNOTNULL)
956 		{
957 			/* out of line implementation: too large */
958 			ExecEvalRowNotNull(state, op, econtext);
959 
960 			EEO_NEXT();
961 		}
962 
963 		/* BooleanTest implementations for all booltesttypes */
964 
965 		EEO_CASE(EEOP_BOOLTEST_IS_TRUE)
966 		{
967 			if (*op->resnull)
968 			{
969 				*op->resvalue = BoolGetDatum(false);
970 				*op->resnull = false;
971 			}
972 			/* else, input value is the correct output as well */
973 
974 			EEO_NEXT();
975 		}
976 
977 		EEO_CASE(EEOP_BOOLTEST_IS_NOT_TRUE)
978 		{
979 			if (*op->resnull)
980 			{
981 				*op->resvalue = BoolGetDatum(true);
982 				*op->resnull = false;
983 			}
984 			else
985 				*op->resvalue = BoolGetDatum(!DatumGetBool(*op->resvalue));
986 
987 			EEO_NEXT();
988 		}
989 
990 		EEO_CASE(EEOP_BOOLTEST_IS_FALSE)
991 		{
992 			if (*op->resnull)
993 			{
994 				*op->resvalue = BoolGetDatum(false);
995 				*op->resnull = false;
996 			}
997 			else
998 				*op->resvalue = BoolGetDatum(!DatumGetBool(*op->resvalue));
999 
1000 			EEO_NEXT();
1001 		}
1002 
1003 		EEO_CASE(EEOP_BOOLTEST_IS_NOT_FALSE)
1004 		{
1005 			if (*op->resnull)
1006 			{
1007 				*op->resvalue = BoolGetDatum(true);
1008 				*op->resnull = false;
1009 			}
1010 			/* else, input value is the correct output as well */
1011 
1012 			EEO_NEXT();
1013 		}
1014 
1015 		EEO_CASE(EEOP_PARAM_EXEC)
1016 		{
1017 			/* out of line implementation: too large */
1018 			ExecEvalParamExec(state, op, econtext);
1019 
1020 			EEO_NEXT();
1021 		}
1022 
1023 		EEO_CASE(EEOP_PARAM_EXTERN)
1024 		{
1025 			/* out of line implementation: too large */
1026 			ExecEvalParamExtern(state, op, econtext);
1027 			EEO_NEXT();
1028 		}
1029 
1030 		EEO_CASE(EEOP_CASE_TESTVAL)
1031 		{
1032 			/*
1033 			 * Normally upper parts of the expression tree have setup the
1034 			 * values to be returned here, but some parts of the system
1035 			 * currently misuse {caseValue,domainValue}_{datum,isNull} to set
1036 			 * run-time data.  So if no values have been set-up, use
1037 			 * ExprContext's.  This isn't pretty, but also not *that* ugly,
1038 			 * and this is unlikely to be performance sensitive enough to
1039 			 * worry about an extra branch.
1040 			 */
1041 			if (op->d.casetest.value)
1042 			{
1043 				*op->resvalue = *op->d.casetest.value;
1044 				*op->resnull = *op->d.casetest.isnull;
1045 			}
1046 			else
1047 			{
1048 				*op->resvalue = econtext->caseValue_datum;
1049 				*op->resnull = econtext->caseValue_isNull;
1050 			}
1051 
1052 			EEO_NEXT();
1053 		}
1054 
1055 		EEO_CASE(EEOP_DOMAIN_TESTVAL)
1056 		{
1057 			/*
1058 			 * See EEOP_CASE_TESTVAL comment.
1059 			 */
1060 			if (op->d.casetest.value)
1061 			{
1062 				*op->resvalue = *op->d.casetest.value;
1063 				*op->resnull = *op->d.casetest.isnull;
1064 			}
1065 			else
1066 			{
1067 				*op->resvalue = econtext->domainValue_datum;
1068 				*op->resnull = econtext->domainValue_isNull;
1069 			}
1070 
1071 			EEO_NEXT();
1072 		}
1073 
1074 		EEO_CASE(EEOP_MAKE_READONLY)
1075 		{
1076 			/*
1077 			 * Force a varlena value that might be read multiple times to R/O
1078 			 */
1079 			if (!*op->d.make_readonly.isnull)
1080 				*op->resvalue =
1081 					MakeExpandedObjectReadOnlyInternal(*op->d.make_readonly.value);
1082 			*op->resnull = *op->d.make_readonly.isnull;
1083 
1084 			EEO_NEXT();
1085 		}
1086 
1087 		EEO_CASE(EEOP_IOCOERCE)
1088 		{
1089 			/*
1090 			 * Evaluate a CoerceViaIO node.  This can be quite a hot path, so
1091 			 * inline as much work as possible.  The source value is in our
1092 			 * result variable.
1093 			 */
1094 			char	   *str;
1095 
1096 			/* call output function (similar to OutputFunctionCall) */
1097 			if (*op->resnull)
1098 			{
1099 				/* output functions are not called on nulls */
1100 				str = NULL;
1101 			}
1102 			else
1103 			{
1104 				FunctionCallInfo fcinfo_out;
1105 
1106 				fcinfo_out = op->d.iocoerce.fcinfo_data_out;
1107 				fcinfo_out->arg[0] = *op->resvalue;
1108 				fcinfo_out->argnull[0] = false;
1109 
1110 				fcinfo_out->isnull = false;
1111 				str = DatumGetCString(FunctionCallInvoke(fcinfo_out));
1112 
1113 				/* OutputFunctionCall assumes result isn't null */
1114 				Assert(!fcinfo_out->isnull);
1115 			}
1116 
1117 			/* call input function (similar to InputFunctionCall) */
1118 			if (!op->d.iocoerce.finfo_in->fn_strict || str != NULL)
1119 			{
1120 				FunctionCallInfo fcinfo_in;
1121 
1122 				fcinfo_in = op->d.iocoerce.fcinfo_data_in;
1123 				fcinfo_in->arg[0] = PointerGetDatum(str);
1124 				fcinfo_in->argnull[0] = *op->resnull;
1125 				/* second and third arguments are already set up */
1126 
1127 				fcinfo_in->isnull = false;
1128 				*op->resvalue = FunctionCallInvoke(fcinfo_in);
1129 
1130 				/* Should get null result if and only if str is NULL */
1131 				if (str == NULL)
1132 				{
1133 					Assert(*op->resnull);
1134 					Assert(fcinfo_in->isnull);
1135 				}
1136 				else
1137 				{
1138 					Assert(!*op->resnull);
1139 					Assert(!fcinfo_in->isnull);
1140 				}
1141 			}
1142 
1143 			EEO_NEXT();
1144 		}
1145 
1146 		EEO_CASE(EEOP_DISTINCT)
1147 		{
1148 			/*
1149 			 * IS DISTINCT FROM must evaluate arguments (already done into
1150 			 * fcinfo->arg/argnull) to determine whether they are NULL; if
1151 			 * either is NULL then the result is determined.  If neither is
1152 			 * NULL, then proceed to evaluate the comparison function, which
1153 			 * is just the type's standard equality operator.  We need not
1154 			 * care whether that function is strict.  Because the handling of
1155 			 * nulls is different, we can't just reuse EEOP_FUNCEXPR.
1156 			 */
1157 			FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
1158 
1159 			/* check function arguments for NULLness */
1160 			if (fcinfo->argnull[0] && fcinfo->argnull[1])
1161 			{
1162 				/* Both NULL? Then is not distinct... */
1163 				*op->resvalue = BoolGetDatum(false);
1164 				*op->resnull = false;
1165 			}
1166 			else if (fcinfo->argnull[0] || fcinfo->argnull[1])
1167 			{
1168 				/* Only one is NULL? Then is distinct... */
1169 				*op->resvalue = BoolGetDatum(true);
1170 				*op->resnull = false;
1171 			}
1172 			else
1173 			{
1174 				/* Neither null, so apply the equality function */
1175 				Datum		eqresult;
1176 
1177 				fcinfo->isnull = false;
1178 				eqresult = (op->d.func.fn_addr) (fcinfo);
1179 				/* Must invert result of "="; safe to do even if null */
1180 				*op->resvalue = BoolGetDatum(!DatumGetBool(eqresult));
1181 				*op->resnull = fcinfo->isnull;
1182 			}
1183 
1184 			EEO_NEXT();
1185 		}
1186 
1187 		EEO_CASE(EEOP_NULLIF)
1188 		{
1189 			/*
1190 			 * The arguments are already evaluated into fcinfo->arg/argnull.
1191 			 */
1192 			FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
1193 
1194 			/* if either argument is NULL they can't be equal */
1195 			if (!fcinfo->argnull[0] && !fcinfo->argnull[1])
1196 			{
1197 				Datum		result;
1198 
1199 				fcinfo->isnull = false;
1200 				result = (op->d.func.fn_addr) (fcinfo);
1201 
1202 				/* if the arguments are equal return null */
1203 				if (!fcinfo->isnull && DatumGetBool(result))
1204 				{
1205 					*op->resvalue = (Datum) 0;
1206 					*op->resnull = true;
1207 
1208 					EEO_NEXT();
1209 				}
1210 			}
1211 
1212 			/* Arguments aren't equal, so return the first one */
1213 			*op->resvalue = fcinfo->arg[0];
1214 			*op->resnull = fcinfo->argnull[0];
1215 
1216 			EEO_NEXT();
1217 		}
1218 
1219 		EEO_CASE(EEOP_SQLVALUEFUNCTION)
1220 		{
1221 			/*
1222 			 * Doesn't seem worthwhile to have an inline implementation
1223 			 * efficiency-wise.
1224 			 */
1225 			ExecEvalSQLValueFunction(state, op);
1226 
1227 			EEO_NEXT();
1228 		}
1229 
1230 		EEO_CASE(EEOP_CURRENTOFEXPR)
1231 		{
1232 			/* error invocation uses space, and shouldn't ever occur */
1233 			ExecEvalCurrentOfExpr(state, op);
1234 
1235 			EEO_NEXT();
1236 		}
1237 
1238 		EEO_CASE(EEOP_NEXTVALUEEXPR)
1239 		{
1240 			/*
1241 			 * Doesn't seem worthwhile to have an inline implementation
1242 			 * efficiency-wise.
1243 			 */
1244 			ExecEvalNextValueExpr(state, op);
1245 
1246 			EEO_NEXT();
1247 		}
1248 
1249 		EEO_CASE(EEOP_ARRAYEXPR)
1250 		{
1251 			/* too complex for an inline implementation */
1252 			ExecEvalArrayExpr(state, op);
1253 
1254 			EEO_NEXT();
1255 		}
1256 
1257 		EEO_CASE(EEOP_ARRAYCOERCE)
1258 		{
1259 			/* too complex for an inline implementation */
1260 			ExecEvalArrayCoerce(state, op);
1261 
1262 			EEO_NEXT();
1263 		}
1264 
1265 		EEO_CASE(EEOP_ROW)
1266 		{
1267 			/* too complex for an inline implementation */
1268 			ExecEvalRow(state, op);
1269 
1270 			EEO_NEXT();
1271 		}
1272 
1273 		EEO_CASE(EEOP_ROWCOMPARE_STEP)
1274 		{
1275 			FunctionCallInfo fcinfo = op->d.rowcompare_step.fcinfo_data;
1276 
1277 			/* force NULL result if strict fn and NULL input */
1278 			if (op->d.rowcompare_step.finfo->fn_strict &&
1279 				(fcinfo->argnull[0] || fcinfo->argnull[1]))
1280 			{
1281 				*op->resnull = true;
1282 				EEO_JUMP(op->d.rowcompare_step.jumpnull);
1283 			}
1284 
1285 			/* Apply comparison function */
1286 			fcinfo->isnull = false;
1287 			*op->resvalue = (op->d.rowcompare_step.fn_addr) (fcinfo);
1288 
1289 			/* force NULL result if NULL function result */
1290 			if (fcinfo->isnull)
1291 			{
1292 				*op->resnull = true;
1293 				EEO_JUMP(op->d.rowcompare_step.jumpnull);
1294 			}
1295 			*op->resnull = false;
1296 
1297 			/* If unequal, no need to compare remaining columns */
1298 			if (DatumGetInt32(*op->resvalue) != 0)
1299 			{
1300 				EEO_JUMP(op->d.rowcompare_step.jumpdone);
1301 			}
1302 
1303 			EEO_NEXT();
1304 		}
1305 
1306 		EEO_CASE(EEOP_ROWCOMPARE_FINAL)
1307 		{
1308 			int32		cmpresult = DatumGetInt32(*op->resvalue);
1309 			RowCompareType rctype = op->d.rowcompare_final.rctype;
1310 
1311 			*op->resnull = false;
1312 			switch (rctype)
1313 			{
1314 					/* EQ and NE cases aren't allowed here */
1315 				case ROWCOMPARE_LT:
1316 					*op->resvalue = BoolGetDatum(cmpresult < 0);
1317 					break;
1318 				case ROWCOMPARE_LE:
1319 					*op->resvalue = BoolGetDatum(cmpresult <= 0);
1320 					break;
1321 				case ROWCOMPARE_GE:
1322 					*op->resvalue = BoolGetDatum(cmpresult >= 0);
1323 					break;
1324 				case ROWCOMPARE_GT:
1325 					*op->resvalue = BoolGetDatum(cmpresult > 0);
1326 					break;
1327 				default:
1328 					Assert(false);
1329 					break;
1330 			}
1331 
1332 			EEO_NEXT();
1333 		}
1334 
1335 		EEO_CASE(EEOP_MINMAX)
1336 		{
1337 			/* too complex for an inline implementation */
1338 			ExecEvalMinMax(state, op);
1339 
1340 			EEO_NEXT();
1341 		}
1342 
1343 		EEO_CASE(EEOP_FIELDSELECT)
1344 		{
1345 			/* too complex for an inline implementation */
1346 			ExecEvalFieldSelect(state, op, econtext);
1347 
1348 			EEO_NEXT();
1349 		}
1350 
1351 		EEO_CASE(EEOP_FIELDSTORE_DEFORM)
1352 		{
1353 			/* too complex for an inline implementation */
1354 			ExecEvalFieldStoreDeForm(state, op, econtext);
1355 
1356 			EEO_NEXT();
1357 		}
1358 
1359 		EEO_CASE(EEOP_FIELDSTORE_FORM)
1360 		{
1361 			/* too complex for an inline implementation */
1362 			ExecEvalFieldStoreForm(state, op, econtext);
1363 
1364 			EEO_NEXT();
1365 		}
1366 
1367 		EEO_CASE(EEOP_ARRAYREF_SUBSCRIPT)
1368 		{
1369 			/* Process an array subscript */
1370 
1371 			/* too complex for an inline implementation */
1372 			if (ExecEvalArrayRefSubscript(state, op))
1373 			{
1374 				EEO_NEXT();
1375 			}
1376 			else
1377 			{
1378 				/* Subscript is null, short-circuit ArrayRef to NULL */
1379 				EEO_JUMP(op->d.arrayref_subscript.jumpdone);
1380 			}
1381 		}
1382 
1383 		EEO_CASE(EEOP_ARRAYREF_OLD)
1384 		{
1385 			/*
1386 			 * Fetch the old value in an arrayref assignment, in case it's
1387 			 * referenced (via a CaseTestExpr) inside the assignment
1388 			 * expression.
1389 			 */
1390 
1391 			/* too complex for an inline implementation */
1392 			ExecEvalArrayRefOld(state, op);
1393 
1394 			EEO_NEXT();
1395 		}
1396 
1397 		/*
1398 		 * Perform ArrayRef assignment
1399 		 */
1400 		EEO_CASE(EEOP_ARRAYREF_ASSIGN)
1401 		{
1402 			/* too complex for an inline implementation */
1403 			ExecEvalArrayRefAssign(state, op);
1404 
1405 			EEO_NEXT();
1406 		}
1407 
1408 		/*
1409 		 * Fetch subset of an array.
1410 		 */
1411 		EEO_CASE(EEOP_ARRAYREF_FETCH)
1412 		{
1413 			/* too complex for an inline implementation */
1414 			ExecEvalArrayRefFetch(state, op);
1415 
1416 			EEO_NEXT();
1417 		}
1418 
1419 		EEO_CASE(EEOP_CONVERT_ROWTYPE)
1420 		{
1421 			/* too complex for an inline implementation */
1422 			ExecEvalConvertRowtype(state, op, econtext);
1423 
1424 			EEO_NEXT();
1425 		}
1426 
1427 		EEO_CASE(EEOP_SCALARARRAYOP)
1428 		{
1429 			/* too complex for an inline implementation */
1430 			ExecEvalScalarArrayOp(state, op);
1431 
1432 			EEO_NEXT();
1433 		}
1434 
1435 		EEO_CASE(EEOP_DOMAIN_NOTNULL)
1436 		{
1437 			/* too complex for an inline implementation */
1438 			ExecEvalConstraintNotNull(state, op);
1439 
1440 			EEO_NEXT();
1441 		}
1442 
1443 		EEO_CASE(EEOP_DOMAIN_CHECK)
1444 		{
1445 			/* too complex for an inline implementation */
1446 			ExecEvalConstraintCheck(state, op);
1447 
1448 			EEO_NEXT();
1449 		}
1450 
1451 		EEO_CASE(EEOP_XMLEXPR)
1452 		{
1453 			/* too complex for an inline implementation */
1454 			ExecEvalXmlExpr(state, op);
1455 
1456 			EEO_NEXT();
1457 		}
1458 
1459 		EEO_CASE(EEOP_AGGREF)
1460 		{
1461 			/*
1462 			 * Returns a Datum whose value is the precomputed aggregate value
1463 			 * found in the given expression context.
1464 			 */
1465 			AggrefExprState *aggref = op->d.aggref.astate;
1466 
1467 			Assert(econtext->ecxt_aggvalues != NULL);
1468 
1469 			*op->resvalue = econtext->ecxt_aggvalues[aggref->aggno];
1470 			*op->resnull = econtext->ecxt_aggnulls[aggref->aggno];
1471 
1472 			EEO_NEXT();
1473 		}
1474 
1475 		EEO_CASE(EEOP_GROUPING_FUNC)
1476 		{
1477 			/* too complex/uncommon for an inline implementation */
1478 			ExecEvalGroupingFunc(state, op);
1479 
1480 			EEO_NEXT();
1481 		}
1482 
1483 		EEO_CASE(EEOP_WINDOW_FUNC)
1484 		{
1485 			/*
1486 			 * Like Aggref, just return a precomputed value from the econtext.
1487 			 */
1488 			WindowFuncExprState *wfunc = op->d.window_func.wfstate;
1489 
1490 			Assert(econtext->ecxt_aggvalues != NULL);
1491 
1492 			*op->resvalue = econtext->ecxt_aggvalues[wfunc->wfuncno];
1493 			*op->resnull = econtext->ecxt_aggnulls[wfunc->wfuncno];
1494 
1495 			EEO_NEXT();
1496 		}
1497 
1498 		EEO_CASE(EEOP_SUBPLAN)
1499 		{
1500 			/* too complex for an inline implementation */
1501 			ExecEvalSubPlan(state, op, econtext);
1502 
1503 			EEO_NEXT();
1504 		}
1505 
1506 		EEO_CASE(EEOP_ALTERNATIVE_SUBPLAN)
1507 		{
1508 			/* too complex for an inline implementation */
1509 			ExecEvalAlternativeSubPlan(state, op, econtext);
1510 
1511 			EEO_NEXT();
1512 		}
1513 
1514 		EEO_CASE(EEOP_LAST)
1515 		{
1516 			/* unreachable */
1517 			Assert(false);
1518 			goto out;
1519 		}
1520 	}
1521 
1522 out:
1523 	*isnull = state->resnull;
1524 	return state->resvalue;
1525 }
1526 
1527 /*
1528  * Check whether a user attribute in a slot can be referenced by a Var
1529  * expression.  This should succeed unless there have been schema changes
1530  * since the expression tree has been created.
1531  */
1532 static void
CheckVarSlotCompatibility(TupleTableSlot * slot,int attnum,Oid vartype)1533 CheckVarSlotCompatibility(TupleTableSlot *slot, int attnum, Oid vartype)
1534 {
1535 	/*
1536 	 * What we have to check for here is the possibility of an attribute
1537 	 * having been dropped or changed in type since the plan tree was created.
1538 	 * Ideally the plan will get invalidated and not re-used, but just in
1539 	 * case, we keep these defenses.  Fortunately it's sufficient to check
1540 	 * once on the first time through.
1541 	 *
1542 	 * Note: ideally we'd check typmod as well as typid, but that seems
1543 	 * impractical at the moment: in many cases the tupdesc will have been
1544 	 * generated by ExecTypeFromTL(), and that can't guarantee to generate an
1545 	 * accurate typmod in all cases, because some expression node types don't
1546 	 * carry typmod.  Fortunately, for precisely that reason, there should be
1547 	 * no places with a critical dependency on the typmod of a value.
1548 	 *
1549 	 * System attributes don't require checking since their types never
1550 	 * change.
1551 	 */
1552 	if (attnum > 0)
1553 	{
1554 		TupleDesc	slot_tupdesc = slot->tts_tupleDescriptor;
1555 		Form_pg_attribute attr;
1556 
1557 		if (attnum > slot_tupdesc->natts)	/* should never happen */
1558 			elog(ERROR, "attribute number %d exceeds number of columns %d",
1559 				 attnum, slot_tupdesc->natts);
1560 
1561 		attr = slot_tupdesc->attrs[attnum - 1];
1562 
1563 		if (attr->attisdropped)
1564 			ereport(ERROR,
1565 					(errcode(ERRCODE_UNDEFINED_COLUMN),
1566 					 errmsg("attribute %d of type %s has been dropped",
1567 							attnum, format_type_be(slot_tupdesc->tdtypeid))));
1568 
1569 		if (vartype != attr->atttypid)
1570 			ereport(ERROR,
1571 					(errcode(ERRCODE_DATATYPE_MISMATCH),
1572 					 errmsg("attribute %d of type %s has wrong type",
1573 							attnum, format_type_be(slot_tupdesc->tdtypeid)),
1574 					 errdetail("Table has type %s, but query expects %s.",
1575 							   format_type_be(attr->atttypid),
1576 							   format_type_be(vartype))));
1577 	}
1578 }
1579 
1580 /*
1581  * get_cached_rowtype: utility function to lookup a rowtype tupdesc
1582  *
1583  * type_id, typmod: identity of the rowtype
1584  * cache_field: where to cache the TupleDesc pointer in expression state node
1585  *		(field must be initialized to NULL)
1586  * econtext: expression context we are executing in
1587  *
1588  * NOTE: because the shutdown callback will be called during plan rescan,
1589  * must be prepared to re-do this during any node execution; cannot call
1590  * just once during expression initialization.
1591  */
1592 static TupleDesc
get_cached_rowtype(Oid type_id,int32 typmod,TupleDesc * cache_field,ExprContext * econtext)1593 get_cached_rowtype(Oid type_id, int32 typmod,
1594 				   TupleDesc *cache_field, ExprContext *econtext)
1595 {
1596 	TupleDesc	tupDesc = *cache_field;
1597 
1598 	/* Do lookup if no cached value or if requested type changed */
1599 	if (tupDesc == NULL ||
1600 		type_id != tupDesc->tdtypeid ||
1601 		typmod != tupDesc->tdtypmod)
1602 	{
1603 		tupDesc = lookup_rowtype_tupdesc(type_id, typmod);
1604 
1605 		if (*cache_field)
1606 		{
1607 			/* Release old tupdesc; but callback is already registered */
1608 			ReleaseTupleDesc(*cache_field);
1609 		}
1610 		else
1611 		{
1612 			/* Need to register shutdown callback to release tupdesc */
1613 			RegisterExprContextCallback(econtext,
1614 										ShutdownTupleDescRef,
1615 										PointerGetDatum(cache_field));
1616 		}
1617 		*cache_field = tupDesc;
1618 	}
1619 	return tupDesc;
1620 }
1621 
1622 /*
1623  * Callback function to release a tupdesc refcount at econtext shutdown
1624  */
1625 static void
ShutdownTupleDescRef(Datum arg)1626 ShutdownTupleDescRef(Datum arg)
1627 {
1628 	TupleDesc  *cache_field = (TupleDesc *) DatumGetPointer(arg);
1629 
1630 	if (*cache_field)
1631 		ReleaseTupleDesc(*cache_field);
1632 	*cache_field = NULL;
1633 }
1634 
1635 /*
1636  * Fast-path functions, for very simple expressions
1637  */
1638 
1639 /* Simple reference to inner Var, first time through */
1640 static Datum
ExecJustInnerVarFirst(ExprState * state,ExprContext * econtext,bool * isnull)1641 ExecJustInnerVarFirst(ExprState *state, ExprContext *econtext, bool *isnull)
1642 {
1643 	ExprEvalStep *op = &state->steps[1];
1644 	int			attnum = op->d.var.attnum + 1;
1645 	TupleTableSlot *slot = econtext->ecxt_innertuple;
1646 
1647 	/* See ExecInterpExpr()'s comments for EEOP_INNER_VAR_FIRST */
1648 
1649 	CheckVarSlotCompatibility(slot, attnum, op->d.var.vartype);
1650 	op->opcode = EEOP_INNER_VAR;	/* just for cleanliness */
1651 	state->evalfunc = ExecJustInnerVar;
1652 
1653 	/*
1654 	 * Since we use slot_getattr(), we don't need to implement the FETCHSOME
1655 	 * step explicitly, and we also needn't Assert that the attnum is in range
1656 	 * --- slot_getattr() will take care of any problems.
1657 	 */
1658 	return slot_getattr(slot, attnum, isnull);
1659 }
1660 
1661 /* Simple reference to inner Var */
1662 static Datum
ExecJustInnerVar(ExprState * state,ExprContext * econtext,bool * isnull)1663 ExecJustInnerVar(ExprState *state, ExprContext *econtext, bool *isnull)
1664 {
1665 	ExprEvalStep *op = &state->steps[1];
1666 	int			attnum = op->d.var.attnum + 1;
1667 	TupleTableSlot *slot = econtext->ecxt_innertuple;
1668 
1669 	/* See comments in ExecJustInnerVarFirst */
1670 	return slot_getattr(slot, attnum, isnull);
1671 }
1672 
1673 /* Simple reference to outer Var, first time through */
1674 static Datum
ExecJustOuterVarFirst(ExprState * state,ExprContext * econtext,bool * isnull)1675 ExecJustOuterVarFirst(ExprState *state, ExprContext *econtext, bool *isnull)
1676 {
1677 	ExprEvalStep *op = &state->steps[1];
1678 	int			attnum = op->d.var.attnum + 1;
1679 	TupleTableSlot *slot = econtext->ecxt_outertuple;
1680 
1681 	CheckVarSlotCompatibility(slot, attnum, op->d.var.vartype);
1682 	op->opcode = EEOP_OUTER_VAR;	/* just for cleanliness */
1683 	state->evalfunc = ExecJustOuterVar;
1684 
1685 	/* See comments in ExecJustInnerVarFirst */
1686 	return slot_getattr(slot, attnum, isnull);
1687 }
1688 
1689 /* Simple reference to outer Var */
1690 static Datum
ExecJustOuterVar(ExprState * state,ExprContext * econtext,bool * isnull)1691 ExecJustOuterVar(ExprState *state, ExprContext *econtext, bool *isnull)
1692 {
1693 	ExprEvalStep *op = &state->steps[1];
1694 	int			attnum = op->d.var.attnum + 1;
1695 	TupleTableSlot *slot = econtext->ecxt_outertuple;
1696 
1697 	/* See comments in ExecJustInnerVarFirst */
1698 	return slot_getattr(slot, attnum, isnull);
1699 }
1700 
1701 /* Simple reference to scan Var, first time through */
1702 static Datum
ExecJustScanVarFirst(ExprState * state,ExprContext * econtext,bool * isnull)1703 ExecJustScanVarFirst(ExprState *state, ExprContext *econtext, bool *isnull)
1704 {
1705 	ExprEvalStep *op = &state->steps[1];
1706 	int			attnum = op->d.var.attnum + 1;
1707 	TupleTableSlot *slot = econtext->ecxt_scantuple;
1708 
1709 	CheckVarSlotCompatibility(slot, attnum, op->d.var.vartype);
1710 	op->opcode = EEOP_SCAN_VAR; /* just for cleanliness */
1711 	state->evalfunc = ExecJustScanVar;
1712 
1713 	/* See comments in ExecJustInnerVarFirst */
1714 	return slot_getattr(slot, attnum, isnull);
1715 }
1716 
1717 /* Simple reference to scan Var */
1718 static Datum
ExecJustScanVar(ExprState * state,ExprContext * econtext,bool * isnull)1719 ExecJustScanVar(ExprState *state, ExprContext *econtext, bool *isnull)
1720 {
1721 	ExprEvalStep *op = &state->steps[1];
1722 	int			attnum = op->d.var.attnum + 1;
1723 	TupleTableSlot *slot = econtext->ecxt_scantuple;
1724 
1725 	/* See comments in ExecJustInnerVarFirst */
1726 	return slot_getattr(slot, attnum, isnull);
1727 }
1728 
1729 /* Simple Const expression */
1730 static Datum
ExecJustConst(ExprState * state,ExprContext * econtext,bool * isnull)1731 ExecJustConst(ExprState *state, ExprContext *econtext, bool *isnull)
1732 {
1733 	ExprEvalStep *op = &state->steps[0];
1734 
1735 	*isnull = op->d.constval.isnull;
1736 	return op->d.constval.value;
1737 }
1738 
1739 /* Evaluate inner Var and assign to appropriate column of result tuple */
1740 static Datum
ExecJustAssignInnerVar(ExprState * state,ExprContext * econtext,bool * isnull)1741 ExecJustAssignInnerVar(ExprState *state, ExprContext *econtext, bool *isnull)
1742 {
1743 	ExprEvalStep *op = &state->steps[1];
1744 	int			attnum = op->d.assign_var.attnum + 1;
1745 	int			resultnum = op->d.assign_var.resultnum;
1746 	TupleTableSlot *inslot = econtext->ecxt_innertuple;
1747 	TupleTableSlot *outslot = state->resultslot;
1748 
1749 	/*
1750 	 * We do not need CheckVarSlotCompatibility here; that was taken care of
1751 	 * at compilation time.
1752 	 *
1753 	 * Since we use slot_getattr(), we don't need to implement the FETCHSOME
1754 	 * step explicitly, and we also needn't Assert that the attnum is in range
1755 	 * --- slot_getattr() will take care of any problems.  Nonetheless, check
1756 	 * that resultnum is in range.
1757 	 */
1758 	Assert(resultnum >= 0 && resultnum < outslot->tts_tupleDescriptor->natts);
1759 	outslot->tts_values[resultnum] =
1760 		slot_getattr(inslot, attnum, &outslot->tts_isnull[resultnum]);
1761 	return 0;
1762 }
1763 
1764 /* Evaluate outer Var and assign to appropriate column of result tuple */
1765 static Datum
ExecJustAssignOuterVar(ExprState * state,ExprContext * econtext,bool * isnull)1766 ExecJustAssignOuterVar(ExprState *state, ExprContext *econtext, bool *isnull)
1767 {
1768 	ExprEvalStep *op = &state->steps[1];
1769 	int			attnum = op->d.assign_var.attnum + 1;
1770 	int			resultnum = op->d.assign_var.resultnum;
1771 	TupleTableSlot *inslot = econtext->ecxt_outertuple;
1772 	TupleTableSlot *outslot = state->resultslot;
1773 
1774 	/* See comments in ExecJustAssignInnerVar */
1775 	Assert(resultnum >= 0 && resultnum < outslot->tts_tupleDescriptor->natts);
1776 	outslot->tts_values[resultnum] =
1777 		slot_getattr(inslot, attnum, &outslot->tts_isnull[resultnum]);
1778 	return 0;
1779 }
1780 
1781 /* Evaluate scan Var and assign to appropriate column of result tuple */
1782 static Datum
ExecJustAssignScanVar(ExprState * state,ExprContext * econtext,bool * isnull)1783 ExecJustAssignScanVar(ExprState *state, ExprContext *econtext, bool *isnull)
1784 {
1785 	ExprEvalStep *op = &state->steps[1];
1786 	int			attnum = op->d.assign_var.attnum + 1;
1787 	int			resultnum = op->d.assign_var.resultnum;
1788 	TupleTableSlot *inslot = econtext->ecxt_scantuple;
1789 	TupleTableSlot *outslot = state->resultslot;
1790 
1791 	/* See comments in ExecJustAssignInnerVar */
1792 	Assert(resultnum >= 0 && resultnum < outslot->tts_tupleDescriptor->natts);
1793 	outslot->tts_values[resultnum] =
1794 		slot_getattr(inslot, attnum, &outslot->tts_isnull[resultnum]);
1795 	return 0;
1796 }
1797 
1798 
1799 /*
1800  * Do one-time initialization of interpretation machinery.
1801  */
1802 static void
ExecInitInterpreter(void)1803 ExecInitInterpreter(void)
1804 {
1805 #if defined(EEO_USE_COMPUTED_GOTO)
1806 	/* Set up externally-visible pointer to dispatch table */
1807 	if (dispatch_table == NULL)
1808 		dispatch_table = (const void **)
1809 			DatumGetPointer(ExecInterpExpr(NULL, NULL, NULL));
1810 #endif
1811 }
1812 
1813 /*
1814  * Function to return the opcode of an expression step.
1815  *
1816  * When direct-threading is in use, ExprState->opcode isn't easily
1817  * decipherable. This function returns the appropriate enum member.
1818  *
1819  * This currently is only supposed to be used in paths that aren't critical
1820  * performance-wise.  If that changes, we could add an inverse dispatch_table
1821  * that's sorted on the address, so a binary search can be performed.
1822  */
1823 ExprEvalOp
ExecEvalStepOp(ExprState * state,ExprEvalStep * op)1824 ExecEvalStepOp(ExprState *state, ExprEvalStep *op)
1825 {
1826 #if defined(EEO_USE_COMPUTED_GOTO)
1827 	if (state->flags & EEO_FLAG_DIRECT_THREADED)
1828 	{
1829 		int			i;
1830 
1831 		for (i = 0; i < EEOP_LAST; i++)
1832 		{
1833 			if ((void *) op->opcode == dispatch_table[i])
1834 			{
1835 				return (ExprEvalOp) i;
1836 			}
1837 		}
1838 		elog(ERROR, "unknown opcode");
1839 	}
1840 #endif
1841 	return (ExprEvalOp) op->opcode;
1842 }
1843 
1844 
1845 /*
1846  * Out-of-line helper functions for complex instructions.
1847  */
1848 
1849 /*
1850  * Evaluate a PARAM_EXEC parameter.
1851  *
1852  * PARAM_EXEC params (internal executor parameters) are stored in the
1853  * ecxt_param_exec_vals array, and can be accessed by array index.
1854  */
1855 void
ExecEvalParamExec(ExprState * state,ExprEvalStep * op,ExprContext * econtext)1856 ExecEvalParamExec(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
1857 {
1858 	ParamExecData *prm;
1859 
1860 	prm = &(econtext->ecxt_param_exec_vals[op->d.param.paramid]);
1861 	if (unlikely(prm->execPlan != NULL))
1862 	{
1863 		/* Parameter not evaluated yet, so go do it */
1864 		ExecSetParamPlan(prm->execPlan, econtext);
1865 		/* ExecSetParamPlan should have processed this param... */
1866 		Assert(prm->execPlan == NULL);
1867 	}
1868 	*op->resvalue = prm->value;
1869 	*op->resnull = prm->isnull;
1870 }
1871 
1872 /*
1873  * Evaluate a PARAM_EXTERN parameter.
1874  *
1875  * PARAM_EXTERN parameters must be sought in ecxt_param_list_info.
1876  */
1877 void
ExecEvalParamExtern(ExprState * state,ExprEvalStep * op,ExprContext * econtext)1878 ExecEvalParamExtern(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
1879 {
1880 	ParamListInfo paramInfo = econtext->ecxt_param_list_info;
1881 	int			paramId = op->d.param.paramid;
1882 
1883 	if (likely(paramInfo &&
1884 			   paramId > 0 && paramId <= paramInfo->numParams))
1885 	{
1886 		ParamExternData *prm = &paramInfo->params[paramId - 1];
1887 
1888 		/* give hook a chance in case parameter is dynamic */
1889 		if (!OidIsValid(prm->ptype) && paramInfo->paramFetch != NULL)
1890 			(*paramInfo->paramFetch) (paramInfo, paramId);
1891 
1892 		if (likely(OidIsValid(prm->ptype)))
1893 		{
1894 			/* safety check in case hook did something unexpected */
1895 			if (unlikely(prm->ptype != op->d.param.paramtype))
1896 				ereport(ERROR,
1897 						(errcode(ERRCODE_DATATYPE_MISMATCH),
1898 						 errmsg("type of parameter %d (%s) does not match that when preparing the plan (%s)",
1899 								paramId,
1900 								format_type_be(prm->ptype),
1901 								format_type_be(op->d.param.paramtype))));
1902 			*op->resvalue = prm->value;
1903 			*op->resnull = prm->isnull;
1904 			return;
1905 		}
1906 	}
1907 
1908 	ereport(ERROR,
1909 			(errcode(ERRCODE_UNDEFINED_OBJECT),
1910 			 errmsg("no value found for parameter %d", paramId)));
1911 }
1912 
1913 /*
1914  * Evaluate a SQLValueFunction expression.
1915  */
1916 void
ExecEvalSQLValueFunction(ExprState * state,ExprEvalStep * op)1917 ExecEvalSQLValueFunction(ExprState *state, ExprEvalStep *op)
1918 {
1919 	SQLValueFunction *svf = op->d.sqlvaluefunction.svf;
1920 	FunctionCallInfoData fcinfo;
1921 
1922 	*op->resnull = false;
1923 
1924 	/*
1925 	 * Note: current_schema() can return NULL.  current_user() etc currently
1926 	 * cannot, but might as well code those cases the same way for safety.
1927 	 */
1928 	switch (svf->op)
1929 	{
1930 		case SVFOP_CURRENT_DATE:
1931 			*op->resvalue = DateADTGetDatum(GetSQLCurrentDate());
1932 			break;
1933 		case SVFOP_CURRENT_TIME:
1934 		case SVFOP_CURRENT_TIME_N:
1935 			*op->resvalue = TimeTzADTPGetDatum(GetSQLCurrentTime(svf->typmod));
1936 			break;
1937 		case SVFOP_CURRENT_TIMESTAMP:
1938 		case SVFOP_CURRENT_TIMESTAMP_N:
1939 			*op->resvalue = TimestampTzGetDatum(GetSQLCurrentTimestamp(svf->typmod));
1940 			break;
1941 		case SVFOP_LOCALTIME:
1942 		case SVFOP_LOCALTIME_N:
1943 			*op->resvalue = TimeADTGetDatum(GetSQLLocalTime(svf->typmod));
1944 			break;
1945 		case SVFOP_LOCALTIMESTAMP:
1946 		case SVFOP_LOCALTIMESTAMP_N:
1947 			*op->resvalue = TimestampGetDatum(GetSQLLocalTimestamp(svf->typmod));
1948 			break;
1949 		case SVFOP_CURRENT_ROLE:
1950 		case SVFOP_CURRENT_USER:
1951 		case SVFOP_USER:
1952 			InitFunctionCallInfoData(fcinfo, NULL, 0, InvalidOid, NULL, NULL);
1953 			*op->resvalue = current_user(&fcinfo);
1954 			*op->resnull = fcinfo.isnull;
1955 			break;
1956 		case SVFOP_SESSION_USER:
1957 			InitFunctionCallInfoData(fcinfo, NULL, 0, InvalidOid, NULL, NULL);
1958 			*op->resvalue = session_user(&fcinfo);
1959 			*op->resnull = fcinfo.isnull;
1960 			break;
1961 		case SVFOP_CURRENT_CATALOG:
1962 			InitFunctionCallInfoData(fcinfo, NULL, 0, InvalidOid, NULL, NULL);
1963 			*op->resvalue = current_database(&fcinfo);
1964 			*op->resnull = fcinfo.isnull;
1965 			break;
1966 		case SVFOP_CURRENT_SCHEMA:
1967 			InitFunctionCallInfoData(fcinfo, NULL, 0, InvalidOid, NULL, NULL);
1968 			*op->resvalue = current_schema(&fcinfo);
1969 			*op->resnull = fcinfo.isnull;
1970 			break;
1971 	}
1972 }
1973 
1974 /*
1975  * Raise error if a CURRENT OF expression is evaluated.
1976  *
1977  * The planner should convert CURRENT OF into a TidScan qualification, or some
1978  * other special handling in a ForeignScan node.  So we have to be able to do
1979  * ExecInitExpr on a CurrentOfExpr, but we shouldn't ever actually execute it.
1980  * If we get here, we suppose we must be dealing with CURRENT OF on a foreign
1981  * table whose FDW doesn't handle it, and complain accordingly.
1982  */
1983 void
ExecEvalCurrentOfExpr(ExprState * state,ExprEvalStep * op)1984 ExecEvalCurrentOfExpr(ExprState *state, ExprEvalStep *op)
1985 {
1986 	ereport(ERROR,
1987 			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1988 			 errmsg("WHERE CURRENT OF is not supported for this table type")));
1989 }
1990 
1991 /*
1992  * Evaluate NextValueExpr.
1993  */
1994 void
ExecEvalNextValueExpr(ExprState * state,ExprEvalStep * op)1995 ExecEvalNextValueExpr(ExprState *state, ExprEvalStep *op)
1996 {
1997 	int64		newval = nextval_internal(op->d.nextvalueexpr.seqid, false);
1998 
1999 	switch (op->d.nextvalueexpr.seqtypid)
2000 	{
2001 		case INT2OID:
2002 			*op->resvalue = Int16GetDatum((int16) newval);
2003 			break;
2004 		case INT4OID:
2005 			*op->resvalue = Int32GetDatum((int32) newval);
2006 			break;
2007 		case INT8OID:
2008 			*op->resvalue = Int64GetDatum((int64) newval);
2009 			break;
2010 		default:
2011 			elog(ERROR, "unsupported sequence type %u",
2012 				 op->d.nextvalueexpr.seqtypid);
2013 	}
2014 	*op->resnull = false;
2015 }
2016 
2017 /*
2018  * Evaluate NullTest / IS NULL for rows.
2019  */
2020 void
ExecEvalRowNull(ExprState * state,ExprEvalStep * op,ExprContext * econtext)2021 ExecEvalRowNull(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
2022 {
2023 	ExecEvalRowNullInt(state, op, econtext, true);
2024 }
2025 
2026 /*
2027  * Evaluate NullTest / IS NOT NULL for rows.
2028  */
2029 void
ExecEvalRowNotNull(ExprState * state,ExprEvalStep * op,ExprContext * econtext)2030 ExecEvalRowNotNull(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
2031 {
2032 	ExecEvalRowNullInt(state, op, econtext, false);
2033 }
2034 
2035 /* Common code for IS [NOT] NULL on a row value */
2036 static void
ExecEvalRowNullInt(ExprState * state,ExprEvalStep * op,ExprContext * econtext,bool checkisnull)2037 ExecEvalRowNullInt(ExprState *state, ExprEvalStep *op,
2038 				   ExprContext *econtext, bool checkisnull)
2039 {
2040 	Datum		value = *op->resvalue;
2041 	bool		isnull = *op->resnull;
2042 	HeapTupleHeader tuple;
2043 	Oid			tupType;
2044 	int32		tupTypmod;
2045 	TupleDesc	tupDesc;
2046 	HeapTupleData tmptup;
2047 	int			att;
2048 
2049 	*op->resnull = false;
2050 
2051 	/* NULL row variables are treated just as NULL scalar columns */
2052 	if (isnull)
2053 	{
2054 		*op->resvalue = BoolGetDatum(checkisnull);
2055 		return;
2056 	}
2057 
2058 	/*
2059 	 * The SQL standard defines IS [NOT] NULL for a non-null rowtype argument
2060 	 * as:
2061 	 *
2062 	 * "R IS NULL" is true if every field is the null value.
2063 	 *
2064 	 * "R IS NOT NULL" is true if no field is the null value.
2065 	 *
2066 	 * This definition is (apparently intentionally) not recursive; so our
2067 	 * tests on the fields are primitive attisnull tests, not recursive checks
2068 	 * to see if they are all-nulls or no-nulls rowtypes.
2069 	 *
2070 	 * The standard does not consider the possibility of zero-field rows, but
2071 	 * here we consider them to vacuously satisfy both predicates.
2072 	 */
2073 
2074 	tuple = DatumGetHeapTupleHeader(value);
2075 
2076 	tupType = HeapTupleHeaderGetTypeId(tuple);
2077 	tupTypmod = HeapTupleHeaderGetTypMod(tuple);
2078 
2079 	/* Lookup tupdesc if first time through or if type changes */
2080 	tupDesc = get_cached_rowtype(tupType, tupTypmod,
2081 								 &op->d.nulltest_row.argdesc,
2082 								 econtext);
2083 
2084 	/*
2085 	 * heap_attisnull needs a HeapTuple not a bare HeapTupleHeader.
2086 	 */
2087 	tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
2088 	tmptup.t_data = tuple;
2089 
2090 	for (att = 1; att <= tupDesc->natts; att++)
2091 	{
2092 		/* ignore dropped columns */
2093 		if (tupDesc->attrs[att - 1]->attisdropped)
2094 			continue;
2095 		if (heap_attisnull(&tmptup, att))
2096 		{
2097 			/* null field disproves IS NOT NULL */
2098 			if (!checkisnull)
2099 			{
2100 				*op->resvalue = BoolGetDatum(false);
2101 				return;
2102 			}
2103 		}
2104 		else
2105 		{
2106 			/* non-null field disproves IS NULL */
2107 			if (checkisnull)
2108 			{
2109 				*op->resvalue = BoolGetDatum(false);
2110 				return;
2111 			}
2112 		}
2113 	}
2114 
2115 	*op->resvalue = BoolGetDatum(true);
2116 }
2117 
2118 /*
2119  * Evaluate an ARRAY[] expression.
2120  *
2121  * The individual array elements (or subarrays) have already been evaluated
2122  * into op->d.arrayexpr.elemvalues[]/elemnulls[].
2123  */
2124 void
ExecEvalArrayExpr(ExprState * state,ExprEvalStep * op)2125 ExecEvalArrayExpr(ExprState *state, ExprEvalStep *op)
2126 {
2127 	ArrayType  *result;
2128 	Oid			element_type = op->d.arrayexpr.elemtype;
2129 	int			nelems = op->d.arrayexpr.nelems;
2130 	int			ndims = 0;
2131 	int			dims[MAXDIM];
2132 	int			lbs[MAXDIM];
2133 
2134 	/* Set non-null as default */
2135 	*op->resnull = false;
2136 
2137 	if (!op->d.arrayexpr.multidims)
2138 	{
2139 		/* Elements are presumably of scalar type */
2140 		Datum	   *dvalues = op->d.arrayexpr.elemvalues;
2141 		bool	   *dnulls = op->d.arrayexpr.elemnulls;
2142 
2143 		/* Shouldn't happen here, but if length is 0, return empty array */
2144 		if (nelems == 0)
2145 		{
2146 			*op->resvalue =
2147 				PointerGetDatum(construct_empty_array(element_type));
2148 			return;
2149 		}
2150 
2151 		/* setup for 1-D array of the given length */
2152 		ndims = 1;
2153 		dims[0] = nelems;
2154 		lbs[0] = 1;
2155 
2156 		result = construct_md_array(dvalues, dnulls, ndims, dims, lbs,
2157 									element_type,
2158 									op->d.arrayexpr.elemlength,
2159 									op->d.arrayexpr.elembyval,
2160 									op->d.arrayexpr.elemalign);
2161 	}
2162 	else
2163 	{
2164 		/* Must be nested array expressions */
2165 		int			nbytes = 0;
2166 		int			nitems = 0;
2167 		int			outer_nelems = 0;
2168 		int			elem_ndims = 0;
2169 		int		   *elem_dims = NULL;
2170 		int		   *elem_lbs = NULL;
2171 		bool		firstone = true;
2172 		bool		havenulls = false;
2173 		bool		haveempty = false;
2174 		char	  **subdata;
2175 		bits8	  **subbitmaps;
2176 		int		   *subbytes;
2177 		int		   *subnitems;
2178 		int32		dataoffset;
2179 		char	   *dat;
2180 		int			iitem;
2181 		int			elemoff;
2182 		int			i;
2183 
2184 		subdata = (char **) palloc(nelems * sizeof(char *));
2185 		subbitmaps = (bits8 **) palloc(nelems * sizeof(bits8 *));
2186 		subbytes = (int *) palloc(nelems * sizeof(int));
2187 		subnitems = (int *) palloc(nelems * sizeof(int));
2188 
2189 		/* loop through and get data area from each element */
2190 		for (elemoff = 0; elemoff < nelems; elemoff++)
2191 		{
2192 			Datum		arraydatum;
2193 			bool		eisnull;
2194 			ArrayType  *array;
2195 			int			this_ndims;
2196 
2197 			arraydatum = op->d.arrayexpr.elemvalues[elemoff];
2198 			eisnull = op->d.arrayexpr.elemnulls[elemoff];
2199 
2200 			/* temporarily ignore null subarrays */
2201 			if (eisnull)
2202 			{
2203 				haveempty = true;
2204 				continue;
2205 			}
2206 
2207 			array = DatumGetArrayTypeP(arraydatum);
2208 
2209 			/* run-time double-check on element type */
2210 			if (element_type != ARR_ELEMTYPE(array))
2211 				ereport(ERROR,
2212 						(errcode(ERRCODE_DATATYPE_MISMATCH),
2213 						 errmsg("cannot merge incompatible arrays"),
2214 						 errdetail("Array with element type %s cannot be "
2215 								   "included in ARRAY construct with element type %s.",
2216 								   format_type_be(ARR_ELEMTYPE(array)),
2217 								   format_type_be(element_type))));
2218 
2219 			this_ndims = ARR_NDIM(array);
2220 			/* temporarily ignore zero-dimensional subarrays */
2221 			if (this_ndims <= 0)
2222 			{
2223 				haveempty = true;
2224 				continue;
2225 			}
2226 
2227 			if (firstone)
2228 			{
2229 				/* Get sub-array details from first member */
2230 				elem_ndims = this_ndims;
2231 				ndims = elem_ndims + 1;
2232 				if (ndims <= 0 || ndims > MAXDIM)
2233 					ereport(ERROR,
2234 							(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2235 							 errmsg("number of array dimensions (%d) exceeds " \
2236 									"the maximum allowed (%d)", ndims, MAXDIM)));
2237 
2238 				elem_dims = (int *) palloc(elem_ndims * sizeof(int));
2239 				memcpy(elem_dims, ARR_DIMS(array), elem_ndims * sizeof(int));
2240 				elem_lbs = (int *) palloc(elem_ndims * sizeof(int));
2241 				memcpy(elem_lbs, ARR_LBOUND(array), elem_ndims * sizeof(int));
2242 
2243 				firstone = false;
2244 			}
2245 			else
2246 			{
2247 				/* Check other sub-arrays are compatible */
2248 				if (elem_ndims != this_ndims ||
2249 					memcmp(elem_dims, ARR_DIMS(array),
2250 						   elem_ndims * sizeof(int)) != 0 ||
2251 					memcmp(elem_lbs, ARR_LBOUND(array),
2252 						   elem_ndims * sizeof(int)) != 0)
2253 					ereport(ERROR,
2254 							(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2255 							 errmsg("multidimensional arrays must have array "
2256 									"expressions with matching dimensions")));
2257 			}
2258 
2259 			subdata[outer_nelems] = ARR_DATA_PTR(array);
2260 			subbitmaps[outer_nelems] = ARR_NULLBITMAP(array);
2261 			subbytes[outer_nelems] = ARR_SIZE(array) - ARR_DATA_OFFSET(array);
2262 			nbytes += subbytes[outer_nelems];
2263 			subnitems[outer_nelems] = ArrayGetNItems(this_ndims,
2264 													 ARR_DIMS(array));
2265 			nitems += subnitems[outer_nelems];
2266 			havenulls |= ARR_HASNULL(array);
2267 			outer_nelems++;
2268 		}
2269 
2270 		/*
2271 		 * If all items were null or empty arrays, return an empty array;
2272 		 * otherwise, if some were and some weren't, raise error.  (Note: we
2273 		 * must special-case this somehow to avoid trying to generate a 1-D
2274 		 * array formed from empty arrays.  It's not ideal...)
2275 		 */
2276 		if (haveempty)
2277 		{
2278 			if (ndims == 0)		/* didn't find any nonempty array */
2279 			{
2280 				*op->resvalue = PointerGetDatum(construct_empty_array(element_type));
2281 				return;
2282 			}
2283 			ereport(ERROR,
2284 					(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2285 					 errmsg("multidimensional arrays must have array "
2286 							"expressions with matching dimensions")));
2287 		}
2288 
2289 		/* setup for multi-D array */
2290 		dims[0] = outer_nelems;
2291 		lbs[0] = 1;
2292 		for (i = 1; i < ndims; i++)
2293 		{
2294 			dims[i] = elem_dims[i - 1];
2295 			lbs[i] = elem_lbs[i - 1];
2296 		}
2297 
2298 		/* check for subscript overflow */
2299 		(void) ArrayGetNItems(ndims, dims);
2300 		ArrayCheckBounds(ndims, dims, lbs);
2301 
2302 		if (havenulls)
2303 		{
2304 			dataoffset = ARR_OVERHEAD_WITHNULLS(ndims, nitems);
2305 			nbytes += dataoffset;
2306 		}
2307 		else
2308 		{
2309 			dataoffset = 0;		/* marker for no null bitmap */
2310 			nbytes += ARR_OVERHEAD_NONULLS(ndims);
2311 		}
2312 
2313 		result = (ArrayType *) palloc(nbytes);
2314 		SET_VARSIZE(result, nbytes);
2315 		result->ndim = ndims;
2316 		result->dataoffset = dataoffset;
2317 		result->elemtype = element_type;
2318 		memcpy(ARR_DIMS(result), dims, ndims * sizeof(int));
2319 		memcpy(ARR_LBOUND(result), lbs, ndims * sizeof(int));
2320 
2321 		dat = ARR_DATA_PTR(result);
2322 		iitem = 0;
2323 		for (i = 0; i < outer_nelems; i++)
2324 		{
2325 			memcpy(dat, subdata[i], subbytes[i]);
2326 			dat += subbytes[i];
2327 			if (havenulls)
2328 				array_bitmap_copy(ARR_NULLBITMAP(result), iitem,
2329 								  subbitmaps[i], 0,
2330 								  subnitems[i]);
2331 			iitem += subnitems[i];
2332 		}
2333 	}
2334 
2335 	*op->resvalue = PointerGetDatum(result);
2336 }
2337 
2338 /*
2339  * Evaluate an ArrayCoerceExpr expression.
2340  *
2341  * Source array is in step's result variable.
2342  */
2343 void
ExecEvalArrayCoerce(ExprState * state,ExprEvalStep * op)2344 ExecEvalArrayCoerce(ExprState *state, ExprEvalStep *op)
2345 {
2346 	ArrayCoerceExpr *acoerce = op->d.arraycoerce.coerceexpr;
2347 	Datum		arraydatum;
2348 	FunctionCallInfoData locfcinfo;
2349 
2350 	/* NULL array -> NULL result */
2351 	if (*op->resnull)
2352 		return;
2353 
2354 	arraydatum = *op->resvalue;
2355 
2356 	/*
2357 	 * If it's binary-compatible, modify the element type in the array header,
2358 	 * but otherwise leave the array as we received it.
2359 	 */
2360 	if (!OidIsValid(acoerce->elemfuncid))
2361 	{
2362 		/* Detoast input array if necessary, and copy in any case */
2363 		ArrayType  *array = DatumGetArrayTypePCopy(arraydatum);
2364 
2365 		ARR_ELEMTYPE(array) = op->d.arraycoerce.resultelemtype;
2366 		*op->resvalue = PointerGetDatum(array);
2367 		return;
2368 	}
2369 
2370 	/*
2371 	 * Use array_map to apply the function to each array element.
2372 	 *
2373 	 * We pass on the desttypmod and isExplicit flags whether or not the
2374 	 * function wants them.
2375 	 *
2376 	 * Note: coercion functions are assumed to not use collation.
2377 	 */
2378 	InitFunctionCallInfoData(locfcinfo, op->d.arraycoerce.elemfunc, 3,
2379 							 InvalidOid, NULL, NULL);
2380 	locfcinfo.arg[0] = arraydatum;
2381 	locfcinfo.arg[1] = Int32GetDatum(acoerce->resulttypmod);
2382 	locfcinfo.arg[2] = BoolGetDatum(acoerce->isExplicit);
2383 	locfcinfo.argnull[0] = false;
2384 	locfcinfo.argnull[1] = false;
2385 	locfcinfo.argnull[2] = false;
2386 
2387 	*op->resvalue = array_map(&locfcinfo, op->d.arraycoerce.resultelemtype,
2388 							  op->d.arraycoerce.amstate);
2389 }
2390 
2391 /*
2392  * Evaluate a ROW() expression.
2393  *
2394  * The individual columns have already been evaluated into
2395  * op->d.row.elemvalues[]/elemnulls[].
2396  */
2397 void
ExecEvalRow(ExprState * state,ExprEvalStep * op)2398 ExecEvalRow(ExprState *state, ExprEvalStep *op)
2399 {
2400 	HeapTuple	tuple;
2401 
2402 	/* build tuple from evaluated field values */
2403 	tuple = heap_form_tuple(op->d.row.tupdesc,
2404 							op->d.row.elemvalues,
2405 							op->d.row.elemnulls);
2406 
2407 	*op->resvalue = HeapTupleGetDatum(tuple);
2408 	*op->resnull = false;
2409 }
2410 
2411 /*
2412  * Evaluate GREATEST() or LEAST() expression (note this is *not* MIN()/MAX()).
2413  *
2414  * All of the to-be-compared expressions have already been evaluated into
2415  * op->d.minmax.values[]/nulls[].
2416  */
2417 void
ExecEvalMinMax(ExprState * state,ExprEvalStep * op)2418 ExecEvalMinMax(ExprState *state, ExprEvalStep *op)
2419 {
2420 	Datum	   *values = op->d.minmax.values;
2421 	bool	   *nulls = op->d.minmax.nulls;
2422 	FunctionCallInfo fcinfo = op->d.minmax.fcinfo_data;
2423 	MinMaxOp	operator = op->d.minmax.op;
2424 	int			off;
2425 
2426 	/* set at initialization */
2427 	Assert(fcinfo->argnull[0] == false);
2428 	Assert(fcinfo->argnull[1] == false);
2429 
2430 	/* default to null result */
2431 	*op->resnull = true;
2432 
2433 	for (off = 0; off < op->d.minmax.nelems; off++)
2434 	{
2435 		/* ignore NULL inputs */
2436 		if (nulls[off])
2437 			continue;
2438 
2439 		if (*op->resnull)
2440 		{
2441 			/* first nonnull input, adopt value */
2442 			*op->resvalue = values[off];
2443 			*op->resnull = false;
2444 		}
2445 		else
2446 		{
2447 			int			cmpresult;
2448 
2449 			/* apply comparison function */
2450 			fcinfo->arg[0] = *op->resvalue;
2451 			fcinfo->arg[1] = values[off];
2452 
2453 			fcinfo->isnull = false;
2454 			cmpresult = DatumGetInt32(FunctionCallInvoke(fcinfo));
2455 			if (fcinfo->isnull) /* probably should not happen */
2456 				continue;
2457 
2458 			if (cmpresult > 0 && operator == IS_LEAST)
2459 				*op->resvalue = values[off];
2460 			else if (cmpresult < 0 && operator == IS_GREATEST)
2461 				*op->resvalue = values[off];
2462 		}
2463 	}
2464 }
2465 
2466 /*
2467  * Evaluate a FieldSelect node.
2468  *
2469  * Source record is in step's result variable.
2470  */
2471 void
ExecEvalFieldSelect(ExprState * state,ExprEvalStep * op,ExprContext * econtext)2472 ExecEvalFieldSelect(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
2473 {
2474 	AttrNumber	fieldnum = op->d.fieldselect.fieldnum;
2475 	Datum		tupDatum;
2476 	HeapTupleHeader tuple;
2477 	Oid			tupType;
2478 	int32		tupTypmod;
2479 	TupleDesc	tupDesc;
2480 	Form_pg_attribute attr;
2481 	HeapTupleData tmptup;
2482 
2483 	/* NULL record -> NULL result */
2484 	if (*op->resnull)
2485 		return;
2486 
2487 	/* Get the composite datum and extract its type fields */
2488 	tupDatum = *op->resvalue;
2489 	tuple = DatumGetHeapTupleHeader(tupDatum);
2490 
2491 	tupType = HeapTupleHeaderGetTypeId(tuple);
2492 	tupTypmod = HeapTupleHeaderGetTypMod(tuple);
2493 
2494 	/* Lookup tupdesc if first time through or if type changes */
2495 	tupDesc = get_cached_rowtype(tupType, tupTypmod,
2496 								 &op->d.fieldselect.argdesc,
2497 								 econtext);
2498 
2499 	/*
2500 	 * Find field's attr record.  Note we don't support system columns here: a
2501 	 * datum tuple doesn't have valid values for most of the interesting
2502 	 * system columns anyway.
2503 	 */
2504 	if (fieldnum <= 0)			/* should never happen */
2505 		elog(ERROR, "unsupported reference to system column %d in FieldSelect",
2506 			 fieldnum);
2507 	if (fieldnum > tupDesc->natts)	/* should never happen */
2508 		elog(ERROR, "attribute number %d exceeds number of columns %d",
2509 			 fieldnum, tupDesc->natts);
2510 	attr = tupDesc->attrs[fieldnum - 1];
2511 
2512 	/* Check for dropped column, and force a NULL result if so */
2513 	if (attr->attisdropped)
2514 	{
2515 		*op->resnull = true;
2516 		return;
2517 	}
2518 
2519 	/* Check for type mismatch --- possible after ALTER COLUMN TYPE? */
2520 	/* As in CheckVarSlotCompatibility, we should but can't check typmod */
2521 	if (op->d.fieldselect.resulttype != attr->atttypid)
2522 		ereport(ERROR,
2523 				(errcode(ERRCODE_DATATYPE_MISMATCH),
2524 				 errmsg("attribute %d has wrong type", fieldnum),
2525 				 errdetail("Table has type %s, but query expects %s.",
2526 						   format_type_be(attr->atttypid),
2527 						   format_type_be(op->d.fieldselect.resulttype))));
2528 
2529 	/* heap_getattr needs a HeapTuple not a bare HeapTupleHeader */
2530 	tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
2531 	tmptup.t_data = tuple;
2532 
2533 	/* extract the field */
2534 	*op->resvalue = heap_getattr(&tmptup,
2535 								 fieldnum,
2536 								 tupDesc,
2537 								 op->resnull);
2538 }
2539 
2540 /*
2541  * Deform source tuple, filling in the step's values/nulls arrays, before
2542  * evaluating individual new values as part of a FieldStore expression.
2543  * Subsequent steps will overwrite individual elements of the values/nulls
2544  * arrays with the new field values, and then FIELDSTORE_FORM will build the
2545  * new tuple value.
2546  *
2547  * Source record is in step's result variable.
2548  */
2549 void
ExecEvalFieldStoreDeForm(ExprState * state,ExprEvalStep * op,ExprContext * econtext)2550 ExecEvalFieldStoreDeForm(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
2551 {
2552 	TupleDesc	tupDesc;
2553 
2554 	/* Lookup tupdesc if first time through or after rescan */
2555 	tupDesc = get_cached_rowtype(op->d.fieldstore.fstore->resulttype, -1,
2556 								 op->d.fieldstore.argdesc, econtext);
2557 
2558 	/* Check that current tupdesc doesn't have more fields than we allocated */
2559 	if (unlikely(tupDesc->natts > op->d.fieldstore.ncolumns))
2560 		elog(ERROR, "too many columns in composite type %u",
2561 			 op->d.fieldstore.fstore->resulttype);
2562 
2563 	if (*op->resnull)
2564 	{
2565 		/* Convert null input tuple into an all-nulls row */
2566 		memset(op->d.fieldstore.nulls, true,
2567 			   op->d.fieldstore.ncolumns * sizeof(bool));
2568 	}
2569 	else
2570 	{
2571 		/*
2572 		 * heap_deform_tuple needs a HeapTuple not a bare HeapTupleHeader. We
2573 		 * set all the fields in the struct just in case.
2574 		 */
2575 		Datum		tupDatum = *op->resvalue;
2576 		HeapTupleHeader tuphdr;
2577 		HeapTupleData tmptup;
2578 
2579 		tuphdr = DatumGetHeapTupleHeader(tupDatum);
2580 		tmptup.t_len = HeapTupleHeaderGetDatumLength(tuphdr);
2581 		ItemPointerSetInvalid(&(tmptup.t_self));
2582 		tmptup.t_tableOid = InvalidOid;
2583 		tmptup.t_data = tuphdr;
2584 
2585 		heap_deform_tuple(&tmptup, tupDesc,
2586 						  op->d.fieldstore.values,
2587 						  op->d.fieldstore.nulls);
2588 	}
2589 }
2590 
2591 /*
2592  * Compute the new composite datum after each individual field value of a
2593  * FieldStore expression has been evaluated.
2594  */
2595 void
ExecEvalFieldStoreForm(ExprState * state,ExprEvalStep * op,ExprContext * econtext)2596 ExecEvalFieldStoreForm(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
2597 {
2598 	HeapTuple	tuple;
2599 
2600 	/* argdesc should already be valid from the DeForm step */
2601 	tuple = heap_form_tuple(*op->d.fieldstore.argdesc,
2602 							op->d.fieldstore.values,
2603 							op->d.fieldstore.nulls);
2604 
2605 	*op->resvalue = HeapTupleGetDatum(tuple);
2606 	*op->resnull = false;
2607 }
2608 
2609 /*
2610  * Process a subscript in an ArrayRef expression.
2611  *
2612  * If subscript is NULL, throw error in assignment case, or in fetch case
2613  * set result to NULL and return false (instructing caller to skip the rest
2614  * of the ArrayRef sequence).
2615  *
2616  * Subscript expression result is in subscriptvalue/subscriptnull.
2617  * On success, integer subscript value has been saved in upperindex[] or
2618  * lowerindex[] for use later.
2619  */
2620 bool
ExecEvalArrayRefSubscript(ExprState * state,ExprEvalStep * op)2621 ExecEvalArrayRefSubscript(ExprState *state, ExprEvalStep *op)
2622 {
2623 	ArrayRefState *arefstate = op->d.arrayref_subscript.state;
2624 	int		   *indexes;
2625 	int			off;
2626 
2627 	/* If any index expr yields NULL, result is NULL or error */
2628 	if (arefstate->subscriptnull)
2629 	{
2630 		if (arefstate->isassignment)
2631 			ereport(ERROR,
2632 					(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
2633 					 errmsg("array subscript in assignment must not be null")));
2634 		*op->resnull = true;
2635 		return false;
2636 	}
2637 
2638 	/* Convert datum to int, save in appropriate place */
2639 	if (op->d.arrayref_subscript.isupper)
2640 		indexes = arefstate->upperindex;
2641 	else
2642 		indexes = arefstate->lowerindex;
2643 	off = op->d.arrayref_subscript.off;
2644 
2645 	indexes[off] = DatumGetInt32(arefstate->subscriptvalue);
2646 
2647 	return true;
2648 }
2649 
2650 /*
2651  * Evaluate ArrayRef fetch.
2652  *
2653  * Source array is in step's result variable.
2654  */
2655 void
ExecEvalArrayRefFetch(ExprState * state,ExprEvalStep * op)2656 ExecEvalArrayRefFetch(ExprState *state, ExprEvalStep *op)
2657 {
2658 	ArrayRefState *arefstate = op->d.arrayref.state;
2659 
2660 	/* Should not get here if source array (or any subscript) is null */
2661 	Assert(!(*op->resnull));
2662 
2663 	if (arefstate->numlower == 0)
2664 	{
2665 		/* Scalar case */
2666 		*op->resvalue = array_get_element(*op->resvalue,
2667 										  arefstate->numupper,
2668 										  arefstate->upperindex,
2669 										  arefstate->refattrlength,
2670 										  arefstate->refelemlength,
2671 										  arefstate->refelembyval,
2672 										  arefstate->refelemalign,
2673 										  op->resnull);
2674 	}
2675 	else
2676 	{
2677 		/* Slice case */
2678 		*op->resvalue = array_get_slice(*op->resvalue,
2679 										arefstate->numupper,
2680 										arefstate->upperindex,
2681 										arefstate->lowerindex,
2682 										arefstate->upperprovided,
2683 										arefstate->lowerprovided,
2684 										arefstate->refattrlength,
2685 										arefstate->refelemlength,
2686 										arefstate->refelembyval,
2687 										arefstate->refelemalign);
2688 	}
2689 }
2690 
2691 /*
2692  * Compute old array element/slice value for an ArrayRef assignment
2693  * expression.  Will only be generated if the new-value subexpression
2694  * contains ArrayRef or FieldStore.  The value is stored into the
2695  * ArrayRefState's prevvalue/prevnull fields.
2696  */
2697 void
ExecEvalArrayRefOld(ExprState * state,ExprEvalStep * op)2698 ExecEvalArrayRefOld(ExprState *state, ExprEvalStep *op)
2699 {
2700 	ArrayRefState *arefstate = op->d.arrayref.state;
2701 
2702 	if (*op->resnull)
2703 	{
2704 		/* whole array is null, so any element or slice is too */
2705 		arefstate->prevvalue = (Datum) 0;
2706 		arefstate->prevnull = true;
2707 	}
2708 	else if (arefstate->numlower == 0)
2709 	{
2710 		/* Scalar case */
2711 		arefstate->prevvalue = array_get_element(*op->resvalue,
2712 												 arefstate->numupper,
2713 												 arefstate->upperindex,
2714 												 arefstate->refattrlength,
2715 												 arefstate->refelemlength,
2716 												 arefstate->refelembyval,
2717 												 arefstate->refelemalign,
2718 												 &arefstate->prevnull);
2719 	}
2720 	else
2721 	{
2722 		/* Slice case */
2723 		/* this is currently unreachable */
2724 		arefstate->prevvalue = array_get_slice(*op->resvalue,
2725 											   arefstate->numupper,
2726 											   arefstate->upperindex,
2727 											   arefstate->lowerindex,
2728 											   arefstate->upperprovided,
2729 											   arefstate->lowerprovided,
2730 											   arefstate->refattrlength,
2731 											   arefstate->refelemlength,
2732 											   arefstate->refelembyval,
2733 											   arefstate->refelemalign);
2734 		arefstate->prevnull = false;
2735 	}
2736 }
2737 
2738 /*
2739  * Evaluate ArrayRef assignment.
2740  *
2741  * Input array (possibly null) is in result area, replacement value is in
2742  * ArrayRefState's replacevalue/replacenull.
2743  */
2744 void
ExecEvalArrayRefAssign(ExprState * state,ExprEvalStep * op)2745 ExecEvalArrayRefAssign(ExprState *state, ExprEvalStep *op)
2746 {
2747 	ArrayRefState *arefstate = op->d.arrayref.state;
2748 
2749 	/*
2750 	 * For an assignment to a fixed-length array type, both the original array
2751 	 * and the value to be assigned into it must be non-NULL, else we punt and
2752 	 * return the original array.
2753 	 */
2754 	if (arefstate->refattrlength > 0)	/* fixed-length array? */
2755 	{
2756 		if (*op->resnull || arefstate->replacenull)
2757 			return;
2758 	}
2759 
2760 	/*
2761 	 * For assignment to varlena arrays, we handle a NULL original array by
2762 	 * substituting an empty (zero-dimensional) array; insertion of the new
2763 	 * element will result in a singleton array value.  It does not matter
2764 	 * whether the new element is NULL.
2765 	 */
2766 	if (*op->resnull)
2767 	{
2768 		*op->resvalue = PointerGetDatum(construct_empty_array(arefstate->refelemtype));
2769 		*op->resnull = false;
2770 	}
2771 
2772 	if (arefstate->numlower == 0)
2773 	{
2774 		/* Scalar case */
2775 		*op->resvalue = array_set_element(*op->resvalue,
2776 										  arefstate->numupper,
2777 										  arefstate->upperindex,
2778 										  arefstate->replacevalue,
2779 										  arefstate->replacenull,
2780 										  arefstate->refattrlength,
2781 										  arefstate->refelemlength,
2782 										  arefstate->refelembyval,
2783 										  arefstate->refelemalign);
2784 	}
2785 	else
2786 	{
2787 		/* Slice case */
2788 		*op->resvalue = array_set_slice(*op->resvalue,
2789 										arefstate->numupper,
2790 										arefstate->upperindex,
2791 										arefstate->lowerindex,
2792 										arefstate->upperprovided,
2793 										arefstate->lowerprovided,
2794 										arefstate->replacevalue,
2795 										arefstate->replacenull,
2796 										arefstate->refattrlength,
2797 										arefstate->refelemlength,
2798 										arefstate->refelembyval,
2799 										arefstate->refelemalign);
2800 	}
2801 }
2802 
2803 /*
2804  * Evaluate a rowtype coercion operation.
2805  * This may require rearranging field positions.
2806  *
2807  * Source record is in step's result variable.
2808  */
2809 void
ExecEvalConvertRowtype(ExprState * state,ExprEvalStep * op,ExprContext * econtext)2810 ExecEvalConvertRowtype(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
2811 {
2812 	ConvertRowtypeExpr *convert = op->d.convert_rowtype.convert;
2813 	HeapTuple	result;
2814 	Datum		tupDatum;
2815 	HeapTupleHeader tuple;
2816 	HeapTupleData tmptup;
2817 	TupleDesc	indesc,
2818 				outdesc;
2819 
2820 	/* NULL in -> NULL out */
2821 	if (*op->resnull)
2822 		return;
2823 
2824 	tupDatum = *op->resvalue;
2825 	tuple = DatumGetHeapTupleHeader(tupDatum);
2826 
2827 	/* Lookup tupdescs if first time through or after rescan */
2828 	if (op->d.convert_rowtype.indesc == NULL)
2829 	{
2830 		get_cached_rowtype(exprType((Node *) convert->arg), -1,
2831 						   &op->d.convert_rowtype.indesc,
2832 						   econtext);
2833 		op->d.convert_rowtype.initialized = false;
2834 	}
2835 	if (op->d.convert_rowtype.outdesc == NULL)
2836 	{
2837 		get_cached_rowtype(convert->resulttype, -1,
2838 						   &op->d.convert_rowtype.outdesc,
2839 						   econtext);
2840 		op->d.convert_rowtype.initialized = false;
2841 	}
2842 
2843 	indesc = op->d.convert_rowtype.indesc;
2844 	outdesc = op->d.convert_rowtype.outdesc;
2845 
2846 	/*
2847 	 * We used to be able to assert that incoming tuples are marked with
2848 	 * exactly the rowtype of indesc.  However, now that ExecEvalWholeRowVar
2849 	 * might change the tuples' marking to plain RECORD due to inserting
2850 	 * aliases, we can only make this weak test:
2851 	 */
2852 	Assert(HeapTupleHeaderGetTypeId(tuple) == indesc->tdtypeid ||
2853 		   HeapTupleHeaderGetTypeId(tuple) == RECORDOID);
2854 
2855 	/* if first time through, initialize conversion map */
2856 	if (!op->d.convert_rowtype.initialized)
2857 	{
2858 		MemoryContext old_cxt;
2859 
2860 		/* allocate map in long-lived memory context */
2861 		old_cxt = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
2862 
2863 		/* prepare map from old to new attribute numbers */
2864 		op->d.convert_rowtype.map =
2865 			convert_tuples_by_name(indesc, outdesc,
2866 								   gettext_noop("could not convert row type"));
2867 		op->d.convert_rowtype.initialized = true;
2868 
2869 		MemoryContextSwitchTo(old_cxt);
2870 	}
2871 
2872 	/* Following steps need a HeapTuple not a bare HeapTupleHeader */
2873 	tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
2874 	tmptup.t_data = tuple;
2875 
2876 	if (op->d.convert_rowtype.map != NULL)
2877 	{
2878 		/* Full conversion with attribute rearrangement needed */
2879 		result = do_convert_tuple(&tmptup, op->d.convert_rowtype.map);
2880 		/* Result already has appropriate composite-datum header fields */
2881 		*op->resvalue = HeapTupleGetDatum(result);
2882 	}
2883 	else
2884 	{
2885 		/*
2886 		 * The tuple is physically compatible as-is, but we need to insert the
2887 		 * destination rowtype OID in its composite-datum header field, so we
2888 		 * have to copy it anyway.  heap_copy_tuple_as_datum() is convenient
2889 		 * for this since it will both make the physical copy and insert the
2890 		 * correct composite header fields.  Note that we aren't expecting to
2891 		 * have to flatten any toasted fields: the input was a composite
2892 		 * datum, so it shouldn't contain any.  So heap_copy_tuple_as_datum()
2893 		 * is overkill here, but its check for external fields is cheap.
2894 		 */
2895 		*op->resvalue = heap_copy_tuple_as_datum(&tmptup, outdesc);
2896 	}
2897 }
2898 
2899 /*
2900  * Evaluate "scalar op ANY/ALL (array)".
2901  *
2902  * Source array is in our result area, scalar arg is already evaluated into
2903  * fcinfo->arg[0]/argnull[0].
2904  *
2905  * The operator always yields boolean, and we combine the results across all
2906  * array elements using OR and AND (for ANY and ALL respectively).  Of course
2907  * we short-circuit as soon as the result is known.
2908  */
2909 void
ExecEvalScalarArrayOp(ExprState * state,ExprEvalStep * op)2910 ExecEvalScalarArrayOp(ExprState *state, ExprEvalStep *op)
2911 {
2912 	FunctionCallInfo fcinfo = op->d.scalararrayop.fcinfo_data;
2913 	bool		useOr = op->d.scalararrayop.useOr;
2914 	bool		strictfunc = op->d.scalararrayop.finfo->fn_strict;
2915 	ArrayType  *arr;
2916 	int			nitems;
2917 	Datum		result;
2918 	bool		resultnull;
2919 	int			i;
2920 	int16		typlen;
2921 	bool		typbyval;
2922 	char		typalign;
2923 	char	   *s;
2924 	bits8	   *bitmap;
2925 	int			bitmask;
2926 
2927 	/*
2928 	 * If the array is NULL then we return NULL --- it's not very meaningful
2929 	 * to do anything else, even if the operator isn't strict.
2930 	 */
2931 	if (*op->resnull)
2932 		return;
2933 
2934 	/* Else okay to fetch and detoast the array */
2935 	arr = DatumGetArrayTypeP(*op->resvalue);
2936 
2937 	/*
2938 	 * If the array is empty, we return either FALSE or TRUE per the useOr
2939 	 * flag.  This is correct even if the scalar is NULL; since we would
2940 	 * evaluate the operator zero times, it matters not whether it would want
2941 	 * to return NULL.
2942 	 */
2943 	nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
2944 	if (nitems <= 0)
2945 	{
2946 		*op->resvalue = BoolGetDatum(!useOr);
2947 		*op->resnull = false;
2948 		return;
2949 	}
2950 
2951 	/*
2952 	 * If the scalar is NULL, and the function is strict, return NULL; no
2953 	 * point in iterating the loop.
2954 	 */
2955 	if (fcinfo->argnull[0] && strictfunc)
2956 	{
2957 		*op->resnull = true;
2958 		return;
2959 	}
2960 
2961 	/*
2962 	 * We arrange to look up info about the element type only once per series
2963 	 * of calls, assuming the element type doesn't change underneath us.
2964 	 */
2965 	if (op->d.scalararrayop.element_type != ARR_ELEMTYPE(arr))
2966 	{
2967 		get_typlenbyvalalign(ARR_ELEMTYPE(arr),
2968 							 &op->d.scalararrayop.typlen,
2969 							 &op->d.scalararrayop.typbyval,
2970 							 &op->d.scalararrayop.typalign);
2971 		op->d.scalararrayop.element_type = ARR_ELEMTYPE(arr);
2972 	}
2973 
2974 	typlen = op->d.scalararrayop.typlen;
2975 	typbyval = op->d.scalararrayop.typbyval;
2976 	typalign = op->d.scalararrayop.typalign;
2977 
2978 	/* Initialize result appropriately depending on useOr */
2979 	result = BoolGetDatum(!useOr);
2980 	resultnull = false;
2981 
2982 	/* Loop over the array elements */
2983 	s = (char *) ARR_DATA_PTR(arr);
2984 	bitmap = ARR_NULLBITMAP(arr);
2985 	bitmask = 1;
2986 
2987 	for (i = 0; i < nitems; i++)
2988 	{
2989 		Datum		elt;
2990 		Datum		thisresult;
2991 
2992 		/* Get array element, checking for NULL */
2993 		if (bitmap && (*bitmap & bitmask) == 0)
2994 		{
2995 			fcinfo->arg[1] = (Datum) 0;
2996 			fcinfo->argnull[1] = true;
2997 		}
2998 		else
2999 		{
3000 			elt = fetch_att(s, typbyval, typlen);
3001 			s = att_addlength_pointer(s, typlen, s);
3002 			s = (char *) att_align_nominal(s, typalign);
3003 			fcinfo->arg[1] = elt;
3004 			fcinfo->argnull[1] = false;
3005 		}
3006 
3007 		/* Call comparison function */
3008 		if (fcinfo->argnull[1] && strictfunc)
3009 		{
3010 			fcinfo->isnull = true;
3011 			thisresult = (Datum) 0;
3012 		}
3013 		else
3014 		{
3015 			fcinfo->isnull = false;
3016 			thisresult = (op->d.scalararrayop.fn_addr) (fcinfo);
3017 		}
3018 
3019 		/* Combine results per OR or AND semantics */
3020 		if (fcinfo->isnull)
3021 			resultnull = true;
3022 		else if (useOr)
3023 		{
3024 			if (DatumGetBool(thisresult))
3025 			{
3026 				result = BoolGetDatum(true);
3027 				resultnull = false;
3028 				break;			/* needn't look at any more elements */
3029 			}
3030 		}
3031 		else
3032 		{
3033 			if (!DatumGetBool(thisresult))
3034 			{
3035 				result = BoolGetDatum(false);
3036 				resultnull = false;
3037 				break;			/* needn't look at any more elements */
3038 			}
3039 		}
3040 
3041 		/* advance bitmap pointer if any */
3042 		if (bitmap)
3043 		{
3044 			bitmask <<= 1;
3045 			if (bitmask == 0x100)
3046 			{
3047 				bitmap++;
3048 				bitmask = 1;
3049 			}
3050 		}
3051 	}
3052 
3053 	*op->resvalue = result;
3054 	*op->resnull = resultnull;
3055 }
3056 
3057 /*
3058  * Evaluate a NOT NULL domain constraint.
3059  */
3060 void
ExecEvalConstraintNotNull(ExprState * state,ExprEvalStep * op)3061 ExecEvalConstraintNotNull(ExprState *state, ExprEvalStep *op)
3062 {
3063 	if (*op->resnull)
3064 		ereport(ERROR,
3065 				(errcode(ERRCODE_NOT_NULL_VIOLATION),
3066 				 errmsg("domain %s does not allow null values",
3067 						format_type_be(op->d.domaincheck.resulttype)),
3068 				 errdatatype(op->d.domaincheck.resulttype)));
3069 }
3070 
3071 /*
3072  * Evaluate a CHECK domain constraint.
3073  */
3074 void
ExecEvalConstraintCheck(ExprState * state,ExprEvalStep * op)3075 ExecEvalConstraintCheck(ExprState *state, ExprEvalStep *op)
3076 {
3077 	if (!*op->d.domaincheck.checknull &&
3078 		!DatumGetBool(*op->d.domaincheck.checkvalue))
3079 		ereport(ERROR,
3080 				(errcode(ERRCODE_CHECK_VIOLATION),
3081 				 errmsg("value for domain %s violates check constraint \"%s\"",
3082 						format_type_be(op->d.domaincheck.resulttype),
3083 						op->d.domaincheck.constraintname),
3084 				 errdomainconstraint(op->d.domaincheck.resulttype,
3085 									 op->d.domaincheck.constraintname)));
3086 }
3087 
3088 /*
3089  * Evaluate the various forms of XmlExpr.
3090  *
3091  * Arguments have been evaluated into named_argvalue/named_argnull
3092  * and/or argvalue/argnull arrays.
3093  */
3094 void
ExecEvalXmlExpr(ExprState * state,ExprEvalStep * op)3095 ExecEvalXmlExpr(ExprState *state, ExprEvalStep *op)
3096 {
3097 	XmlExpr    *xexpr = op->d.xmlexpr.xexpr;
3098 	Datum		value;
3099 	int			i;
3100 
3101 	*op->resnull = true;		/* until we get a result */
3102 	*op->resvalue = (Datum) 0;
3103 
3104 	switch (xexpr->op)
3105 	{
3106 		case IS_XMLCONCAT:
3107 			{
3108 				Datum	   *argvalue = op->d.xmlexpr.argvalue;
3109 				bool	   *argnull = op->d.xmlexpr.argnull;
3110 				List	   *values = NIL;
3111 
3112 				for (i = 0; i < list_length(xexpr->args); i++)
3113 				{
3114 					if (!argnull[i])
3115 						values = lappend(values, DatumGetPointer(argvalue[i]));
3116 				}
3117 
3118 				if (values != NIL)
3119 				{
3120 					*op->resvalue = PointerGetDatum(xmlconcat(values));
3121 					*op->resnull = false;
3122 				}
3123 			}
3124 			break;
3125 
3126 		case IS_XMLFOREST:
3127 			{
3128 				Datum	   *argvalue = op->d.xmlexpr.named_argvalue;
3129 				bool	   *argnull = op->d.xmlexpr.named_argnull;
3130 				StringInfoData buf;
3131 				ListCell   *lc;
3132 				ListCell   *lc2;
3133 
3134 				initStringInfo(&buf);
3135 
3136 				i = 0;
3137 				forboth(lc, xexpr->named_args, lc2, xexpr->arg_names)
3138 				{
3139 					Expr	   *e = (Expr *) lfirst(lc);
3140 					char	   *argname = strVal(lfirst(lc2));
3141 
3142 					if (!argnull[i])
3143 					{
3144 						value = argvalue[i];
3145 						appendStringInfo(&buf, "<%s>%s</%s>",
3146 										 argname,
3147 										 map_sql_value_to_xml_value(value,
3148 																	exprType((Node *) e), true),
3149 										 argname);
3150 						*op->resnull = false;
3151 					}
3152 					i++;
3153 				}
3154 
3155 				if (!*op->resnull)
3156 				{
3157 					text	   *result;
3158 
3159 					result = cstring_to_text_with_len(buf.data, buf.len);
3160 					*op->resvalue = PointerGetDatum(result);
3161 				}
3162 
3163 				pfree(buf.data);
3164 			}
3165 			break;
3166 
3167 		case IS_XMLELEMENT:
3168 			*op->resvalue = PointerGetDatum(xmlelement(xexpr,
3169 													   op->d.xmlexpr.named_argvalue,
3170 													   op->d.xmlexpr.named_argnull,
3171 													   op->d.xmlexpr.argvalue,
3172 													   op->d.xmlexpr.argnull));
3173 			*op->resnull = false;
3174 			break;
3175 
3176 		case IS_XMLPARSE:
3177 			{
3178 				Datum	   *argvalue = op->d.xmlexpr.argvalue;
3179 				bool	   *argnull = op->d.xmlexpr.argnull;
3180 				text	   *data;
3181 				bool		preserve_whitespace;
3182 
3183 				/* arguments are known to be text, bool */
3184 				Assert(list_length(xexpr->args) == 2);
3185 
3186 				if (argnull[0])
3187 					return;
3188 				value = argvalue[0];
3189 				data = DatumGetTextPP(value);
3190 
3191 				if (argnull[1]) /* probably can't happen */
3192 					return;
3193 				value = argvalue[1];
3194 				preserve_whitespace = DatumGetBool(value);
3195 
3196 				*op->resvalue = PointerGetDatum(xmlparse(data,
3197 														 xexpr->xmloption,
3198 														 preserve_whitespace));
3199 				*op->resnull = false;
3200 			}
3201 			break;
3202 
3203 		case IS_XMLPI:
3204 			{
3205 				text	   *arg;
3206 				bool		isnull;
3207 
3208 				/* optional argument is known to be text */
3209 				Assert(list_length(xexpr->args) <= 1);
3210 
3211 				if (xexpr->args)
3212 				{
3213 					isnull = op->d.xmlexpr.argnull[0];
3214 					if (isnull)
3215 						arg = NULL;
3216 					else
3217 						arg = DatumGetTextPP(op->d.xmlexpr.argvalue[0]);
3218 				}
3219 				else
3220 				{
3221 					arg = NULL;
3222 					isnull = false;
3223 				}
3224 
3225 				*op->resvalue = PointerGetDatum(xmlpi(xexpr->name,
3226 													  arg,
3227 													  isnull,
3228 													  op->resnull));
3229 			}
3230 			break;
3231 
3232 		case IS_XMLROOT:
3233 			{
3234 				Datum	   *argvalue = op->d.xmlexpr.argvalue;
3235 				bool	   *argnull = op->d.xmlexpr.argnull;
3236 				xmltype    *data;
3237 				text	   *version;
3238 				int			standalone;
3239 
3240 				/* arguments are known to be xml, text, int */
3241 				Assert(list_length(xexpr->args) == 3);
3242 
3243 				if (argnull[0])
3244 					return;
3245 				data = DatumGetXmlP(argvalue[0]);
3246 
3247 				if (argnull[1])
3248 					version = NULL;
3249 				else
3250 					version = DatumGetTextPP(argvalue[1]);
3251 
3252 				Assert(!argnull[2]);	/* always present */
3253 				standalone = DatumGetInt32(argvalue[2]);
3254 
3255 				*op->resvalue = PointerGetDatum(xmlroot(data,
3256 														version,
3257 														standalone));
3258 				*op->resnull = false;
3259 			}
3260 			break;
3261 
3262 		case IS_XMLSERIALIZE:
3263 			{
3264 				Datum	   *argvalue = op->d.xmlexpr.argvalue;
3265 				bool	   *argnull = op->d.xmlexpr.argnull;
3266 
3267 				/* argument type is known to be xml */
3268 				Assert(list_length(xexpr->args) == 1);
3269 
3270 				if (argnull[0])
3271 					return;
3272 				value = argvalue[0];
3273 
3274 				*op->resvalue = PointerGetDatum(
3275 												xmltotext_with_xmloption(DatumGetXmlP(value),
3276 																		 xexpr->xmloption));
3277 				*op->resnull = false;
3278 			}
3279 			break;
3280 
3281 		case IS_DOCUMENT:
3282 			{
3283 				Datum	   *argvalue = op->d.xmlexpr.argvalue;
3284 				bool	   *argnull = op->d.xmlexpr.argnull;
3285 
3286 				/* optional argument is known to be xml */
3287 				Assert(list_length(xexpr->args) == 1);
3288 
3289 				if (argnull[0])
3290 					return;
3291 				value = argvalue[0];
3292 
3293 				*op->resvalue =
3294 					BoolGetDatum(xml_is_document(DatumGetXmlP(value)));
3295 				*op->resnull = false;
3296 			}
3297 			break;
3298 
3299 		default:
3300 			elog(ERROR, "unrecognized XML operation");
3301 			break;
3302 	}
3303 }
3304 
3305 /*
3306  * ExecEvalGroupingFunc
3307  *
3308  * Computes a bitmask with a bit for each (unevaluated) argument expression
3309  * (rightmost arg is least significant bit).
3310  *
3311  * A bit is set if the corresponding expression is NOT part of the set of
3312  * grouping expressions in the current grouping set.
3313  */
3314 void
ExecEvalGroupingFunc(ExprState * state,ExprEvalStep * op)3315 ExecEvalGroupingFunc(ExprState *state, ExprEvalStep *op)
3316 {
3317 	int			result = 0;
3318 	Bitmapset  *grouped_cols = op->d.grouping_func.parent->grouped_cols;
3319 	ListCell   *lc;
3320 
3321 	foreach(lc, op->d.grouping_func.clauses)
3322 	{
3323 		int			attnum = lfirst_int(lc);
3324 
3325 		result <<= 1;
3326 
3327 		if (!bms_is_member(attnum, grouped_cols))
3328 			result |= 1;
3329 	}
3330 
3331 	*op->resvalue = Int32GetDatum(result);
3332 	*op->resnull = false;
3333 }
3334 
3335 /*
3336  * Hand off evaluation of a subplan to nodeSubplan.c
3337  */
3338 void
ExecEvalSubPlan(ExprState * state,ExprEvalStep * op,ExprContext * econtext)3339 ExecEvalSubPlan(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
3340 {
3341 	SubPlanState *sstate = op->d.subplan.sstate;
3342 
3343 	/* could potentially be nested, so make sure there's enough stack */
3344 	check_stack_depth();
3345 
3346 	*op->resvalue = ExecSubPlan(sstate, econtext, op->resnull);
3347 }
3348 
3349 /*
3350  * Hand off evaluation of an alternative subplan to nodeSubplan.c
3351  */
3352 void
ExecEvalAlternativeSubPlan(ExprState * state,ExprEvalStep * op,ExprContext * econtext)3353 ExecEvalAlternativeSubPlan(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
3354 {
3355 	AlternativeSubPlanState *asstate = op->d.alternative_subplan.asstate;
3356 
3357 	/* could potentially be nested, so make sure there's enough stack */
3358 	check_stack_depth();
3359 
3360 	*op->resvalue = ExecAlternativeSubPlan(asstate, econtext, op->resnull);
3361 }
3362 
3363 /*
3364  * Evaluate a wholerow Var expression.
3365  *
3366  * Returns a Datum whose value is the value of a whole-row range variable
3367  * with respect to given expression context.
3368  */
3369 void
ExecEvalWholeRowVar(ExprState * state,ExprEvalStep * op,ExprContext * econtext)3370 ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
3371 {
3372 	Var		   *variable = op->d.wholerow.var;
3373 	TupleTableSlot *slot;
3374 	TupleDesc	output_tupdesc;
3375 	MemoryContext oldcontext;
3376 	HeapTupleHeader dtuple;
3377 	HeapTuple	tuple;
3378 
3379 	/* This was checked by ExecInitExpr */
3380 	Assert(variable->varattno == InvalidAttrNumber);
3381 
3382 	/* Get the input slot we want */
3383 	switch (variable->varno)
3384 	{
3385 		case INNER_VAR:
3386 			/* get the tuple from the inner node */
3387 			slot = econtext->ecxt_innertuple;
3388 			break;
3389 
3390 		case OUTER_VAR:
3391 			/* get the tuple from the outer node */
3392 			slot = econtext->ecxt_outertuple;
3393 			break;
3394 
3395 			/* INDEX_VAR is handled by default case */
3396 
3397 		default:
3398 			/* get the tuple from the relation being scanned */
3399 			slot = econtext->ecxt_scantuple;
3400 			break;
3401 	}
3402 
3403 	/* Apply the junkfilter if any */
3404 	if (op->d.wholerow.junkFilter != NULL)
3405 		slot = ExecFilterJunk(op->d.wholerow.junkFilter, slot);
3406 
3407 	/*
3408 	 * If first time through, obtain tuple descriptor and check compatibility.
3409 	 *
3410 	 * XXX: It'd be great if this could be moved to the expression
3411 	 * initialization phase, but due to using slots that's currently not
3412 	 * feasible.
3413 	 */
3414 	if (op->d.wholerow.first)
3415 	{
3416 		/* optimistically assume we don't need slow path */
3417 		op->d.wholerow.slow = false;
3418 
3419 		/*
3420 		 * If the Var identifies a named composite type, we must check that
3421 		 * the actual tuple type is compatible with it.
3422 		 */
3423 		if (variable->vartype != RECORDOID)
3424 		{
3425 			TupleDesc	var_tupdesc;
3426 			TupleDesc	slot_tupdesc;
3427 			int			i;
3428 
3429 			/*
3430 			 * We really only care about numbers of attributes and data types.
3431 			 * Also, we can ignore type mismatch on columns that are dropped
3432 			 * in the destination type, so long as (1) the physical storage
3433 			 * matches or (2) the actual column value is NULL.  Case (1) is
3434 			 * helpful in some cases involving out-of-date cached plans, while
3435 			 * case (2) is expected behavior in situations such as an INSERT
3436 			 * into a table with dropped columns (the planner typically
3437 			 * generates an INT4 NULL regardless of the dropped column type).
3438 			 * If we find a dropped column and cannot verify that case (1)
3439 			 * holds, we have to use the slow path to check (2) for each row.
3440 			 */
3441 			var_tupdesc = lookup_rowtype_tupdesc(variable->vartype, -1);
3442 
3443 			slot_tupdesc = slot->tts_tupleDescriptor;
3444 
3445 			if (var_tupdesc->natts != slot_tupdesc->natts)
3446 				ereport(ERROR,
3447 						(errcode(ERRCODE_DATATYPE_MISMATCH),
3448 						 errmsg("table row type and query-specified row type do not match"),
3449 						 errdetail_plural("Table row contains %d attribute, but query expects %d.",
3450 										  "Table row contains %d attributes, but query expects %d.",
3451 										  slot_tupdesc->natts,
3452 										  slot_tupdesc->natts,
3453 										  var_tupdesc->natts)));
3454 
3455 			for (i = 0; i < var_tupdesc->natts; i++)
3456 			{
3457 				Form_pg_attribute vattr = var_tupdesc->attrs[i];
3458 				Form_pg_attribute sattr = slot_tupdesc->attrs[i];
3459 
3460 				if (vattr->atttypid == sattr->atttypid)
3461 					continue;	/* no worries */
3462 				if (!vattr->attisdropped)
3463 					ereport(ERROR,
3464 							(errcode(ERRCODE_DATATYPE_MISMATCH),
3465 							 errmsg("table row type and query-specified row type do not match"),
3466 							 errdetail("Table has type %s at ordinal position %d, but query expects %s.",
3467 									   format_type_be(sattr->atttypid),
3468 									   i + 1,
3469 									   format_type_be(vattr->atttypid))));
3470 
3471 				if (vattr->attlen != sattr->attlen ||
3472 					vattr->attalign != sattr->attalign)
3473 					op->d.wholerow.slow = true; /* need to check for nulls */
3474 			}
3475 
3476 			/*
3477 			 * Use the variable's declared rowtype as the descriptor for the
3478 			 * output values, modulo possibly assigning new column names
3479 			 * below. In particular, we *must* absorb any attisdropped
3480 			 * markings.
3481 			 */
3482 			oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
3483 			output_tupdesc = CreateTupleDescCopy(var_tupdesc);
3484 			MemoryContextSwitchTo(oldcontext);
3485 
3486 			ReleaseTupleDesc(var_tupdesc);
3487 		}
3488 		else
3489 		{
3490 			/*
3491 			 * In the RECORD case, we use the input slot's rowtype as the
3492 			 * descriptor for the output values, modulo possibly assigning new
3493 			 * column names below.
3494 			 */
3495 			oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
3496 			output_tupdesc = CreateTupleDescCopy(slot->tts_tupleDescriptor);
3497 			MemoryContextSwitchTo(oldcontext);
3498 		}
3499 
3500 		/*
3501 		 * Construct a tuple descriptor for the composite values we'll
3502 		 * produce, and make sure its record type is "blessed".  The main
3503 		 * reason to do this is to be sure that operations such as
3504 		 * row_to_json() will see the desired column names when they look up
3505 		 * the descriptor from the type information embedded in the composite
3506 		 * values.
3507 		 *
3508 		 * We already got the correct physical datatype info above, but now we
3509 		 * should try to find the source RTE and adopt its column aliases, in
3510 		 * case they are different from the original rowtype's names.  For
3511 		 * example, in "SELECT foo(t) FROM tab t(x,y)", the first two columns
3512 		 * in the composite output should be named "x" and "y" regardless of
3513 		 * tab's column names.
3514 		 *
3515 		 * If we can't locate the RTE, assume the column names we've got are
3516 		 * OK.  (As of this writing, the only cases where we can't locate the
3517 		 * RTE are in execution of trigger WHEN clauses, and then the Var will
3518 		 * have the trigger's relation's rowtype, so its names are fine.)
3519 		 * Also, if the creator of the RTE didn't bother to fill in an eref
3520 		 * field, assume our column names are OK.  (This happens in COPY, and
3521 		 * perhaps other places.)
3522 		 */
3523 		if (econtext->ecxt_estate &&
3524 			variable->varno <= list_length(econtext->ecxt_estate->es_range_table))
3525 		{
3526 			RangeTblEntry *rte = rt_fetch(variable->varno,
3527 										  econtext->ecxt_estate->es_range_table);
3528 
3529 			if (rte->eref)
3530 				ExecTypeSetColNames(output_tupdesc, rte->eref->colnames);
3531 		}
3532 
3533 		/* Bless the tupdesc if needed, and save it in the execution state */
3534 		op->d.wholerow.tupdesc = BlessTupleDesc(output_tupdesc);
3535 
3536 		op->d.wholerow.first = false;
3537 	}
3538 
3539 	/*
3540 	 * Make sure all columns of the slot are accessible in the slot's
3541 	 * Datum/isnull arrays.
3542 	 */
3543 	slot_getallattrs(slot);
3544 
3545 	if (op->d.wholerow.slow)
3546 	{
3547 		/* Check to see if any dropped attributes are non-null */
3548 		TupleDesc	tupleDesc = slot->tts_tupleDescriptor;
3549 		TupleDesc	var_tupdesc = op->d.wholerow.tupdesc;
3550 		int			i;
3551 
3552 		Assert(var_tupdesc->natts == tupleDesc->natts);
3553 
3554 		for (i = 0; i < var_tupdesc->natts; i++)
3555 		{
3556 			Form_pg_attribute vattr = var_tupdesc->attrs[i];
3557 			Form_pg_attribute sattr = tupleDesc->attrs[i];
3558 
3559 			if (!vattr->attisdropped)
3560 				continue;		/* already checked non-dropped cols */
3561 			if (slot->tts_isnull[i])
3562 				continue;		/* null is always okay */
3563 			if (vattr->attlen != sattr->attlen ||
3564 				vattr->attalign != sattr->attalign)
3565 				ereport(ERROR,
3566 						(errcode(ERRCODE_DATATYPE_MISMATCH),
3567 						 errmsg("table row type and query-specified row type do not match"),
3568 						 errdetail("Physical storage mismatch on dropped attribute at ordinal position %d.",
3569 								   i + 1)));
3570 		}
3571 	}
3572 
3573 	/*
3574 	 * Build a composite datum, making sure any toasted fields get detoasted.
3575 	 *
3576 	 * (Note: it is critical that we not change the slot's state here.)
3577 	 */
3578 	tuple = toast_build_flattened_tuple(slot->tts_tupleDescriptor,
3579 										slot->tts_values,
3580 										slot->tts_isnull);
3581 	dtuple = tuple->t_data;
3582 
3583 	/*
3584 	 * Label the datum with the composite type info we identified before.
3585 	 *
3586 	 * (Note: we could skip doing this by passing op->d.wholerow.tupdesc to
3587 	 * the tuple build step; but that seems a tad risky so let's not.)
3588 	 */
3589 	HeapTupleHeaderSetTypeId(dtuple, op->d.wholerow.tupdesc->tdtypeid);
3590 	HeapTupleHeaderSetTypMod(dtuple, op->d.wholerow.tupdesc->tdtypmod);
3591 
3592 	*op->resvalue = PointerGetDatum(dtuple);
3593 	*op->resnull = false;
3594 }
3595