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