1
/*-------------------------------------------------------------------------
4
* Routines to evaluate qualification and targetlist expressions
6
* Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
7
* Portions Copyright (c) 1994, Regents of the University of California
11
* src/backend/executor/execQual.c
13
*-------------------------------------------------------------------------
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
23
* The more heavily used ExecEvalExpr routines, such as ExecEvalVar(),
24
* are hotspots. Making these faster will speed up the entire system.
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
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.
39
#include "access/nbtree.h"
40
#include "access/tupconvert.h"
41
#include "catalog/pg_type.h"
42
#include "commands/typecmds.h"
43
#include "executor/execdebug.h"
44
#include "executor/nodeSubplan.h"
46
#include "miscadmin.h"
47
#include "nodes/makefuncs.h"
48
#include "nodes/nodeFuncs.h"
49
#include "optimizer/planner.h"
50
#include "parser/parse_coerce.h"
52
#include "utils/acl.h"
53
#include "utils/builtins.h"
54
#include "utils/lsyscache.h"
55
#include "utils/memutils.h"
56
#include "utils/typcache.h"
57
#include "utils/xml.h"
60
/* static function decls */
61
static Datum ExecEvalArrayRef(ArrayRefExprState *astate,
62
ExprContext *econtext,
63
bool *isNull, ExprDoneCond *isDone);
64
static bool isAssignmentIndirectionExpr(ExprState *exprstate);
65
static Datum ExecEvalAggref(AggrefExprState *aggref,
66
ExprContext *econtext,
67
bool *isNull, ExprDoneCond *isDone);
68
static Datum ExecEvalWindowFunc(WindowFuncExprState *wfunc,
69
ExprContext *econtext,
70
bool *isNull, ExprDoneCond *isDone);
71
static Datum ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
72
bool *isNull, ExprDoneCond *isDone);
73
static Datum ExecEvalScalarVar(ExprState *exprstate, ExprContext *econtext,
74
bool *isNull, ExprDoneCond *isDone);
75
static Datum ExecEvalWholeRowVar(ExprState *exprstate, ExprContext *econtext,
76
bool *isNull, ExprDoneCond *isDone);
77
static Datum ExecEvalWholeRowSlow(ExprState *exprstate, ExprContext *econtext,
78
bool *isNull, ExprDoneCond *isDone);
79
static Datum ExecEvalConst(ExprState *exprstate, ExprContext *econtext,
80
bool *isNull, ExprDoneCond *isDone);
81
static Datum ExecEvalParamExec(ExprState *exprstate, ExprContext *econtext,
82
bool *isNull, ExprDoneCond *isDone);
83
static Datum ExecEvalParamExtern(ExprState *exprstate, ExprContext *econtext,
84
bool *isNull, ExprDoneCond *isDone);
85
static void init_fcache(Oid foid, Oid input_collation, FuncExprState *fcache,
86
MemoryContext fcacheCxt, bool needDescForSets);
87
static void ShutdownFuncExpr(Datum arg);
88
static TupleDesc get_cached_rowtype(Oid type_id, int32 typmod,
89
TupleDesc *cache_field, ExprContext *econtext);
90
static void ShutdownTupleDescRef(Datum arg);
91
static ExprDoneCond ExecEvalFuncArgs(FunctionCallInfo fcinfo,
92
List *argList, ExprContext *econtext);
93
static void ExecPrepareTuplestoreResult(FuncExprState *fcache,
94
ExprContext *econtext,
95
Tuplestorestate *resultStore,
96
TupleDesc resultDesc);
97
static void tupledesc_match(TupleDesc dst_tupdesc, TupleDesc src_tupdesc);
98
static Datum ExecMakeFunctionResult(FuncExprState *fcache,
99
ExprContext *econtext,
101
ExprDoneCond *isDone);
102
static Datum ExecMakeFunctionResultNoSets(FuncExprState *fcache,
103
ExprContext *econtext,
104
bool *isNull, ExprDoneCond *isDone);
105
static Datum ExecEvalFunc(FuncExprState *fcache, ExprContext *econtext,
106
bool *isNull, ExprDoneCond *isDone);
107
static Datum ExecEvalOper(FuncExprState *fcache, ExprContext *econtext,
108
bool *isNull, ExprDoneCond *isDone);
109
static Datum ExecEvalDistinct(FuncExprState *fcache, ExprContext *econtext,
110
bool *isNull, ExprDoneCond *isDone);
111
static Datum ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate,
112
ExprContext *econtext,
113
bool *isNull, ExprDoneCond *isDone);
114
static Datum ExecEvalNot(BoolExprState *notclause, ExprContext *econtext,
115
bool *isNull, ExprDoneCond *isDone);
116
static Datum ExecEvalOr(BoolExprState *orExpr, ExprContext *econtext,
117
bool *isNull, ExprDoneCond *isDone);
118
static Datum ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
119
bool *isNull, ExprDoneCond *isDone);
120
static Datum ExecEvalConvertRowtype(ConvertRowtypeExprState *cstate,
121
ExprContext *econtext,
122
bool *isNull, ExprDoneCond *isDone);
123
static Datum ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
124
bool *isNull, ExprDoneCond *isDone);
125
static Datum ExecEvalCaseTestExpr(ExprState *exprstate,
126
ExprContext *econtext,
127
bool *isNull, ExprDoneCond *isDone);
128
static Datum ExecEvalArray(ArrayExprState *astate,
129
ExprContext *econtext,
130
bool *isNull, ExprDoneCond *isDone);
131
static Datum ExecEvalRow(RowExprState *rstate,
132
ExprContext *econtext,
133
bool *isNull, ExprDoneCond *isDone);
134
static Datum ExecEvalRowCompare(RowCompareExprState *rstate,
135
ExprContext *econtext,
136
bool *isNull, ExprDoneCond *isDone);
137
static Datum ExecEvalCoalesce(CoalesceExprState *coalesceExpr,
138
ExprContext *econtext,
139
bool *isNull, ExprDoneCond *isDone);
140
static Datum ExecEvalMinMax(MinMaxExprState *minmaxExpr,
141
ExprContext *econtext,
142
bool *isNull, ExprDoneCond *isDone);
143
static Datum ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
144
bool *isNull, ExprDoneCond *isDone);
145
static Datum ExecEvalNullIf(FuncExprState *nullIfExpr,
146
ExprContext *econtext,
147
bool *isNull, ExprDoneCond *isDone);
148
static Datum ExecEvalNullTest(NullTestState *nstate,
149
ExprContext *econtext,
150
bool *isNull, ExprDoneCond *isDone);
151
static Datum ExecEvalBooleanTest(GenericExprState *bstate,
152
ExprContext *econtext,
153
bool *isNull, ExprDoneCond *isDone);
154
static Datum ExecEvalCoerceToDomain(CoerceToDomainState *cstate,
155
ExprContext *econtext,
156
bool *isNull, ExprDoneCond *isDone);
157
static Datum ExecEvalCoerceToDomainValue(ExprState *exprstate,
158
ExprContext *econtext,
159
bool *isNull, ExprDoneCond *isDone);
160
static Datum ExecEvalFieldSelect(FieldSelectState *fstate,
161
ExprContext *econtext,
162
bool *isNull, ExprDoneCond *isDone);
163
static Datum ExecEvalFieldStore(FieldStoreState *fstate,
164
ExprContext *econtext,
165
bool *isNull, ExprDoneCond *isDone);
166
static Datum ExecEvalRelabelType(GenericExprState *exprstate,
167
ExprContext *econtext,
168
bool *isNull, ExprDoneCond *isDone);
169
static Datum ExecEvalCoerceViaIO(CoerceViaIOState *iostate,
170
ExprContext *econtext,
171
bool *isNull, ExprDoneCond *isDone);
172
static Datum ExecEvalArrayCoerceExpr(ArrayCoerceExprState *astate,
173
ExprContext *econtext,
174
bool *isNull, ExprDoneCond *isDone);
175
static Datum ExecEvalCurrentOfExpr(ExprState *exprstate, ExprContext *econtext,
176
bool *isNull, ExprDoneCond *isDone);
179
/* ----------------------------------------------------------------
180
* ExecEvalExpr routines
182
* Recursively evaluate a targetlist or qualification expression.
184
* Each of the following routines having the signature
185
* Datum ExecEvalFoo(ExprState *expression,
186
* ExprContext *econtext,
188
* ExprDoneCond *isDone);
189
* is responsible for evaluating one type or subtype of ExprState node.
190
* They are normally called via the ExecEvalExpr macro, which makes use of
191
* the function pointer set up when the ExprState node was built by
192
* ExecInitExpr. (In some cases, we change this pointer later to avoid
193
* re-executing one-time overhead.)
195
* Note: for notational simplicity we declare these functions as taking the
196
* specific type of ExprState that they work on. This requires casting when
197
* assigning the function pointer in ExecInitExpr. Be careful that the
198
* function signature is declared correctly, because the cast suppresses
199
* automatic checking!
202
* All these functions share this calling convention:
205
* expression: the expression state tree to evaluate
206
* econtext: evaluation context information
209
* return value: Datum value of result
210
* *isNull: set to TRUE if result is NULL (actual return value is
211
* meaningless if so); set to FALSE if non-null result
212
* *isDone: set to indicator of set-result status
214
* A caller that can only accept a singleton (non-set) result should pass
215
* NULL for isDone; if the expression computes a set result then an error
216
* will be reported via ereport. If the caller does pass an isDone pointer
217
* then *isDone is set to one of these three states:
218
* ExprSingleResult singleton result (not a set)
219
* ExprMultipleResult return value is one element of a set
220
* ExprEndResult there are no more elements in the set
221
* When ExprMultipleResult is returned, the caller should invoke
222
* ExecEvalExpr() repeatedly until ExprEndResult is returned. ExprEndResult
223
* is returned after the last real set element. For convenience isNull will
224
* always be set TRUE when ExprEndResult is returned, but this should not be
225
* taken as indicating a NULL element of the set. Note that these return
226
* conventions allow us to distinguish among a singleton NULL, a NULL element
227
* of a set, and an empty set.
229
* The caller should already have switched into the temporary memory
230
* context econtext->ecxt_per_tuple_memory. The convenience entry point
231
* ExecEvalExprSwitchContext() is provided for callers who don't prefer to
232
* do the switch in an outer loop. We do not do the switch in these routines
233
* because it'd be a waste of cycles during nested expression evaluation.
234
* ----------------------------------------------------------------
241
* This function takes an ArrayRef and returns the extracted Datum
242
* if it's a simple reference, or the modified array value if it's
243
* an array assignment (i.e., array element or slice insertion).
245
* NOTE: if we get a NULL result from a subscript expression, we return NULL
246
* when it's an array reference, or raise an error when it's an assignment.
248
* NOTE: we deliberately refrain from applying DatumGetArrayTypeP() here,
249
* even though that might seem natural, because this code needs to support
250
* both varlena arrays and fixed-length array types. DatumGetArrayTypeP()
251
* only works for the varlena kind. The routines we call in arrayfuncs.c
252
* have to know the difference (that's what they need refattrlength for).
256
ExecEvalArrayRef(ArrayRefExprState *astate,
257
ExprContext *econtext,
259
ExprDoneCond *isDone)
261
ArrayRef *arrayRef = (ArrayRef *) astate->xprstate.expr;
262
ArrayType *array_source;
263
ArrayType *resultArray;
264
bool isAssignment = (arrayRef->refassgnexpr != NULL);
273
array_source = (ArrayType *)
274
DatumGetPointer(ExecEvalExpr(astate->refexpr,
280
* If refexpr yields NULL, and it's a fetch, then result is NULL. In the
281
* assignment case, we'll cons up something below.
285
if (isDone && *isDone == ExprEndResult)
286
return (Datum) NULL; /* end of set result */
291
foreach(l, astate->refupperindexpr)
293
ExprState *eltstate = (ExprState *) lfirst(l);
297
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
298
errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
301
upper.indx[i++] = DatumGetInt32(ExecEvalExpr(eltstate,
305
/* If any index expr yields NULL, result is NULL or error */
310
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
311
errmsg("array subscript in assignment must not be null")));
317
if (astate->reflowerindexpr != NIL)
319
foreach(l, astate->reflowerindexpr)
321
ExprState *eltstate = (ExprState *) lfirst(l);
325
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
326
errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
329
lower.indx[j++] = DatumGetInt32(ExecEvalExpr(eltstate,
333
/* If any index expr yields NULL, result is NULL or error */
338
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
339
errmsg("array subscript in assignment must not be null")));
344
/* this can't happen unless parser messed up */
346
elog(ERROR, "upper and lower index lists are not same length");
359
* We might have a nested-assignment situation, in which the
360
* refassgnexpr is itself a FieldStore or ArrayRef that needs to
361
* obtain and modify the previous value of the array element or slice
362
* being replaced. If so, we have to extract that value from the
363
* array and pass it down via the econtext's caseValue. It's safe to
364
* reuse the CASE mechanism because there cannot be a CASE between
365
* here and where the value would be needed, and an array assignment
366
* can't be within a CASE either. (So saving and restoring the
367
* caseValue is just paranoia, but let's do it anyway.)
369
* Since fetching the old element might be a nontrivial expense, do it
370
* only if the argument appears to actually need it.
372
save_datum = econtext->caseValue_datum;
373
save_isNull = econtext->caseValue_isNull;
375
if (isAssignmentIndirectionExpr(astate->refassgnexpr))
379
/* whole array is null, so any element or slice is too */
380
econtext->caseValue_datum = (Datum) 0;
381
econtext->caseValue_isNull = true;
383
else if (lIndex == NULL)
385
econtext->caseValue_datum = array_ref(array_source, i,
387
astate->refattrlength,
388
astate->refelemlength,
389
astate->refelembyval,
390
astate->refelemalign,
391
&econtext->caseValue_isNull);
395
resultArray = array_get_slice(array_source, i,
396
upper.indx, lower.indx,
397
astate->refattrlength,
398
astate->refelemlength,
399
astate->refelembyval,
400
astate->refelemalign);
401
econtext->caseValue_datum = PointerGetDatum(resultArray);
402
econtext->caseValue_isNull = false;
407
/* argument shouldn't need caseValue, but for safety set it null */
408
econtext->caseValue_datum = (Datum) 0;
409
econtext->caseValue_isNull = true;
413
* Evaluate the value to be assigned into the array.
415
sourceData = ExecEvalExpr(astate->refassgnexpr,
420
econtext->caseValue_datum = save_datum;
421
econtext->caseValue_isNull = save_isNull;
424
* For an assignment to a fixed-length array type, both the original
425
* array and the value to be assigned into it must be non-NULL, else
426
* we punt and return the original array.
428
if (astate->refattrlength > 0) /* fixed-length array? */
429
if (eisnull || *isNull)
430
return PointerGetDatum(array_source);
433
* For assignment to varlena arrays, we handle a NULL original array
434
* by substituting an empty (zero-dimensional) array; insertion of the
435
* new element will result in a singleton array value. It does not
436
* matter whether the new element is NULL.
440
array_source = construct_empty_array(arrayRef->refelemtype);
445
resultArray = array_set(array_source, i,
449
astate->refattrlength,
450
astate->refelemlength,
451
astate->refelembyval,
452
astate->refelemalign);
454
resultArray = array_set_slice(array_source, i,
455
upper.indx, lower.indx,
456
(ArrayType *) DatumGetPointer(sourceData),
458
astate->refattrlength,
459
astate->refelemlength,
460
astate->refelembyval,
461
astate->refelemalign);
462
return PointerGetDatum(resultArray);
466
return array_ref(array_source, i, upper.indx,
467
astate->refattrlength,
468
astate->refelemlength,
469
astate->refelembyval,
470
astate->refelemalign,
474
resultArray = array_get_slice(array_source, i,
475
upper.indx, lower.indx,
476
astate->refattrlength,
477
astate->refelemlength,
478
astate->refelembyval,
479
astate->refelemalign);
480
return PointerGetDatum(resultArray);
485
* Helper for ExecEvalArrayRef: is expr a nested FieldStore or ArrayRef
486
* that might need the old element value passed down?
488
* (We could use this in ExecEvalFieldStore too, but in that case passing
489
* the old value is so cheap there's no need.)
492
isAssignmentIndirectionExpr(ExprState *exprstate)
494
if (exprstate == NULL)
495
return false; /* just paranoia */
496
if (IsA(exprstate, FieldStoreState))
498
FieldStore *fstore = (FieldStore *) exprstate->expr;
500
if (fstore->arg && IsA(fstore->arg, CaseTestExpr))
503
else if (IsA(exprstate, ArrayRefExprState))
505
ArrayRef *arrayRef = (ArrayRef *) exprstate->expr;
507
if (arrayRef->refexpr && IsA(arrayRef->refexpr, CaseTestExpr))
513
/* ----------------------------------------------------------------
516
* Returns a Datum whose value is the value of the precomputed
517
* aggregate found in the given expression context.
518
* ----------------------------------------------------------------
521
ExecEvalAggref(AggrefExprState *aggref, ExprContext *econtext,
522
bool *isNull, ExprDoneCond *isDone)
525
*isDone = ExprSingleResult;
527
if (econtext->ecxt_aggvalues == NULL) /* safety check */
528
elog(ERROR, "no aggregates in this expression context");
530
*isNull = econtext->ecxt_aggnulls[aggref->aggno];
531
return econtext->ecxt_aggvalues[aggref->aggno];
534
/* ----------------------------------------------------------------
537
* Returns a Datum whose value is the value of the precomputed
538
* window function found in the given expression context.
539
* ----------------------------------------------------------------
542
ExecEvalWindowFunc(WindowFuncExprState *wfunc, ExprContext *econtext,
543
bool *isNull, ExprDoneCond *isDone)
546
*isDone = ExprSingleResult;
548
if (econtext->ecxt_aggvalues == NULL) /* safety check */
549
elog(ERROR, "no window functions in this expression context");
551
*isNull = econtext->ecxt_aggnulls[wfunc->wfuncno];
552
return econtext->ecxt_aggvalues[wfunc->wfuncno];
555
/* ----------------------------------------------------------------
558
* Returns a Datum whose value is the value of a range
559
* variable with respect to given expression context.
561
* Note: ExecEvalVar is executed only the first time through in a given plan;
562
* it changes the ExprState's function pointer to pass control directly to
563
* ExecEvalScalarVar, ExecEvalWholeRowVar, or ExecEvalWholeRowSlow after
564
* making one-time checks.
565
* ----------------------------------------------------------------
568
ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
569
bool *isNull, ExprDoneCond *isDone)
571
Var *variable = (Var *) exprstate->expr;
572
TupleTableSlot *slot;
576
*isDone = ExprSingleResult;
578
/* Get the input slot and attribute number we want */
579
switch (variable->varno)
581
case INNER: /* get the tuple from the inner node */
582
slot = econtext->ecxt_innertuple;
585
case OUTER: /* get the tuple from the outer node */
586
slot = econtext->ecxt_outertuple;
589
default: /* get the tuple from the relation being
591
slot = econtext->ecxt_scantuple;
595
attnum = variable->varattno;
597
if (attnum != InvalidAttrNumber)
600
* Scalar variable case.
602
* If it's a user attribute, check validity (bogus system attnums will
603
* be caught inside slot_getattr). What we have to check for here is
604
* the possibility of an attribute having been changed in type since
605
* the plan tree was created. Ideally the plan would get invalidated
606
* and not re-used, but until that day arrives, we need defenses.
607
* Fortunately it's sufficient to check once on the first time
610
* Note: we allow a reference to a dropped attribute. slot_getattr
611
* will force a NULL result in such cases.
613
* Note: ideally we'd check typmod as well as typid, but that seems
614
* impractical at the moment: in many cases the tupdesc will have been
615
* generated by ExecTypeFromTL(), and that can't guarantee to generate
616
* an accurate typmod in all cases, because some expression node types
617
* don't carry typmod.
621
TupleDesc slot_tupdesc = slot->tts_tupleDescriptor;
622
Form_pg_attribute attr;
624
if (attnum > slot_tupdesc->natts) /* should never happen */
625
elog(ERROR, "attribute number %d exceeds number of columns %d",
626
attnum, slot_tupdesc->natts);
628
attr = slot_tupdesc->attrs[attnum - 1];
630
/* can't check type if dropped, since atttypid is probably 0 */
631
if (!attr->attisdropped)
633
if (variable->vartype != attr->atttypid)
635
(errmsg("attribute %d has wrong type", attnum),
636
errdetail("Table has type %s, but query expects %s.",
637
format_type_be(attr->atttypid),
638
format_type_be(variable->vartype))));
642
/* Skip the checking on future executions of node */
643
exprstate->evalfunc = ExecEvalScalarVar;
645
/* Fetch the value from the slot */
646
return slot_getattr(slot, attnum, isNull);
651
* Whole-row variable.
653
* If it's a RECORD Var, we'll use the slot's type ID info. It's
654
* likely that the slot's type is also RECORD; if so, make sure it's
655
* been "blessed", so that the Datum can be interpreted later.
657
* If the Var identifies a named composite type, we must check that
658
* the actual tuple type is compatible with it.
660
TupleDesc slot_tupdesc = slot->tts_tupleDescriptor;
661
bool needslow = false;
663
if (variable->vartype == RECORDOID)
665
if (slot_tupdesc->tdtypeid == RECORDOID &&
666
slot_tupdesc->tdtypmod < 0)
667
assign_record_type_typmod(slot_tupdesc);
671
TupleDesc var_tupdesc;
675
* We really only care about number of attributes and data type.
676
* Also, we can ignore type mismatch on columns that are dropped
677
* in the destination type, so long as (1) the physical storage
678
* matches or (2) the actual column value is NULL. Case (1) is
679
* helpful in some cases involving out-of-date cached plans, while
680
* case (2) is expected behavior in situations such as an INSERT
681
* into a table with dropped columns (the planner typically
682
* generates an INT4 NULL regardless of the dropped column type).
683
* If we find a dropped column and cannot verify that case (1)
684
* holds, we have to use ExecEvalWholeRowSlow to check (2) for
685
* each row. Also, we have to allow the case that the slot has
686
* more columns than the Var's type, because we might be looking
687
* at the output of a subplan that includes resjunk columns. (XXX
688
* it would be nice to verify that the extra columns are all
689
* marked resjunk, but we haven't got access to the subplan
690
* targetlist here...) Resjunk columns should always be at the end
691
* of a targetlist, so it's sufficient to ignore them here; but we
692
* need to use ExecEvalWholeRowSlow to get rid of them in the
693
* eventual output tuples.
695
var_tupdesc = lookup_rowtype_tupdesc(variable->vartype, -1);
697
if (var_tupdesc->natts > slot_tupdesc->natts)
699
(errcode(ERRCODE_DATATYPE_MISMATCH),
700
errmsg("table row type and query-specified row type do not match"),
701
errdetail_plural("Table row contains %d attribute, but query expects %d.",
702
"Table row contains %d attributes, but query expects %d.",
705
var_tupdesc->natts)));
706
else if (var_tupdesc->natts < slot_tupdesc->natts)
707
needslow = true; /* need to trim trailing atts */
709
for (i = 0; i < var_tupdesc->natts; i++)
711
Form_pg_attribute vattr = var_tupdesc->attrs[i];
712
Form_pg_attribute sattr = slot_tupdesc->attrs[i];
714
if (vattr->atttypid == sattr->atttypid)
715
continue; /* no worries */
716
if (!vattr->attisdropped)
718
(errcode(ERRCODE_DATATYPE_MISMATCH),
719
errmsg("table row type and query-specified row type do not match"),
720
errdetail("Table has type %s at ordinal position %d, but query expects %s.",
721
format_type_be(sattr->atttypid),
723
format_type_be(vattr->atttypid))));
725
if (vattr->attlen != sattr->attlen ||
726
vattr->attalign != sattr->attalign)
727
needslow = true; /* need runtime check for null */
730
ReleaseTupleDesc(var_tupdesc);
733
/* Skip the checking on future executions of node */
735
exprstate->evalfunc = ExecEvalWholeRowSlow;
737
exprstate->evalfunc = ExecEvalWholeRowVar;
739
/* Fetch the value */
740
return (*exprstate->evalfunc) (exprstate, econtext, isNull, isDone);
744
/* ----------------------------------------------------------------
747
* Returns a Datum for a scalar variable.
748
* ----------------------------------------------------------------
751
ExecEvalScalarVar(ExprState *exprstate, ExprContext *econtext,
752
bool *isNull, ExprDoneCond *isDone)
754
Var *variable = (Var *) exprstate->expr;
755
TupleTableSlot *slot;
759
*isDone = ExprSingleResult;
761
/* Get the input slot and attribute number we want */
762
switch (variable->varno)
764
case INNER: /* get the tuple from the inner node */
765
slot = econtext->ecxt_innertuple;
768
case OUTER: /* get the tuple from the outer node */
769
slot = econtext->ecxt_outertuple;
772
default: /* get the tuple from the relation being
774
slot = econtext->ecxt_scantuple;
778
attnum = variable->varattno;
780
/* Fetch the value from the slot */
781
return slot_getattr(slot, attnum, isNull);
784
/* ----------------------------------------------------------------
785
* ExecEvalWholeRowVar
787
* Returns a Datum for a whole-row variable.
788
* ----------------------------------------------------------------
791
ExecEvalWholeRowVar(ExprState *exprstate, ExprContext *econtext,
792
bool *isNull, ExprDoneCond *isDone)
794
Var *variable = (Var *) exprstate->expr;
795
TupleTableSlot *slot;
798
HeapTupleHeader dtuple;
801
*isDone = ExprSingleResult;
804
/* Get the input slot we want */
805
switch (variable->varno)
807
case INNER: /* get the tuple from the inner node */
808
slot = econtext->ecxt_innertuple;
811
case OUTER: /* get the tuple from the outer node */
812
slot = econtext->ecxt_outertuple;
815
default: /* get the tuple from the relation being
817
slot = econtext->ecxt_scantuple;
821
tuple = ExecFetchSlotTuple(slot);
822
tupleDesc = slot->tts_tupleDescriptor;
825
* We have to make a copy of the tuple so we can safely insert the Datum
826
* overhead fields, which are not set in on-disk tuples.
828
dtuple = (HeapTupleHeader) palloc(tuple->t_len);
829
memcpy((char *) dtuple, (char *) tuple->t_data, tuple->t_len);
831
HeapTupleHeaderSetDatumLength(dtuple, tuple->t_len);
834
* If the Var identifies a named composite type, label the tuple with that
835
* type; otherwise use what is in the tupleDesc.
837
if (variable->vartype != RECORDOID)
839
HeapTupleHeaderSetTypeId(dtuple, variable->vartype);
840
HeapTupleHeaderSetTypMod(dtuple, variable->vartypmod);
844
HeapTupleHeaderSetTypeId(dtuple, tupleDesc->tdtypeid);
845
HeapTupleHeaderSetTypMod(dtuple, tupleDesc->tdtypmod);
848
return PointerGetDatum(dtuple);
851
/* ----------------------------------------------------------------
852
* ExecEvalWholeRowSlow
854
* Returns a Datum for a whole-row variable, in the "slow" cases where
855
* we can't just copy the subplan's output.
856
* ----------------------------------------------------------------
859
ExecEvalWholeRowSlow(ExprState *exprstate, ExprContext *econtext,
860
bool *isNull, ExprDoneCond *isDone)
862
Var *variable = (Var *) exprstate->expr;
863
TupleTableSlot *slot;
865
TupleDesc var_tupdesc;
866
HeapTupleHeader dtuple;
870
*isDone = ExprSingleResult;
873
/* Get the input slot we want */
874
switch (variable->varno)
876
case INNER: /* get the tuple from the inner node */
877
slot = econtext->ecxt_innertuple;
880
case OUTER: /* get the tuple from the outer node */
881
slot = econtext->ecxt_outertuple;
884
default: /* get the tuple from the relation being
886
slot = econtext->ecxt_scantuple;
891
* Currently, the only data modification case handled here is stripping of
892
* trailing resjunk fields, which we do in a slightly chintzy way by just
893
* adjusting the tuple's natts header field. Possibly there will someday
894
* be a need for more-extensive rearrangements, in which case we'd
895
* probably use tupconvert.c.
897
Assert(variable->vartype != RECORDOID);
898
var_tupdesc = lookup_rowtype_tupdesc(variable->vartype, -1);
900
tuple = ExecFetchSlotTuple(slot);
902
Assert(HeapTupleHeaderGetNatts(tuple->t_data) >= var_tupdesc->natts);
904
/* Check to see if any dropped attributes are non-null */
905
for (i = 0; i < var_tupdesc->natts; i++)
907
Form_pg_attribute vattr = var_tupdesc->attrs[i];
908
Form_pg_attribute sattr = slot->tts_tupleDescriptor->attrs[i];
910
if (!vattr->attisdropped)
911
continue; /* already checked non-dropped cols */
912
if (heap_attisnull(tuple, i + 1))
913
continue; /* null is always okay */
914
if (vattr->attlen != sattr->attlen ||
915
vattr->attalign != sattr->attalign)
917
(errcode(ERRCODE_DATATYPE_MISMATCH),
918
errmsg("table row type and query-specified row type do not match"),
919
errdetail("Physical storage mismatch on dropped attribute at ordinal position %d.",
924
* We have to make a copy of the tuple so we can safely insert the Datum
925
* overhead fields, which are not set in on-disk tuples; not to mention
926
* fooling with its natts field.
928
dtuple = (HeapTupleHeader) palloc(tuple->t_len);
929
memcpy((char *) dtuple, (char *) tuple->t_data, tuple->t_len);
931
HeapTupleHeaderSetDatumLength(dtuple, tuple->t_len);
932
HeapTupleHeaderSetTypeId(dtuple, variable->vartype);
933
HeapTupleHeaderSetTypMod(dtuple, variable->vartypmod);
935
HeapTupleHeaderSetNatts(dtuple, var_tupdesc->natts);
937
ReleaseTupleDesc(var_tupdesc);
939
return PointerGetDatum(dtuple);
942
/* ----------------------------------------------------------------
945
* Returns the value of a constant.
947
* Note that for pass-by-ref datatypes, we return a pointer to the
948
* actual constant node. This is one of the reasons why functions
949
* must treat their input arguments as read-only.
950
* ----------------------------------------------------------------
953
ExecEvalConst(ExprState *exprstate, ExprContext *econtext,
954
bool *isNull, ExprDoneCond *isDone)
956
Const *con = (Const *) exprstate->expr;
959
*isDone = ExprSingleResult;
961
*isNull = con->constisnull;
962
return con->constvalue;
965
/* ----------------------------------------------------------------
968
* Returns the value of a PARAM_EXEC parameter.
969
* ----------------------------------------------------------------
972
ExecEvalParamExec(ExprState *exprstate, ExprContext *econtext,
973
bool *isNull, ExprDoneCond *isDone)
975
Param *expression = (Param *) exprstate->expr;
976
int thisParamId = expression->paramid;
980
*isDone = ExprSingleResult;
983
* PARAM_EXEC params (internal executor parameters) are stored in the
984
* ecxt_param_exec_vals array, and can be accessed by array index.
986
prm = &(econtext->ecxt_param_exec_vals[thisParamId]);
987
if (prm->execPlan != NULL)
989
/* Parameter not evaluated yet, so go do it */
990
ExecSetParamPlan(prm->execPlan, econtext);
991
/* ExecSetParamPlan should have processed this param... */
992
Assert(prm->execPlan == NULL);
994
*isNull = prm->isnull;
998
/* ----------------------------------------------------------------
999
* ExecEvalParamExtern
1001
* Returns the value of a PARAM_EXTERN parameter.
1002
* ----------------------------------------------------------------
1005
ExecEvalParamExtern(ExprState *exprstate, ExprContext *econtext,
1006
bool *isNull, ExprDoneCond *isDone)
1008
Param *expression = (Param *) exprstate->expr;
1009
int thisParamId = expression->paramid;
1010
ParamListInfo paramInfo = econtext->ecxt_param_list_info;
1013
*isDone = ExprSingleResult;
1016
* PARAM_EXTERN parameters must be sought in ecxt_param_list_info.
1019
thisParamId > 0 && thisParamId <= paramInfo->numParams)
1021
ParamExternData *prm = ¶mInfo->params[thisParamId - 1];
1023
/* give hook a chance in case parameter is dynamic */
1024
if (!OidIsValid(prm->ptype) && paramInfo->paramFetch != NULL)
1025
(*paramInfo->paramFetch) (paramInfo, thisParamId);
1027
if (OidIsValid(prm->ptype))
1029
/* safety check in case hook did something unexpected */
1030
if (prm->ptype != expression->paramtype)
1032
(errcode(ERRCODE_DATATYPE_MISMATCH),
1033
errmsg("type of parameter %d (%s) does not match that when preparing the plan (%s)",
1035
format_type_be(prm->ptype),
1036
format_type_be(expression->paramtype))));
1038
*isNull = prm->isnull;
1044
(errcode(ERRCODE_UNDEFINED_OBJECT),
1045
errmsg("no value found for parameter %d", thisParamId)));
1046
return (Datum) 0; /* keep compiler quiet */
1050
/* ----------------------------------------------------------------
1051
* ExecEvalOper / ExecEvalFunc support routines
1052
* ----------------------------------------------------------------
1056
* GetAttributeByName
1059
* These functions return the value of the requested attribute
1060
* out of the given tuple Datum.
1061
* C functions which take a tuple as an argument are expected
1062
* to use these. Ex: overpaid(EMP) might call GetAttributeByNum().
1063
* Note: these are actually rather slow because they do a typcache
1064
* lookup on each call.
1067
GetAttributeByNum(HeapTupleHeader tuple,
1075
HeapTupleData tmptup;
1077
if (!AttributeNumberIsValid(attrno))
1078
elog(ERROR, "invalid attribute number %d", attrno);
1081
elog(ERROR, "a NULL isNull pointer was passed");
1085
/* Kinda bogus but compatible with old behavior... */
1090
tupType = HeapTupleHeaderGetTypeId(tuple);
1091
tupTypmod = HeapTupleHeaderGetTypMod(tuple);
1092
tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
1095
* heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
1096
* the fields in the struct just in case user tries to inspect system
1099
tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
1100
ItemPointerSetInvalid(&(tmptup.t_self));
1101
tmptup.t_tableOid = InvalidOid;
1102
tmptup.t_data = tuple;
1104
result = heap_getattr(&tmptup,
1109
ReleaseTupleDesc(tupDesc);
1115
GetAttributeByName(HeapTupleHeader tuple, const char *attname, bool *isNull)
1122
HeapTupleData tmptup;
1125
if (attname == NULL)
1126
elog(ERROR, "invalid attribute name");
1129
elog(ERROR, "a NULL isNull pointer was passed");
1133
/* Kinda bogus but compatible with old behavior... */
1138
tupType = HeapTupleHeaderGetTypeId(tuple);
1139
tupTypmod = HeapTupleHeaderGetTypMod(tuple);
1140
tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
1142
attrno = InvalidAttrNumber;
1143
for (i = 0; i < tupDesc->natts; i++)
1145
if (namestrcmp(&(tupDesc->attrs[i]->attname), attname) == 0)
1147
attrno = tupDesc->attrs[i]->attnum;
1152
if (attrno == InvalidAttrNumber)
1153
elog(ERROR, "attribute \"%s\" does not exist", attname);
1156
* heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
1157
* the fields in the struct just in case user tries to inspect system
1160
tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
1161
ItemPointerSetInvalid(&(tmptup.t_self));
1162
tmptup.t_tableOid = InvalidOid;
1163
tmptup.t_data = tuple;
1165
result = heap_getattr(&tmptup,
1170
ReleaseTupleDesc(tupDesc);
1176
* init_fcache - initialize a FuncExprState node during first use
1179
init_fcache(Oid foid, Oid input_collation, FuncExprState *fcache,
1180
MemoryContext fcacheCxt, bool needDescForSets)
1182
AclResult aclresult;
1184
/* Check permission to call function */
1185
aclresult = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE);
1186
if (aclresult != ACLCHECK_OK)
1187
aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(foid));
1190
* Safety check on nargs. Under normal circumstances this should never
1191
* fail, as parser should check sooner. But possibly it might fail if
1192
* server has been compiled with FUNC_MAX_ARGS smaller than some functions
1193
* declared in pg_proc?
1195
if (list_length(fcache->args) > FUNC_MAX_ARGS)
1197
(errcode(ERRCODE_TOO_MANY_ARGUMENTS),
1198
errmsg_plural("cannot pass more than %d argument to a function",
1199
"cannot pass more than %d arguments to a function",
1203
/* Set up the primary fmgr lookup information */
1204
fmgr_info_cxt(foid, &(fcache->func), fcacheCxt);
1205
fmgr_info_set_expr((Node *) fcache->xprstate.expr, &(fcache->func));
1207
/* Initialize the function call parameter struct as well */
1208
InitFunctionCallInfoData(fcache->fcinfo_data, &(fcache->func),
1209
list_length(fcache->args),
1210
input_collation, NULL, NULL);
1212
/* If function returns set, prepare expected tuple descriptor */
1213
if (fcache->func.fn_retset && needDescForSets)
1215
TypeFuncClass functypclass;
1218
MemoryContext oldcontext;
1220
functypclass = get_expr_result_type(fcache->func.fn_expr,
1224
/* Must save tupdesc in fcache's context */
1225
oldcontext = MemoryContextSwitchTo(fcacheCxt);
1227
if (functypclass == TYPEFUNC_COMPOSITE)
1229
/* Composite data type, e.g. a table's row type */
1231
/* Must copy it out of typcache for safety */
1232
fcache->funcResultDesc = CreateTupleDescCopy(tupdesc);
1233
fcache->funcReturnsTuple = true;
1235
else if (functypclass == TYPEFUNC_SCALAR)
1237
/* Base data type, i.e. scalar */
1238
tupdesc = CreateTemplateTupleDesc(1, false);
1239
TupleDescInitEntry(tupdesc,
1245
fcache->funcResultDesc = tupdesc;
1246
fcache->funcReturnsTuple = false;
1248
else if (functypclass == TYPEFUNC_RECORD)
1250
/* This will work if function doesn't need an expectedDesc */
1251
fcache->funcResultDesc = NULL;
1252
fcache->funcReturnsTuple = true;
1256
/* Else, we will fail if function needs an expectedDesc */
1257
fcache->funcResultDesc = NULL;
1260
MemoryContextSwitchTo(oldcontext);
1263
fcache->funcResultDesc = NULL;
1265
/* Initialize additional state */
1266
fcache->funcResultStore = NULL;
1267
fcache->funcResultSlot = NULL;
1268
fcache->setArgsValid = false;
1269
fcache->shutdown_reg = false;
1273
* callback function in case a FuncExpr returning a set needs to be shut down
1274
* before it has been run to completion
1277
ShutdownFuncExpr(Datum arg)
1279
FuncExprState *fcache = (FuncExprState *) DatumGetPointer(arg);
1281
/* If we have a slot, make sure it's let go of any tuplestore pointer */
1282
if (fcache->funcResultSlot)
1283
ExecClearTuple(fcache->funcResultSlot);
1285
/* Release any open tuplestore */
1286
if (fcache->funcResultStore)
1287
tuplestore_end(fcache->funcResultStore);
1288
fcache->funcResultStore = NULL;
1290
/* Clear any active set-argument state */
1291
fcache->setArgsValid = false;
1293
/* execUtils will deregister the callback... */
1294
fcache->shutdown_reg = false;
1298
* get_cached_rowtype: utility function to lookup a rowtype tupdesc
1300
* type_id, typmod: identity of the rowtype
1301
* cache_field: where to cache the TupleDesc pointer in expression state node
1302
* (field must be initialized to NULL)
1303
* econtext: expression context we are executing in
1305
* NOTE: because the shutdown callback will be called during plan rescan,
1306
* must be prepared to re-do this during any node execution; cannot call
1307
* just once during expression initialization
1310
get_cached_rowtype(Oid type_id, int32 typmod,
1311
TupleDesc *cache_field, ExprContext *econtext)
1313
TupleDesc tupDesc = *cache_field;
1315
/* Do lookup if no cached value or if requested type changed */
1316
if (tupDesc == NULL ||
1317
type_id != tupDesc->tdtypeid ||
1318
typmod != tupDesc->tdtypmod)
1320
tupDesc = lookup_rowtype_tupdesc(type_id, typmod);
1324
/* Release old tupdesc; but callback is already registered */
1325
ReleaseTupleDesc(*cache_field);
1329
/* Need to register shutdown callback to release tupdesc */
1330
RegisterExprContextCallback(econtext,
1331
ShutdownTupleDescRef,
1332
PointerGetDatum(cache_field));
1334
*cache_field = tupDesc;
1340
* Callback function to release a tupdesc refcount at expression tree shutdown
1343
ShutdownTupleDescRef(Datum arg)
1345
TupleDesc *cache_field = (TupleDesc *) DatumGetPointer(arg);
1348
ReleaseTupleDesc(*cache_field);
1349
*cache_field = NULL;
1353
* Evaluate arguments for a function.
1356
ExecEvalFuncArgs(FunctionCallInfo fcinfo,
1358
ExprContext *econtext)
1360
ExprDoneCond argIsDone;
1364
argIsDone = ExprSingleResult; /* default assumption */
1367
foreach(arg, argList)
1369
ExprState *argstate = (ExprState *) lfirst(arg);
1370
ExprDoneCond thisArgIsDone;
1372
fcinfo->arg[i] = ExecEvalExpr(argstate,
1374
&fcinfo->argnull[i],
1377
if (thisArgIsDone != ExprSingleResult)
1380
* We allow only one argument to have a set value; we'd need much
1381
* more complexity to keep track of multiple set arguments (cf.
1382
* ExecTargetList) and it doesn't seem worth it.
1384
if (argIsDone != ExprSingleResult)
1386
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1387
errmsg("functions and operators can take at most one set argument")));
1388
argIsDone = thisArgIsDone;
1393
Assert(i == fcinfo->nargs);
1399
* ExecPrepareTuplestoreResult
1401
* Subroutine for ExecMakeFunctionResult: prepare to extract rows from a
1402
* tuplestore function result. We must set up a funcResultSlot (unless
1403
* already done in a previous call cycle) and verify that the function
1404
* returned the expected tuple descriptor.
1407
ExecPrepareTuplestoreResult(FuncExprState *fcache,
1408
ExprContext *econtext,
1409
Tuplestorestate *resultStore,
1410
TupleDesc resultDesc)
1412
fcache->funcResultStore = resultStore;
1414
if (fcache->funcResultSlot == NULL)
1416
/* Create a slot so we can read data out of the tuplestore */
1418
MemoryContext oldcontext;
1420
oldcontext = MemoryContextSwitchTo(fcache->func.fn_mcxt);
1423
* If we were not able to determine the result rowtype from context,
1424
* and the function didn't return a tupdesc, we have to fail.
1426
if (fcache->funcResultDesc)
1427
slotDesc = fcache->funcResultDesc;
1428
else if (resultDesc)
1430
/* don't assume resultDesc is long-lived */
1431
slotDesc = CreateTupleDescCopy(resultDesc);
1436
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1437
errmsg("function returning setof record called in "
1438
"context that cannot accept type record")));
1439
slotDesc = NULL; /* keep compiler quiet */
1442
fcache->funcResultSlot = MakeSingleTupleTableSlot(slotDesc);
1443
MemoryContextSwitchTo(oldcontext);
1447
* If function provided a tupdesc, cross-check it. We only really need to
1448
* do this for functions returning RECORD, but might as well do it always.
1452
if (fcache->funcResultDesc)
1453
tupledesc_match(fcache->funcResultDesc, resultDesc);
1456
* If it is a dynamically-allocated TupleDesc, free it: it is
1457
* typically allocated in a per-query context, so we must avoid
1458
* leaking it across multiple usages.
1460
if (resultDesc->tdrefcount == -1)
1461
FreeTupleDesc(resultDesc);
1464
/* Register cleanup callback if we didn't already */
1465
if (!fcache->shutdown_reg)
1467
RegisterExprContextCallback(econtext,
1469
PointerGetDatum(fcache));
1470
fcache->shutdown_reg = true;
1475
* Check that function result tuple type (src_tupdesc) matches or can
1476
* be considered to match what the query expects (dst_tupdesc). If
1477
* they don't match, ereport.
1479
* We really only care about number of attributes and data type.
1480
* Also, we can ignore type mismatch on columns that are dropped in the
1481
* destination type, so long as the physical storage matches. This is
1482
* helpful in some cases involving out-of-date cached plans.
1485
tupledesc_match(TupleDesc dst_tupdesc, TupleDesc src_tupdesc)
1489
if (dst_tupdesc->natts != src_tupdesc->natts)
1491
(errcode(ERRCODE_DATATYPE_MISMATCH),
1492
errmsg("function return row and query-specified return row do not match"),
1493
errdetail_plural("Returned row contains %d attribute, but query expects %d.",
1494
"Returned row contains %d attributes, but query expects %d.",
1496
src_tupdesc->natts, dst_tupdesc->natts)));
1498
for (i = 0; i < dst_tupdesc->natts; i++)
1500
Form_pg_attribute dattr = dst_tupdesc->attrs[i];
1501
Form_pg_attribute sattr = src_tupdesc->attrs[i];
1503
if (IsBinaryCoercible(sattr->atttypid, dattr->atttypid))
1504
continue; /* no worries */
1505
if (!dattr->attisdropped)
1507
(errcode(ERRCODE_DATATYPE_MISMATCH),
1508
errmsg("function return row and query-specified return row do not match"),
1509
errdetail("Returned type %s at ordinal position %d, but query expects %s.",
1510
format_type_be(sattr->atttypid),
1512
format_type_be(dattr->atttypid))));
1514
if (dattr->attlen != sattr->attlen ||
1515
dattr->attalign != sattr->attalign)
1517
(errcode(ERRCODE_DATATYPE_MISMATCH),
1518
errmsg("function return row and query-specified return row do not match"),
1519
errdetail("Physical storage mismatch on dropped attribute at ordinal position %d.",
1525
* ExecMakeFunctionResult
1527
* Evaluate the arguments to a function and then the function itself.
1528
* init_fcache is presumed already run on the FuncExprState.
1530
* This function handles the most general case, wherein the function or
1531
* one of its arguments might (or might not) return a set. If we find
1532
* no sets involved, we will change the FuncExprState's function pointer
1533
* to use a simpler method on subsequent calls.
1536
ExecMakeFunctionResult(FuncExprState *fcache,
1537
ExprContext *econtext,
1539
ExprDoneCond *isDone)
1543
FunctionCallInfo fcinfo;
1544
PgStat_FunctionCallUsage fcusage;
1545
ReturnSetInfo rsinfo; /* for functions returning sets */
1546
ExprDoneCond argDone;
1552
/* Guard against stack overflow due to overly complex expressions */
1553
check_stack_depth();
1556
* If a previous call of the function returned a set result in the form of
1557
* a tuplestore, continue reading rows from the tuplestore until it's
1560
if (fcache->funcResultStore)
1562
Assert(isDone); /* it was provided before ... */
1563
if (tuplestore_gettupleslot(fcache->funcResultStore, true, false,
1564
fcache->funcResultSlot))
1566
*isDone = ExprMultipleResult;
1567
if (fcache->funcReturnsTuple)
1569
/* We must return the whole tuple as a Datum. */
1571
return ExecFetchSlotTupleDatum(fcache->funcResultSlot);
1575
/* Extract the first column and return it as a scalar. */
1576
return slot_getattr(fcache->funcResultSlot, 1, isNull);
1579
/* Exhausted the tuplestore, so clean up */
1580
tuplestore_end(fcache->funcResultStore);
1581
fcache->funcResultStore = NULL;
1582
/* We are done unless there was a set-valued argument */
1583
if (!fcache->setHasSetArg)
1585
*isDone = ExprEndResult;
1589
/* If there was, continue evaluating the argument values */
1590
Assert(!fcache->setArgsValid);
1594
* arguments is a list of expressions to evaluate before passing to the
1595
* function manager. We skip the evaluation if it was already done in the
1596
* previous call (ie, we are continuing the evaluation of a set-valued
1597
* function). Otherwise, collect the current argument values into fcinfo.
1599
fcinfo = &fcache->fcinfo_data;
1600
arguments = fcache->args;
1601
if (!fcache->setArgsValid)
1603
argDone = ExecEvalFuncArgs(fcinfo, arguments, econtext);
1604
if (argDone == ExprEndResult)
1606
/* input is an empty set, so return an empty set. */
1609
*isDone = ExprEndResult;
1612
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1613
errmsg("set-valued function called in context that cannot accept a set")));
1616
hasSetArg = (argDone != ExprSingleResult);
1620
/* Re-use callinfo from previous evaluation */
1621
hasSetArg = fcache->setHasSetArg;
1622
/* Reset flag (we may set it again below) */
1623
fcache->setArgsValid = false;
1627
* Now call the function, passing the evaluated parameter values.
1629
if (fcache->func.fn_retset || hasSetArg)
1632
* We need to return a set result. Complain if caller not ready to
1637
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1638
errmsg("set-valued function called in context that cannot accept a set")));
1641
* Prepare a resultinfo node for communication. If the function
1642
* doesn't itself return set, we don't pass the resultinfo to the
1643
* function, but we need to fill it in anyway for internal use.
1645
if (fcache->func.fn_retset)
1646
fcinfo->resultinfo = (Node *) &rsinfo;
1647
rsinfo.type = T_ReturnSetInfo;
1648
rsinfo.econtext = econtext;
1649
rsinfo.expectedDesc = fcache->funcResultDesc;
1650
rsinfo.allowedModes = (int) (SFRM_ValuePerCall | SFRM_Materialize);
1651
/* note we do not set SFRM_Materialize_Random or _Preferred */
1652
rsinfo.returnMode = SFRM_ValuePerCall;
1653
/* isDone is filled below */
1654
rsinfo.setResult = NULL;
1655
rsinfo.setDesc = NULL;
1658
* This loop handles the situation where we have both a set argument
1659
* and a set-valued function. Once we have exhausted the function's
1660
* value(s) for a particular argument value, we have to get the next
1661
* argument value and start the function over again. We might have to
1662
* do it more than once, if the function produces an empty result set
1663
* for a particular input value.
1668
* If function is strict, and there are any NULL arguments, skip
1669
* calling the function (at least for this set of args).
1673
if (fcache->func.fn_strict)
1675
for (i = 0; i < fcinfo->nargs; i++)
1677
if (fcinfo->argnull[i])
1687
pgstat_init_function_usage(fcinfo, &fcusage);
1689
fcinfo->isnull = false;
1690
rsinfo.isDone = ExprSingleResult;
1691
result = FunctionCallInvoke(fcinfo);
1692
*isNull = fcinfo->isnull;
1693
*isDone = rsinfo.isDone;
1695
pgstat_end_function_usage(&fcusage,
1696
rsinfo.isDone != ExprMultipleResult);
1702
*isDone = ExprEndResult;
1705
/* Which protocol does function want to use? */
1706
if (rsinfo.returnMode == SFRM_ValuePerCall)
1708
if (*isDone != ExprEndResult)
1711
* Got a result from current argument. If function itself
1712
* returns set, save the current argument values to re-use
1715
if (fcache->func.fn_retset &&
1716
*isDone == ExprMultipleResult)
1718
fcache->setHasSetArg = hasSetArg;
1719
fcache->setArgsValid = true;
1720
/* Register cleanup callback if we didn't already */
1721
if (!fcache->shutdown_reg)
1723
RegisterExprContextCallback(econtext,
1725
PointerGetDatum(fcache));
1726
fcache->shutdown_reg = true;
1731
* Make sure we say we are returning a set, even if the
1732
* function itself doesn't return sets.
1735
*isDone = ExprMultipleResult;
1739
else if (rsinfo.returnMode == SFRM_Materialize)
1741
/* check we're on the same page as the function author */
1742
if (rsinfo.isDone != ExprSingleResult)
1744
(errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
1745
errmsg("table-function protocol for materialize mode was not followed")));
1746
if (rsinfo.setResult != NULL)
1748
/* prepare to return values from the tuplestore */
1749
ExecPrepareTuplestoreResult(fcache, econtext,
1752
/* remember whether we had set arguments */
1753
fcache->setHasSetArg = hasSetArg;
1754
/* loop back to top to start returning from tuplestore */
1757
/* if setResult was left null, treat it as empty set */
1758
*isDone = ExprEndResult;
1764
(errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
1765
errmsg("unrecognized table-function returnMode: %d",
1766
(int) rsinfo.returnMode)));
1768
/* Else, done with this argument */
1770
break; /* input not a set, so done */
1772
/* Re-eval args to get the next element of the input set */
1773
argDone = ExecEvalFuncArgs(fcinfo, arguments, econtext);
1775
if (argDone != ExprMultipleResult)
1777
/* End of argument set, so we're done. */
1779
*isDone = ExprEndResult;
1785
* If we reach here, loop around to run the function on the new
1793
* Non-set case: much easier.
1795
* We change the ExprState function pointer to use the simpler
1796
* ExecMakeFunctionResultNoSets on subsequent calls. This amounts to
1797
* assuming that no argument can return a set if it didn't do so the
1800
fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResultNoSets;
1803
*isDone = ExprSingleResult;
1806
* If function is strict, and there are any NULL arguments, skip
1807
* calling the function and return NULL.
1809
if (fcache->func.fn_strict)
1811
for (i = 0; i < fcinfo->nargs; i++)
1813
if (fcinfo->argnull[i])
1821
pgstat_init_function_usage(fcinfo, &fcusage);
1823
fcinfo->isnull = false;
1824
result = FunctionCallInvoke(fcinfo);
1825
*isNull = fcinfo->isnull;
1827
pgstat_end_function_usage(&fcusage, true);
1834
* ExecMakeFunctionResultNoSets
1836
* Simplified version of ExecMakeFunctionResult that can only handle
1837
* non-set cases. Hand-tuned for speed.
1840
ExecMakeFunctionResultNoSets(FuncExprState *fcache,
1841
ExprContext *econtext,
1843
ExprDoneCond *isDone)
1847
FunctionCallInfo fcinfo;
1848
PgStat_FunctionCallUsage fcusage;
1851
/* Guard against stack overflow due to overly complex expressions */
1852
check_stack_depth();
1855
*isDone = ExprSingleResult;
1857
/* inlined, simplified version of ExecEvalFuncArgs */
1858
fcinfo = &fcache->fcinfo_data;
1860
foreach(arg, fcache->args)
1862
ExprState *argstate = (ExprState *) lfirst(arg);
1864
fcinfo->arg[i] = ExecEvalExpr(argstate,
1866
&fcinfo->argnull[i],
1872
* If function is strict, and there are any NULL arguments, skip calling
1873
* the function and return NULL.
1875
if (fcache->func.fn_strict)
1879
if (fcinfo->argnull[i])
1887
pgstat_init_function_usage(fcinfo, &fcusage);
1889
fcinfo->isnull = false;
1890
result = FunctionCallInvoke(fcinfo);
1891
*isNull = fcinfo->isnull;
1893
pgstat_end_function_usage(&fcusage, true);
1900
* ExecMakeTableFunctionResult
1902
* Evaluate a table function, producing a materialized result in a Tuplestore
1906
ExecMakeTableFunctionResult(ExprState *funcexpr,
1907
ExprContext *econtext,
1908
TupleDesc expectedDesc,
1911
Tuplestorestate *tupstore = NULL;
1912
TupleDesc tupdesc = NULL;
1915
bool returnsSet = false;
1916
FunctionCallInfoData fcinfo;
1917
PgStat_FunctionCallUsage fcusage;
1918
ReturnSetInfo rsinfo;
1919
HeapTupleData tmptup;
1920
MemoryContext callerContext;
1921
MemoryContext oldcontext;
1922
bool direct_function_call;
1923
bool first_time = true;
1925
callerContext = CurrentMemoryContext;
1927
funcrettype = exprType((Node *) funcexpr->expr);
1929
returnsTuple = type_is_rowtype(funcrettype);
1932
* Prepare a resultinfo node for communication. We always do this even if
1933
* not expecting a set result, so that we can pass expectedDesc. In the
1934
* generic-expression case, the expression doesn't actually get to see the
1935
* resultinfo, but set it up anyway because we use some of the fields as
1936
* our own state variables.
1938
rsinfo.type = T_ReturnSetInfo;
1939
rsinfo.econtext = econtext;
1940
rsinfo.expectedDesc = expectedDesc;
1941
rsinfo.allowedModes = (int) (SFRM_ValuePerCall | SFRM_Materialize | SFRM_Materialize_Preferred);
1943
rsinfo.allowedModes |= (int) SFRM_Materialize_Random;
1944
rsinfo.returnMode = SFRM_ValuePerCall;
1945
/* isDone is filled below */
1946
rsinfo.setResult = NULL;
1947
rsinfo.setDesc = NULL;
1950
* Normally the passed expression tree will be a FuncExprState, since the
1951
* grammar only allows a function call at the top level of a table
1952
* function reference. However, if the function doesn't return set then
1953
* the planner might have replaced the function call via constant-folding
1954
* or inlining. So if we see any other kind of expression node, execute
1955
* it via the general ExecEvalExpr() code; the only difference is that we
1956
* don't get a chance to pass a special ReturnSetInfo to any functions
1957
* buried in the expression.
1959
if (funcexpr && IsA(funcexpr, FuncExprState) &&
1960
IsA(funcexpr->expr, FuncExpr))
1962
FuncExprState *fcache = (FuncExprState *) funcexpr;
1963
ExprDoneCond argDone;
1966
* This path is similar to ExecMakeFunctionResult.
1968
direct_function_call = true;
1971
* Initialize function cache if first time through
1973
if (fcache->func.fn_oid == InvalidOid)
1975
FuncExpr *func = (FuncExpr *) fcache->xprstate.expr;
1977
init_fcache(func->funcid, func->inputcollid, fcache,
1978
econtext->ecxt_per_query_memory, false);
1980
returnsSet = fcache->func.fn_retset;
1981
InitFunctionCallInfoData(fcinfo, &(fcache->func),
1982
list_length(fcache->args),
1983
fcache->fcinfo_data.fncollation,
1984
NULL, (Node *) &rsinfo);
1987
* Evaluate the function's argument list.
1989
* Note: ideally, we'd do this in the per-tuple context, but then the
1990
* argument values would disappear when we reset the context in the
1991
* inner loop. So do it in caller context. Perhaps we should make a
1992
* separate context just to hold the evaluated arguments?
1994
argDone = ExecEvalFuncArgs(&fcinfo, fcache->args, econtext);
1995
/* We don't allow sets in the arguments of the table function */
1996
if (argDone != ExprSingleResult)
1998
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1999
errmsg("set-valued function called in context that cannot accept a set")));
2002
* If function is strict, and there are any NULL arguments, skip
2003
* calling the function and act like it returned NULL (or an empty
2004
* set, in the returns-set case).
2006
if (fcache->func.fn_strict)
2010
for (i = 0; i < fcinfo.nargs; i++)
2012
if (fcinfo.argnull[i])
2013
goto no_function_result;
2019
/* Treat funcexpr as a generic expression */
2020
direct_function_call = false;
2021
InitFunctionCallInfoData(fcinfo, NULL, 0, InvalidOid, NULL, NULL);
2025
* Switch to short-lived context for calling the function or expression.
2027
MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
2030
* Loop to handle the ValuePerCall protocol (which is also the same
2031
* behavior needed in the generic ExecEvalExpr path).
2037
CHECK_FOR_INTERRUPTS();
2040
* reset per-tuple memory context before each call of the function or
2041
* expression. This cleans up any local memory the function may leak
2044
ResetExprContext(econtext);
2046
/* Call the function or expression one time */
2047
if (direct_function_call)
2049
pgstat_init_function_usage(&fcinfo, &fcusage);
2051
fcinfo.isnull = false;
2052
rsinfo.isDone = ExprSingleResult;
2053
result = FunctionCallInvoke(&fcinfo);
2055
pgstat_end_function_usage(&fcusage,
2056
rsinfo.isDone != ExprMultipleResult);
2060
result = ExecEvalExpr(funcexpr, econtext,
2061
&fcinfo.isnull, &rsinfo.isDone);
2064
/* Which protocol does function want to use? */
2065
if (rsinfo.returnMode == SFRM_ValuePerCall)
2068
* Check for end of result set.
2070
if (rsinfo.isDone == ExprEndResult)
2074
* Can't do anything very useful with NULL rowtype values. For a
2075
* function returning set, we consider this a protocol violation
2076
* (but another alternative would be to just ignore the result and
2077
* "continue" to get another row). For a function not returning
2078
* set, we fall out of the loop; we'll cons up an all-nulls result
2081
if (returnsTuple && fcinfo.isnull)
2086
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
2087
errmsg("function returning set of rows cannot return null value")));
2091
* If first time through, build tupdesc and tuplestore for result
2095
oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
2099
* Use the type info embedded in the rowtype Datum to look
2100
* up the needed tupdesc. Make a copy for the query.
2104
td = DatumGetHeapTupleHeader(result);
2105
tupdesc = lookup_rowtype_tupdesc_copy(HeapTupleHeaderGetTypeId(td),
2106
HeapTupleHeaderGetTypMod(td));
2111
* Scalar type, so make a single-column descriptor
2113
tupdesc = CreateTemplateTupleDesc(1, false);
2114
TupleDescInitEntry(tupdesc,
2121
tupstore = tuplestore_begin_heap(randomAccess, false, work_mem);
2122
MemoryContextSwitchTo(oldcontext);
2123
rsinfo.setResult = tupstore;
2124
rsinfo.setDesc = tupdesc;
2128
* Store current resultset item.
2134
td = DatumGetHeapTupleHeader(result);
2137
* Verify all returned rows have same subtype; necessary in
2138
* case the type is RECORD.
2140
if (HeapTupleHeaderGetTypeId(td) != tupdesc->tdtypeid ||
2141
HeapTupleHeaderGetTypMod(td) != tupdesc->tdtypmod)
2143
(errcode(ERRCODE_DATATYPE_MISMATCH),
2144
errmsg("rows returned by function are not all of the same row type")));
2147
* tuplestore_puttuple needs a HeapTuple not a bare
2148
* HeapTupleHeader, but it doesn't need all the fields.
2150
tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
2153
tuplestore_puttuple(tupstore, &tmptup);
2156
tuplestore_putvalues(tupstore, tupdesc, &result, &fcinfo.isnull);
2161
if (rsinfo.isDone != ExprMultipleResult)
2164
else if (rsinfo.returnMode == SFRM_Materialize)
2166
/* check we're on the same page as the function author */
2167
if (!first_time || rsinfo.isDone != ExprSingleResult)
2169
(errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
2170
errmsg("table-function protocol for materialize mode was not followed")));
2171
/* Done evaluating the set result */
2176
(errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
2177
errmsg("unrecognized table-function returnMode: %d",
2178
(int) rsinfo.returnMode)));
2186
* If we got nothing from the function (ie, an empty-set or NULL result),
2187
* we have to create the tuplestore to return, and if it's a
2188
* non-set-returning function then insert a single all-nulls row.
2190
if (rsinfo.setResult == NULL)
2192
MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
2193
tupstore = tuplestore_begin_heap(randomAccess, false, work_mem);
2194
rsinfo.setResult = tupstore;
2197
int natts = expectedDesc->natts;
2201
MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
2202
nulldatums = (Datum *) palloc0(natts * sizeof(Datum));
2203
nullflags = (bool *) palloc(natts * sizeof(bool));
2204
memset(nullflags, true, natts * sizeof(bool));
2205
MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
2206
tuplestore_putvalues(tupstore, expectedDesc, nulldatums, nullflags);
2211
* If function provided a tupdesc, cross-check it. We only really need to
2212
* do this for functions returning RECORD, but might as well do it always.
2216
tupledesc_match(expectedDesc, rsinfo.setDesc);
2219
* If it is a dynamically-allocated TupleDesc, free it: it is
2220
* typically allocated in a per-query context, so we must avoid
2221
* leaking it across multiple usages.
2223
if (rsinfo.setDesc->tdrefcount == -1)
2224
FreeTupleDesc(rsinfo.setDesc);
2227
MemoryContextSwitchTo(callerContext);
2229
/* All done, pass back the tuplestore */
2230
return rsinfo.setResult;
2234
/* ----------------------------------------------------------------
2238
* Evaluate the functional result of a list of arguments by calling the
2240
* ----------------------------------------------------------------
2243
/* ----------------------------------------------------------------
2245
* ----------------------------------------------------------------
2248
ExecEvalFunc(FuncExprState *fcache,
2249
ExprContext *econtext,
2251
ExprDoneCond *isDone)
2253
/* This is called only the first time through */
2254
FuncExpr *func = (FuncExpr *) fcache->xprstate.expr;
2256
/* Initialize function lookup info */
2257
init_fcache(func->funcid, func->inputcollid, fcache,
2258
econtext->ecxt_per_query_memory, true);
2260
/* Go directly to ExecMakeFunctionResult on subsequent uses */
2261
fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResult;
2263
return ExecMakeFunctionResult(fcache, econtext, isNull, isDone);
2266
/* ----------------------------------------------------------------
2268
* ----------------------------------------------------------------
2271
ExecEvalOper(FuncExprState *fcache,
2272
ExprContext *econtext,
2274
ExprDoneCond *isDone)
2276
/* This is called only the first time through */
2277
OpExpr *op = (OpExpr *) fcache->xprstate.expr;
2279
/* Initialize function lookup info */
2280
init_fcache(op->opfuncid, op->inputcollid, fcache,
2281
econtext->ecxt_per_query_memory, true);
2283
/* Go directly to ExecMakeFunctionResult on subsequent uses */
2284
fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResult;
2286
return ExecMakeFunctionResult(fcache, econtext, isNull, isDone);
2289
/* ----------------------------------------------------------------
2292
* IS DISTINCT FROM must evaluate arguments to determine whether
2293
* they are NULL; if either is NULL then the result is already
2294
* known. If neither is NULL, then proceed to evaluate the
2295
* function. Note that this is *always* derived from the equals
2296
* operator, but since we need special processing of the arguments
2297
* we can not simply reuse ExecEvalOper() or ExecEvalFunc().
2298
* ----------------------------------------------------------------
2301
ExecEvalDistinct(FuncExprState *fcache,
2302
ExprContext *econtext,
2304
ExprDoneCond *isDone)
2307
FunctionCallInfo fcinfo;
2308
ExprDoneCond argDone;
2310
/* Set default values for result flags: non-null, not a set result */
2313
*isDone = ExprSingleResult;
2316
* Initialize function cache if first time through
2318
if (fcache->func.fn_oid == InvalidOid)
2320
DistinctExpr *op = (DistinctExpr *) fcache->xprstate.expr;
2322
init_fcache(op->opfuncid, op->inputcollid, fcache,
2323
econtext->ecxt_per_query_memory, true);
2324
Assert(!fcache->func.fn_retset);
2328
* Evaluate arguments
2330
fcinfo = &fcache->fcinfo_data;
2331
argDone = ExecEvalFuncArgs(fcinfo, fcache->args, econtext);
2332
if (argDone != ExprSingleResult)
2334
(errcode(ERRCODE_DATATYPE_MISMATCH),
2335
errmsg("IS DISTINCT FROM does not support set arguments")));
2336
Assert(fcinfo->nargs == 2);
2338
if (fcinfo->argnull[0] && fcinfo->argnull[1])
2340
/* Both NULL? Then is not distinct... */
2341
result = BoolGetDatum(FALSE);
2343
else if (fcinfo->argnull[0] || fcinfo->argnull[1])
2345
/* Only one is NULL? Then is distinct... */
2346
result = BoolGetDatum(TRUE);
2350
fcinfo->isnull = false;
2351
result = FunctionCallInvoke(fcinfo);
2352
*isNull = fcinfo->isnull;
2353
/* Must invert result of "=" */
2354
result = BoolGetDatum(!DatumGetBool(result));
2361
* ExecEvalScalarArrayOp
2363
* Evaluate "scalar op ANY/ALL (array)". The operator always yields boolean,
2364
* and we combine the results across all array elements using OR and AND
2365
* (for ANY and ALL respectively). Of course we short-circuit as soon as
2366
* the result is known.
2369
ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate,
2370
ExprContext *econtext,
2371
bool *isNull, ExprDoneCond *isDone)
2373
ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) sstate->fxprstate.xprstate.expr;
2374
bool useOr = opexpr->useOr;
2379
FunctionCallInfo fcinfo;
2380
ExprDoneCond argDone;
2389
/* Set default values for result flags: non-null, not a set result */
2392
*isDone = ExprSingleResult;
2395
* Initialize function cache if first time through
2397
if (sstate->fxprstate.func.fn_oid == InvalidOid)
2399
init_fcache(opexpr->opfuncid, opexpr->inputcollid, &sstate->fxprstate,
2400
econtext->ecxt_per_query_memory, true);
2401
Assert(!sstate->fxprstate.func.fn_retset);
2405
* Evaluate arguments
2407
fcinfo = &sstate->fxprstate.fcinfo_data;
2408
argDone = ExecEvalFuncArgs(fcinfo, sstate->fxprstate.args, econtext);
2409
if (argDone != ExprSingleResult)
2411
(errcode(ERRCODE_DATATYPE_MISMATCH),
2412
errmsg("op ANY/ALL (array) does not support set arguments")));
2413
Assert(fcinfo->nargs == 2);
2416
* If the array is NULL then we return NULL --- it's not very meaningful
2417
* to do anything else, even if the operator isn't strict.
2419
if (fcinfo->argnull[1])
2424
/* Else okay to fetch and detoast the array */
2425
arr = DatumGetArrayTypeP(fcinfo->arg[1]);
2428
* If the array is empty, we return either FALSE or TRUE per the useOr
2429
* flag. This is correct even if the scalar is NULL; since we would
2430
* evaluate the operator zero times, it matters not whether it would want
2433
nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
2435
return BoolGetDatum(!useOr);
2438
* If the scalar is NULL, and the function is strict, return NULL; no
2439
* point in iterating the loop.
2441
if (fcinfo->argnull[0] && sstate->fxprstate.func.fn_strict)
2448
* We arrange to look up info about the element type only once per series
2449
* of calls, assuming the element type doesn't change underneath us.
2451
if (sstate->element_type != ARR_ELEMTYPE(arr))
2453
get_typlenbyvalalign(ARR_ELEMTYPE(arr),
2457
sstate->element_type = ARR_ELEMTYPE(arr);
2459
typlen = sstate->typlen;
2460
typbyval = sstate->typbyval;
2461
typalign = sstate->typalign;
2463
result = BoolGetDatum(!useOr);
2466
/* Loop over the array elements */
2467
s = (char *) ARR_DATA_PTR(arr);
2468
bitmap = ARR_NULLBITMAP(arr);
2471
for (i = 0; i < nitems; i++)
2476
/* Get array element, checking for NULL */
2477
if (bitmap && (*bitmap & bitmask) == 0)
2479
fcinfo->arg[1] = (Datum) 0;
2480
fcinfo->argnull[1] = true;
2484
elt = fetch_att(s, typbyval, typlen);
2485
s = att_addlength_pointer(s, typlen, s);
2486
s = (char *) att_align_nominal(s, typalign);
2487
fcinfo->arg[1] = elt;
2488
fcinfo->argnull[1] = false;
2491
/* Call comparison function */
2492
if (fcinfo->argnull[1] && sstate->fxprstate.func.fn_strict)
2494
fcinfo->isnull = true;
2495
thisresult = (Datum) 0;
2499
fcinfo->isnull = false;
2500
thisresult = FunctionCallInvoke(fcinfo);
2503
/* Combine results per OR or AND semantics */
2508
if (DatumGetBool(thisresult))
2510
result = BoolGetDatum(true);
2512
break; /* needn't look at any more elements */
2517
if (!DatumGetBool(thisresult))
2519
result = BoolGetDatum(false);
2521
break; /* needn't look at any more elements */
2525
/* advance bitmap pointer if any */
2529
if (bitmask == 0x100)
2537
*isNull = resultnull;
2541
/* ----------------------------------------------------------------
2546
* Evaluate boolean expressions, with appropriate short-circuiting.
2548
* The query planner reformulates clause expressions in the
2549
* qualification to conjunctive normal form. If we ever get
2550
* an AND to evaluate, we can be sure that it's not a top-level
2551
* clause in the qualification, but appears lower (as a function
2552
* argument, for example), or in the target list. Not that you
2553
* need to know this, mind you...
2554
* ----------------------------------------------------------------
2557
ExecEvalNot(BoolExprState *notclause, ExprContext *econtext,
2558
bool *isNull, ExprDoneCond *isDone)
2560
ExprState *clause = linitial(notclause->args);
2564
*isDone = ExprSingleResult;
2566
expr_value = ExecEvalExpr(clause, econtext, isNull, NULL);
2569
* if the expression evaluates to null, then we just cascade the null back
2570
* to whoever called us.
2576
* evaluation of 'not' is simple.. expr is false, then return 'true' and
2579
return BoolGetDatum(!DatumGetBool(expr_value));
2582
/* ----------------------------------------------------------------
2584
* ----------------------------------------------------------------
2587
ExecEvalOr(BoolExprState *orExpr, ExprContext *econtext,
2588
bool *isNull, ExprDoneCond *isDone)
2590
List *clauses = orExpr->args;
2595
*isDone = ExprSingleResult;
2600
* If any of the clauses is TRUE, the OR result is TRUE regardless of the
2601
* states of the rest of the clauses, so we can stop evaluating and return
2602
* TRUE immediately. If none are TRUE and one or more is NULL, we return
2603
* NULL; otherwise we return FALSE. This makes sense when you interpret
2604
* NULL as "don't know": if we have a TRUE then the OR is TRUE even if we
2605
* aren't sure about some of the other inputs. If all the known inputs are
2606
* FALSE, but we have one or more "don't knows", then we have to report
2607
* that we "don't know" what the OR's result should be --- perhaps one of
2608
* the "don't knows" would have been TRUE if we'd known its value. Only
2609
* when all the inputs are known to be FALSE can we state confidently that
2610
* the OR's result is FALSE.
2612
foreach(clause, clauses)
2614
ExprState *clausestate = (ExprState *) lfirst(clause);
2617
clause_value = ExecEvalExpr(clausestate, econtext, isNull, NULL);
2620
* if we have a non-null true result, then return it.
2623
AnyNull = true; /* remember we got a null */
2624
else if (DatumGetBool(clause_value))
2625
return clause_value;
2628
/* AnyNull is true if at least one clause evaluated to NULL */
2630
return BoolGetDatum(false);
2633
/* ----------------------------------------------------------------
2635
* ----------------------------------------------------------------
2638
ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
2639
bool *isNull, ExprDoneCond *isDone)
2641
List *clauses = andExpr->args;
2646
*isDone = ExprSingleResult;
2651
* If any of the clauses is FALSE, the AND result is FALSE regardless of
2652
* the states of the rest of the clauses, so we can stop evaluating and
2653
* return FALSE immediately. If none are FALSE and one or more is NULL,
2654
* we return NULL; otherwise we return TRUE. This makes sense when you
2655
* interpret NULL as "don't know", using the same sort of reasoning as for
2659
foreach(clause, clauses)
2661
ExprState *clausestate = (ExprState *) lfirst(clause);
2664
clause_value = ExecEvalExpr(clausestate, econtext, isNull, NULL);
2667
* if we have a non-null false result, then return it.
2670
AnyNull = true; /* remember we got a null */
2671
else if (!DatumGetBool(clause_value))
2672
return clause_value;
2675
/* AnyNull is true if at least one clause evaluated to NULL */
2677
return BoolGetDatum(!AnyNull);
2680
/* ----------------------------------------------------------------
2681
* ExecEvalConvertRowtype
2683
* Evaluate a rowtype coercion operation. This may require
2684
* rearranging field positions.
2685
* ----------------------------------------------------------------
2688
ExecEvalConvertRowtype(ConvertRowtypeExprState *cstate,
2689
ExprContext *econtext,
2690
bool *isNull, ExprDoneCond *isDone)
2692
ConvertRowtypeExpr *convert = (ConvertRowtypeExpr *) cstate->xprstate.expr;
2695
HeapTupleHeader tuple;
2696
HeapTupleData tmptup;
2698
tupDatum = ExecEvalExpr(cstate->arg, econtext, isNull, isDone);
2700
/* this test covers the isDone exception too: */
2704
tuple = DatumGetHeapTupleHeader(tupDatum);
2706
/* Lookup tupdescs if first time through or after rescan */
2707
if (cstate->indesc == NULL)
2709
get_cached_rowtype(exprType((Node *) convert->arg), -1,
2710
&cstate->indesc, econtext);
2711
cstate->initialized = false;
2713
if (cstate->outdesc == NULL)
2715
get_cached_rowtype(convert->resulttype, -1,
2716
&cstate->outdesc, econtext);
2717
cstate->initialized = false;
2720
Assert(HeapTupleHeaderGetTypeId(tuple) == cstate->indesc->tdtypeid);
2721
Assert(HeapTupleHeaderGetTypMod(tuple) == cstate->indesc->tdtypmod);
2723
/* if first time through, initialize conversion map */
2724
if (!cstate->initialized)
2726
MemoryContext old_cxt;
2728
/* allocate map in long-lived memory context */
2729
old_cxt = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
2731
/* prepare map from old to new attribute numbers */
2732
cstate->map = convert_tuples_by_name(cstate->indesc,
2734
gettext_noop("could not convert row type"));
2735
cstate->initialized = true;
2737
MemoryContextSwitchTo(old_cxt);
2741
* No-op if no conversion needed (not clear this can happen here).
2743
if (cstate->map == NULL)
2747
* do_convert_tuple needs a HeapTuple not a bare HeapTupleHeader.
2749
tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
2750
tmptup.t_data = tuple;
2752
result = do_convert_tuple(&tmptup, cstate->map);
2754
return HeapTupleGetDatum(result);
2757
/* ----------------------------------------------------------------
2760
* Evaluate a CASE clause. Will have boolean expressions
2761
* inside the WHEN clauses, and will have expressions
2763
* - thomas 1998-11-09
2764
* ----------------------------------------------------------------
2767
ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
2768
bool *isNull, ExprDoneCond *isDone)
2770
List *clauses = caseExpr->args;
2776
*isDone = ExprSingleResult;
2779
* If there's a test expression, we have to evaluate it and save the value
2780
* where the CaseTestExpr placeholders can find it. We must save and
2781
* restore prior setting of econtext's caseValue fields, in case this node
2782
* is itself within a larger CASE.
2784
save_datum = econtext->caseValue_datum;
2785
save_isNull = econtext->caseValue_isNull;
2789
econtext->caseValue_datum = ExecEvalExpr(caseExpr->arg,
2791
&econtext->caseValue_isNull,
2796
* we evaluate each of the WHEN clauses in turn, as soon as one is true we
2797
* return the corresponding result. If none are true then we return the
2798
* value of the default clause, or NULL if there is none.
2800
foreach(clause, clauses)
2802
CaseWhenState *wclause = lfirst(clause);
2805
clause_value = ExecEvalExpr(wclause->expr,
2811
* if we have a true test, then we return the result, since the case
2812
* statement is satisfied. A NULL result from the test is not
2815
if (DatumGetBool(clause_value) && !*isNull)
2817
econtext->caseValue_datum = save_datum;
2818
econtext->caseValue_isNull = save_isNull;
2819
return ExecEvalExpr(wclause->result,
2826
econtext->caseValue_datum = save_datum;
2827
econtext->caseValue_isNull = save_isNull;
2829
if (caseExpr->defresult)
2831
return ExecEvalExpr(caseExpr->defresult,
2842
* ExecEvalCaseTestExpr
2844
* Return the value stored by CASE.
2847
ExecEvalCaseTestExpr(ExprState *exprstate,
2848
ExprContext *econtext,
2849
bool *isNull, ExprDoneCond *isDone)
2852
*isDone = ExprSingleResult;
2853
*isNull = econtext->caseValue_isNull;
2854
return econtext->caseValue_datum;
2857
/* ----------------------------------------------------------------
2858
* ExecEvalArray - ARRAY[] expressions
2859
* ----------------------------------------------------------------
2862
ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
2863
bool *isNull, ExprDoneCond *isDone)
2865
ArrayExpr *arrayExpr = (ArrayExpr *) astate->xprstate.expr;
2868
Oid element_type = arrayExpr->element_typeid;
2873
/* Set default values for result flags: non-null, not a set result */
2876
*isDone = ExprSingleResult;
2878
if (!arrayExpr->multidims)
2880
/* Elements are presumably of scalar type */
2887
nelems = list_length(astate->elements);
2889
/* Shouldn't happen here, but if length is 0, return empty array */
2891
return PointerGetDatum(construct_empty_array(element_type));
2893
dvalues = (Datum *) palloc(nelems * sizeof(Datum));
2894
dnulls = (bool *) palloc(nelems * sizeof(bool));
2896
/* loop through and build array of datums */
2897
foreach(element, astate->elements)
2899
ExprState *e = (ExprState *) lfirst(element);
2901
dvalues[i] = ExecEvalExpr(e, econtext, &dnulls[i], NULL);
2905
/* setup for 1-D array of the given length */
2909
result = construct_md_array(dvalues, dnulls, ndims, dims, lbs,
2917
/* Must be nested array expressions */
2920
int outer_nelems = 0;
2922
int *elem_dims = NULL;
2923
int *elem_lbs = NULL;
2924
bool firstone = true;
2925
bool havenulls = false;
2926
bool haveempty = false;
2936
i = list_length(astate->elements);
2937
subdata = (char **) palloc(i * sizeof(char *));
2938
subbitmaps = (bits8 **) palloc(i * sizeof(bits8 *));
2939
subbytes = (int *) palloc(i * sizeof(int));
2940
subnitems = (int *) palloc(i * sizeof(int));
2942
/* loop through and get data area from each element */
2943
foreach(element, astate->elements)
2945
ExprState *e = (ExprState *) lfirst(element);
2951
arraydatum = ExecEvalExpr(e, econtext, &eisnull, NULL);
2952
/* temporarily ignore null subarrays */
2959
array = DatumGetArrayTypeP(arraydatum);
2961
/* run-time double-check on element type */
2962
if (element_type != ARR_ELEMTYPE(array))
2964
(errcode(ERRCODE_DATATYPE_MISMATCH),
2965
errmsg("cannot merge incompatible arrays"),
2966
errdetail("Array with element type %s cannot be "
2967
"included in ARRAY construct with element type %s.",
2968
format_type_be(ARR_ELEMTYPE(array)),
2969
format_type_be(element_type))));
2971
this_ndims = ARR_NDIM(array);
2972
/* temporarily ignore zero-dimensional subarrays */
2973
if (this_ndims <= 0)
2981
/* Get sub-array details from first member */
2982
elem_ndims = this_ndims;
2983
ndims = elem_ndims + 1;
2984
if (ndims <= 0 || ndims > MAXDIM)
2986
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2987
errmsg("number of array dimensions (%d) exceeds " \
2988
"the maximum allowed (%d)", ndims, MAXDIM)));
2990
elem_dims = (int *) palloc(elem_ndims * sizeof(int));
2991
memcpy(elem_dims, ARR_DIMS(array), elem_ndims * sizeof(int));
2992
elem_lbs = (int *) palloc(elem_ndims * sizeof(int));
2993
memcpy(elem_lbs, ARR_LBOUND(array), elem_ndims * sizeof(int));
2999
/* Check other sub-arrays are compatible */
3000
if (elem_ndims != this_ndims ||
3001
memcmp(elem_dims, ARR_DIMS(array),
3002
elem_ndims * sizeof(int)) != 0 ||
3003
memcmp(elem_lbs, ARR_LBOUND(array),
3004
elem_ndims * sizeof(int)) != 0)
3006
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3007
errmsg("multidimensional arrays must have array "
3008
"expressions with matching dimensions")));
3011
subdata[outer_nelems] = ARR_DATA_PTR(array);
3012
subbitmaps[outer_nelems] = ARR_NULLBITMAP(array);
3013
subbytes[outer_nelems] = ARR_SIZE(array) - ARR_DATA_OFFSET(array);
3014
nbytes += subbytes[outer_nelems];
3015
subnitems[outer_nelems] = ArrayGetNItems(this_ndims,
3017
nitems += subnitems[outer_nelems];
3018
havenulls |= ARR_HASNULL(array);
3023
* If all items were null or empty arrays, return an empty array;
3024
* otherwise, if some were and some weren't, raise error. (Note: we
3025
* must special-case this somehow to avoid trying to generate a 1-D
3026
* array formed from empty arrays. It's not ideal...)
3030
if (ndims == 0) /* didn't find any nonempty array */
3031
return PointerGetDatum(construct_empty_array(element_type));
3033
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3034
errmsg("multidimensional arrays must have array "
3035
"expressions with matching dimensions")));
3038
/* setup for multi-D array */
3039
dims[0] = outer_nelems;
3041
for (i = 1; i < ndims; i++)
3043
dims[i] = elem_dims[i - 1];
3044
lbs[i] = elem_lbs[i - 1];
3049
dataoffset = ARR_OVERHEAD_WITHNULLS(ndims, nitems);
3050
nbytes += dataoffset;
3054
dataoffset = 0; /* marker for no null bitmap */
3055
nbytes += ARR_OVERHEAD_NONULLS(ndims);
3058
result = (ArrayType *) palloc(nbytes);
3059
SET_VARSIZE(result, nbytes);
3060
result->ndim = ndims;
3061
result->dataoffset = dataoffset;
3062
result->elemtype = element_type;
3063
memcpy(ARR_DIMS(result), dims, ndims * sizeof(int));
3064
memcpy(ARR_LBOUND(result), lbs, ndims * sizeof(int));
3066
dat = ARR_DATA_PTR(result);
3068
for (i = 0; i < outer_nelems; i++)
3070
memcpy(dat, subdata[i], subbytes[i]);
3073
array_bitmap_copy(ARR_NULLBITMAP(result), iitem,
3076
iitem += subnitems[i];
3080
return PointerGetDatum(result);
3083
/* ----------------------------------------------------------------
3084
* ExecEvalRow - ROW() expressions
3085
* ----------------------------------------------------------------
3088
ExecEvalRow(RowExprState *rstate,
3089
ExprContext *econtext,
3090
bool *isNull, ExprDoneCond *isDone)
3099
/* Set default values for result flags: non-null, not a set result */
3102
*isDone = ExprSingleResult;
3104
/* Allocate workspace */
3105
natts = rstate->tupdesc->natts;
3106
values = (Datum *) palloc0(natts * sizeof(Datum));
3107
isnull = (bool *) palloc(natts * sizeof(bool));
3109
/* preset to nulls in case rowtype has some later-added columns */
3110
memset(isnull, true, natts * sizeof(bool));
3112
/* Evaluate field values */
3114
foreach(arg, rstate->args)
3116
ExprState *e = (ExprState *) lfirst(arg);
3118
values[i] = ExecEvalExpr(e, econtext, &isnull[i], NULL);
3122
tuple = heap_form_tuple(rstate->tupdesc, values, isnull);
3127
return HeapTupleGetDatum(tuple);
3130
/* ----------------------------------------------------------------
3131
* ExecEvalRowCompare - ROW() comparison-op ROW()
3132
* ----------------------------------------------------------------
3135
ExecEvalRowCompare(RowCompareExprState *rstate,
3136
ExprContext *econtext,
3137
bool *isNull, ExprDoneCond *isDone)
3140
RowCompareType rctype = ((RowCompareExpr *) rstate->xprstate.expr)->rctype;
3141
int32 cmpresult = 0;
3147
*isDone = ExprSingleResult;
3148
*isNull = true; /* until we get a result */
3151
forboth(l, rstate->largs, r, rstate->rargs)
3153
ExprState *le = (ExprState *) lfirst(l);
3154
ExprState *re = (ExprState *) lfirst(r);
3155
FunctionCallInfoData locfcinfo;
3157
InitFunctionCallInfoData(locfcinfo, &(rstate->funcs[i]), 2,
3158
rstate->collations[i],
3160
locfcinfo.arg[0] = ExecEvalExpr(le, econtext,
3161
&locfcinfo.argnull[0], NULL);
3162
locfcinfo.arg[1] = ExecEvalExpr(re, econtext,
3163
&locfcinfo.argnull[1], NULL);
3164
if (rstate->funcs[i].fn_strict &&
3165
(locfcinfo.argnull[0] || locfcinfo.argnull[1]))
3166
return (Datum) 0; /* force NULL result */
3167
locfcinfo.isnull = false;
3168
cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo));
3169
if (locfcinfo.isnull)
3170
return (Datum) 0; /* force NULL result */
3172
break; /* no need to compare remaining columns */
3178
/* EQ and NE cases aren't allowed here */
3180
result = (cmpresult < 0);
3183
result = (cmpresult <= 0);
3186
result = (cmpresult >= 0);
3189
result = (cmpresult > 0);
3192
elog(ERROR, "unrecognized RowCompareType: %d", (int) rctype);
3193
result = 0; /* keep compiler quiet */
3198
return BoolGetDatum(result);
3201
/* ----------------------------------------------------------------
3203
* ----------------------------------------------------------------
3206
ExecEvalCoalesce(CoalesceExprState *coalesceExpr, ExprContext *econtext,
3207
bool *isNull, ExprDoneCond *isDone)
3212
*isDone = ExprSingleResult;
3214
/* Simply loop through until something NOT NULL is found */
3215
foreach(arg, coalesceExpr->args)
3217
ExprState *e = (ExprState *) lfirst(arg);
3220
value = ExecEvalExpr(e, econtext, isNull, NULL);
3225
/* Else return NULL */
3230
/* ----------------------------------------------------------------
3232
* ----------------------------------------------------------------
3235
ExecEvalMinMax(MinMaxExprState *minmaxExpr, ExprContext *econtext,
3236
bool *isNull, ExprDoneCond *isDone)
3238
Datum result = (Datum) 0;
3239
MinMaxExpr *minmax = (MinMaxExpr *) minmaxExpr->xprstate.expr;
3240
Oid collation = minmax->inputcollid;
3241
MinMaxOp op = minmax->op;
3242
FunctionCallInfoData locfcinfo;
3246
*isDone = ExprSingleResult;
3247
*isNull = true; /* until we get a result */
3249
InitFunctionCallInfoData(locfcinfo, &minmaxExpr->cfunc, 2,
3250
collation, NULL, NULL);
3251
locfcinfo.argnull[0] = false;
3252
locfcinfo.argnull[1] = false;
3254
foreach(arg, minmaxExpr->args)
3256
ExprState *e = (ExprState *) lfirst(arg);
3261
value = ExecEvalExpr(e, econtext, &valueIsNull, NULL);
3263
continue; /* ignore NULL inputs */
3267
/* first nonnull input, adopt value */
3273
/* apply comparison function */
3274
locfcinfo.arg[0] = result;
3275
locfcinfo.arg[1] = value;
3276
locfcinfo.isnull = false;
3277
cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo));
3278
if (locfcinfo.isnull) /* probably should not happen */
3280
if (cmpresult > 0 && op == IS_LEAST)
3282
else if (cmpresult < 0 && op == IS_GREATEST)
3290
/* ----------------------------------------------------------------
3292
* ----------------------------------------------------------------
3295
ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
3296
bool *isNull, ExprDoneCond *isDone)
3298
XmlExpr *xexpr = (XmlExpr *) xmlExpr->xprstate.expr;
3305
*isDone = ExprSingleResult;
3306
*isNull = true; /* until we get a result */
3314
foreach(arg, xmlExpr->args)
3316
ExprState *e = (ExprState *) lfirst(arg);
3318
value = ExecEvalExpr(e, econtext, &isnull, NULL);
3320
values = lappend(values, DatumGetPointer(value));
3323
if (list_length(values) > 0)
3326
return PointerGetDatum(xmlconcat(values));
3337
initStringInfo(&buf);
3338
forboth(arg, xmlExpr->named_args, narg, xexpr->arg_names)
3340
ExprState *e = (ExprState *) lfirst(arg);
3341
char *argname = strVal(lfirst(narg));
3343
value = ExecEvalExpr(e, econtext, &isnull, NULL);
3346
appendStringInfo(&buf, "<%s>%s</%s>",
3348
map_sql_value_to_xml_value(value, exprType((Node *) e->expr), true),
3363
result = cstring_to_text_with_len(buf.data, buf.len);
3366
return PointerGetDatum(result);
3373
return PointerGetDatum(xmlelement(xmlExpr, econtext));
3380
bool preserve_whitespace;
3382
/* arguments are known to be text, bool */
3383
Assert(list_length(xmlExpr->args) == 2);
3385
e = (ExprState *) linitial(xmlExpr->args);
3386
value = ExecEvalExpr(e, econtext, &isnull, NULL);
3389
data = DatumGetTextP(value);
3391
e = (ExprState *) lsecond(xmlExpr->args);
3392
value = ExecEvalExpr(e, econtext, &isnull, NULL);
3393
if (isnull) /* probably can't happen */
3395
preserve_whitespace = DatumGetBool(value);
3399
return PointerGetDatum(xmlparse(data,
3401
preserve_whitespace));
3410
/* optional argument is known to be text */
3411
Assert(list_length(xmlExpr->args) <= 1);
3415
e = (ExprState *) linitial(xmlExpr->args);
3416
value = ExecEvalExpr(e, econtext, &isnull, NULL);
3420
arg = DatumGetTextP(value);
3428
return PointerGetDatum(xmlpi(xexpr->name, arg, isnull, isNull));
3439
/* arguments are known to be xml, text, int */
3440
Assert(list_length(xmlExpr->args) == 3);
3442
e = (ExprState *) linitial(xmlExpr->args);
3443
value = ExecEvalExpr(e, econtext, &isnull, NULL);
3446
data = DatumGetXmlP(value);
3448
e = (ExprState *) lsecond(xmlExpr->args);
3449
value = ExecEvalExpr(e, econtext, &isnull, NULL);
3453
version = DatumGetTextP(value);
3455
e = (ExprState *) lthird(xmlExpr->args);
3456
value = ExecEvalExpr(e, econtext, &isnull, NULL);
3457
standalone = DatumGetInt32(value);
3461
return PointerGetDatum(xmlroot(data,
3467
case IS_XMLSERIALIZE:
3471
/* argument type is known to be xml */
3472
Assert(list_length(xmlExpr->args) == 1);
3474
e = (ExprState *) linitial(xmlExpr->args);
3475
value = ExecEvalExpr(e, econtext, &isnull, NULL);
3481
return PointerGetDatum(xmltotext_with_xmloption(DatumGetXmlP(value), xexpr->xmloption));
3489
/* optional argument is known to be xml */
3490
Assert(list_length(xmlExpr->args) == 1);
3492
e = (ExprState *) linitial(xmlExpr->args);
3493
value = ExecEvalExpr(e, econtext, &isnull, NULL);
3499
return BoolGetDatum(xml_is_document(DatumGetXmlP(value)));
3505
elog(ERROR, "unrecognized XML operation");
3509
/* ----------------------------------------------------------------
3512
* Note that this is *always* derived from the equals operator,
3513
* but since we need special processing of the arguments
3514
* we can not simply reuse ExecEvalOper() or ExecEvalFunc().
3515
* ----------------------------------------------------------------
3518
ExecEvalNullIf(FuncExprState *nullIfExpr,
3519
ExprContext *econtext,
3520
bool *isNull, ExprDoneCond *isDone)
3523
FunctionCallInfo fcinfo;
3524
ExprDoneCond argDone;
3527
*isDone = ExprSingleResult;
3530
* Initialize function cache if first time through
3532
if (nullIfExpr->func.fn_oid == InvalidOid)
3534
NullIfExpr *op = (NullIfExpr *) nullIfExpr->xprstate.expr;
3536
init_fcache(op->opfuncid, op->inputcollid, nullIfExpr,
3537
econtext->ecxt_per_query_memory, true);
3538
Assert(!nullIfExpr->func.fn_retset);
3542
* Evaluate arguments
3544
fcinfo = &nullIfExpr->fcinfo_data;
3545
argDone = ExecEvalFuncArgs(fcinfo, nullIfExpr->args, econtext);
3546
if (argDone != ExprSingleResult)
3548
(errcode(ERRCODE_DATATYPE_MISMATCH),
3549
errmsg("NULLIF does not support set arguments")));
3550
Assert(fcinfo->nargs == 2);
3552
/* if either argument is NULL they can't be equal */
3553
if (!fcinfo->argnull[0] && !fcinfo->argnull[1])
3555
fcinfo->isnull = false;
3556
result = FunctionCallInvoke(fcinfo);
3557
/* if the arguments are equal return null */
3558
if (!fcinfo->isnull && DatumGetBool(result))
3565
/* else return first argument */
3566
*isNull = fcinfo->argnull[0];
3567
return fcinfo->arg[0];
3570
/* ----------------------------------------------------------------
3573
* Evaluate a NullTest node.
3574
* ----------------------------------------------------------------
3577
ExecEvalNullTest(NullTestState *nstate,
3578
ExprContext *econtext,
3580
ExprDoneCond *isDone)
3582
NullTest *ntest = (NullTest *) nstate->xprstate.expr;
3585
result = ExecEvalExpr(nstate->arg, econtext, isNull, isDone);
3587
if (isDone && *isDone == ExprEndResult)
3588
return result; /* nothing to check */
3590
if (ntest->argisrow && !(*isNull))
3592
HeapTupleHeader tuple;
3596
HeapTupleData tmptup;
3599
tuple = DatumGetHeapTupleHeader(result);
3601
tupType = HeapTupleHeaderGetTypeId(tuple);
3602
tupTypmod = HeapTupleHeaderGetTypMod(tuple);
3604
/* Lookup tupdesc if first time through or if type changes */
3605
tupDesc = get_cached_rowtype(tupType, tupTypmod,
3606
&nstate->argdesc, econtext);
3609
* heap_attisnull needs a HeapTuple not a bare HeapTupleHeader.
3611
tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
3612
tmptup.t_data = tuple;
3614
for (att = 1; att <= tupDesc->natts; att++)
3616
/* ignore dropped columns */
3617
if (tupDesc->attrs[att - 1]->attisdropped)
3619
if (heap_attisnull(&tmptup, att))
3621
/* null field disproves IS NOT NULL */
3622
if (ntest->nulltesttype == IS_NOT_NULL)
3623
return BoolGetDatum(false);
3627
/* non-null field disproves IS NULL */
3628
if (ntest->nulltesttype == IS_NULL)
3629
return BoolGetDatum(false);
3633
return BoolGetDatum(true);
3637
/* Simple scalar-argument case, or a null rowtype datum */
3638
switch (ntest->nulltesttype)
3644
return BoolGetDatum(true);
3647
return BoolGetDatum(false);
3652
return BoolGetDatum(false);
3655
return BoolGetDatum(true);
3657
elog(ERROR, "unrecognized nulltesttype: %d",
3658
(int) ntest->nulltesttype);
3659
return (Datum) 0; /* keep compiler quiet */
3664
/* ----------------------------------------------------------------
3665
* ExecEvalBooleanTest
3667
* Evaluate a BooleanTest node.
3668
* ----------------------------------------------------------------
3671
ExecEvalBooleanTest(GenericExprState *bstate,
3672
ExprContext *econtext,
3674
ExprDoneCond *isDone)
3676
BooleanTest *btest = (BooleanTest *) bstate->xprstate.expr;
3679
result = ExecEvalExpr(bstate->arg, econtext, isNull, isDone);
3681
if (isDone && *isDone == ExprEndResult)
3682
return result; /* nothing to check */
3684
switch (btest->booltesttype)
3690
return BoolGetDatum(false);
3692
else if (DatumGetBool(result))
3693
return BoolGetDatum(true);
3695
return BoolGetDatum(false);
3700
return BoolGetDatum(true);
3702
else if (DatumGetBool(result))
3703
return BoolGetDatum(false);
3705
return BoolGetDatum(true);
3710
return BoolGetDatum(false);
3712
else if (DatumGetBool(result))
3713
return BoolGetDatum(false);
3715
return BoolGetDatum(true);
3720
return BoolGetDatum(true);
3722
else if (DatumGetBool(result))
3723
return BoolGetDatum(true);
3725
return BoolGetDatum(false);
3730
return BoolGetDatum(true);
3733
return BoolGetDatum(false);
3734
case IS_NOT_UNKNOWN:
3738
return BoolGetDatum(false);
3741
return BoolGetDatum(true);
3743
elog(ERROR, "unrecognized booltesttype: %d",
3744
(int) btest->booltesttype);
3745
return (Datum) 0; /* keep compiler quiet */
3750
* ExecEvalCoerceToDomain
3752
* Test the provided data against the domain constraint(s). If the data
3753
* passes the constraint specifications, pass it through (return the
3754
* datum) otherwise throw an error.
3757
ExecEvalCoerceToDomain(CoerceToDomainState *cstate, ExprContext *econtext,
3758
bool *isNull, ExprDoneCond *isDone)
3760
CoerceToDomain *ctest = (CoerceToDomain *) cstate->xprstate.expr;
3764
result = ExecEvalExpr(cstate->arg, econtext, isNull, isDone);
3766
if (isDone && *isDone == ExprEndResult)
3767
return result; /* nothing to check */
3769
foreach(l, cstate->constraints)
3771
DomainConstraintState *con = (DomainConstraintState *) lfirst(l);
3773
switch (con->constrainttype)
3775
case DOM_CONSTRAINT_NOTNULL:
3778
(errcode(ERRCODE_NOT_NULL_VIOLATION),
3779
errmsg("domain %s does not allow null values",
3780
format_type_be(ctest->resulttype))));
3782
case DOM_CONSTRAINT_CHECK:
3790
* Set up value to be returned by CoerceToDomainValue
3791
* nodes. We must save and restore prior setting of
3792
* econtext's domainValue fields, in case this node is
3793
* itself within a check expression for another domain.
3795
save_datum = econtext->domainValue_datum;
3796
save_isNull = econtext->domainValue_isNull;
3798
econtext->domainValue_datum = result;
3799
econtext->domainValue_isNull = *isNull;
3801
conResult = ExecEvalExpr(con->check_expr,
3802
econtext, &conIsNull, NULL);
3805
!DatumGetBool(conResult))
3807
(errcode(ERRCODE_CHECK_VIOLATION),
3808
errmsg("value for domain %s violates check constraint \"%s\"",
3809
format_type_be(ctest->resulttype),
3811
econtext->domainValue_datum = save_datum;
3812
econtext->domainValue_isNull = save_isNull;
3817
elog(ERROR, "unrecognized constraint type: %d",
3818
(int) con->constrainttype);
3823
/* If all has gone well (constraints did not fail) return the datum */
3828
* ExecEvalCoerceToDomainValue
3830
* Return the value stored by CoerceToDomain.
3833
ExecEvalCoerceToDomainValue(ExprState *exprstate,
3834
ExprContext *econtext,
3835
bool *isNull, ExprDoneCond *isDone)
3838
*isDone = ExprSingleResult;
3839
*isNull = econtext->domainValue_isNull;
3840
return econtext->domainValue_datum;
3843
/* ----------------------------------------------------------------
3844
* ExecEvalFieldSelect
3846
* Evaluate a FieldSelect node.
3847
* ----------------------------------------------------------------
3850
ExecEvalFieldSelect(FieldSelectState *fstate,
3851
ExprContext *econtext,
3853
ExprDoneCond *isDone)
3855
FieldSelect *fselect = (FieldSelect *) fstate->xprstate.expr;
3856
AttrNumber fieldnum = fselect->fieldnum;
3859
HeapTupleHeader tuple;
3863
Form_pg_attribute attr;
3864
HeapTupleData tmptup;
3866
tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull, isDone);
3868
/* this test covers the isDone exception too: */
3872
tuple = DatumGetHeapTupleHeader(tupDatum);
3874
tupType = HeapTupleHeaderGetTypeId(tuple);
3875
tupTypmod = HeapTupleHeaderGetTypMod(tuple);
3877
/* Lookup tupdesc if first time through or if type changes */
3878
tupDesc = get_cached_rowtype(tupType, tupTypmod,
3879
&fstate->argdesc, econtext);
3882
* Find field's attr record. Note we don't support system columns here: a
3883
* datum tuple doesn't have valid values for most of the interesting
3884
* system columns anyway.
3886
if (fieldnum <= 0) /* should never happen */
3887
elog(ERROR, "unsupported reference to system column %d in FieldSelect",
3889
if (fieldnum > tupDesc->natts) /* should never happen */
3890
elog(ERROR, "attribute number %d exceeds number of columns %d",
3891
fieldnum, tupDesc->natts);
3892
attr = tupDesc->attrs[fieldnum - 1];
3894
/* Check for dropped column, and force a NULL result if so */
3895
if (attr->attisdropped)
3901
/* Check for type mismatch --- possible after ALTER COLUMN TYPE? */
3902
/* As in ExecEvalVar, we should but can't check typmod */
3903
if (fselect->resulttype != attr->atttypid)
3905
(errmsg("attribute %d has wrong type", fieldnum),
3906
errdetail("Table has type %s, but query expects %s.",
3907
format_type_be(attr->atttypid),
3908
format_type_be(fselect->resulttype))));
3910
/* heap_getattr needs a HeapTuple not a bare HeapTupleHeader */
3911
tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
3912
tmptup.t_data = tuple;
3914
result = heap_getattr(&tmptup,
3921
/* ----------------------------------------------------------------
3922
* ExecEvalFieldStore
3924
* Evaluate a FieldStore node.
3925
* ----------------------------------------------------------------
3928
ExecEvalFieldStore(FieldStoreState *fstate,
3929
ExprContext *econtext,
3931
ExprDoneCond *isDone)
3933
FieldStore *fstore = (FieldStore *) fstate->xprstate.expr;
3944
tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull, isDone);
3946
if (isDone && *isDone == ExprEndResult)
3949
/* Lookup tupdesc if first time through or after rescan */
3950
tupDesc = get_cached_rowtype(fstore->resulttype, -1,
3951
&fstate->argdesc, econtext);
3953
/* Allocate workspace */
3954
values = (Datum *) palloc(tupDesc->natts * sizeof(Datum));
3955
isnull = (bool *) palloc(tupDesc->natts * sizeof(bool));
3960
* heap_deform_tuple needs a HeapTuple not a bare HeapTupleHeader. We
3961
* set all the fields in the struct just in case.
3963
HeapTupleHeader tuphdr;
3964
HeapTupleData tmptup;
3966
tuphdr = DatumGetHeapTupleHeader(tupDatum);
3967
tmptup.t_len = HeapTupleHeaderGetDatumLength(tuphdr);
3968
ItemPointerSetInvalid(&(tmptup.t_self));
3969
tmptup.t_tableOid = InvalidOid;
3970
tmptup.t_data = tuphdr;
3972
heap_deform_tuple(&tmptup, tupDesc, values, isnull);
3976
/* Convert null input tuple into an all-nulls row */
3977
memset(isnull, true, tupDesc->natts * sizeof(bool));
3980
/* Result is never null */
3983
save_datum = econtext->caseValue_datum;
3984
save_isNull = econtext->caseValue_isNull;
3986
forboth(l1, fstate->newvals, l2, fstore->fieldnums)
3988
ExprState *newval = (ExprState *) lfirst(l1);
3989
AttrNumber fieldnum = lfirst_int(l2);
3991
Assert(fieldnum > 0 && fieldnum <= tupDesc->natts);
3994
* Use the CaseTestExpr mechanism to pass down the old value of the
3995
* field being replaced; this is needed in case the newval is itself a
3996
* FieldStore or ArrayRef that has to obtain and modify the old value.
3997
* It's safe to reuse the CASE mechanism because there cannot be a
3998
* CASE between here and where the value would be needed, and a field
3999
* assignment can't be within a CASE either. (So saving and restoring
4000
* the caseValue is just paranoia, but let's do it anyway.)
4002
econtext->caseValue_datum = values[fieldnum - 1];
4003
econtext->caseValue_isNull = isnull[fieldnum - 1];
4005
values[fieldnum - 1] = ExecEvalExpr(newval,
4007
&isnull[fieldnum - 1],
4011
econtext->caseValue_datum = save_datum;
4012
econtext->caseValue_isNull = save_isNull;
4014
tuple = heap_form_tuple(tupDesc, values, isnull);
4019
return HeapTupleGetDatum(tuple);
4022
/* ----------------------------------------------------------------
4023
* ExecEvalRelabelType
4025
* Evaluate a RelabelType node.
4026
* ----------------------------------------------------------------
4029
ExecEvalRelabelType(GenericExprState *exprstate,
4030
ExprContext *econtext,
4031
bool *isNull, ExprDoneCond *isDone)
4033
return ExecEvalExpr(exprstate->arg, econtext, isNull, isDone);
4036
/* ----------------------------------------------------------------
4037
* ExecEvalCoerceViaIO
4039
* Evaluate a CoerceViaIO node.
4040
* ----------------------------------------------------------------
4043
ExecEvalCoerceViaIO(CoerceViaIOState *iostate,
4044
ExprContext *econtext,
4045
bool *isNull, ExprDoneCond *isDone)
4051
inputval = ExecEvalExpr(iostate->arg, econtext, isNull, isDone);
4053
if (isDone && *isDone == ExprEndResult)
4054
return inputval; /* nothing to do */
4057
string = NULL; /* output functions are not called on nulls */
4059
string = OutputFunctionCall(&iostate->outfunc, inputval);
4061
result = InputFunctionCall(&iostate->infunc,
4063
iostate->intypioparam,
4066
/* The input function cannot change the null/not-null status */
4070
/* ----------------------------------------------------------------
4071
* ExecEvalArrayCoerceExpr
4073
* Evaluate an ArrayCoerceExpr node.
4074
* ----------------------------------------------------------------
4077
ExecEvalArrayCoerceExpr(ArrayCoerceExprState *astate,
4078
ExprContext *econtext,
4079
bool *isNull, ExprDoneCond *isDone)
4081
ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) astate->xprstate.expr;
4084
FunctionCallInfoData locfcinfo;
4086
result = ExecEvalExpr(astate->arg, econtext, isNull, isDone);
4088
if (isDone && *isDone == ExprEndResult)
4089
return result; /* nothing to do */
4091
return result; /* nothing to do */
4094
* If it's binary-compatible, modify the element type in the array header,
4095
* but otherwise leave the array as we received it.
4097
if (!OidIsValid(acoerce->elemfuncid))
4099
/* Detoast input array if necessary, and copy in any case */
4100
array = DatumGetArrayTypePCopy(result);
4101
ARR_ELEMTYPE(array) = astate->resultelemtype;
4102
PG_RETURN_ARRAYTYPE_P(array);
4105
/* Detoast input array if necessary, but don't make a useless copy */
4106
array = DatumGetArrayTypeP(result);
4108
/* Initialize function cache if first time through */
4109
if (astate->elemfunc.fn_oid == InvalidOid)
4111
AclResult aclresult;
4113
/* Check permission to call function */
4114
aclresult = pg_proc_aclcheck(acoerce->elemfuncid, GetUserId(),
4116
if (aclresult != ACLCHECK_OK)
4117
aclcheck_error(aclresult, ACL_KIND_PROC,
4118
get_func_name(acoerce->elemfuncid));
4120
/* Set up the primary fmgr lookup information */
4121
fmgr_info_cxt(acoerce->elemfuncid, &(astate->elemfunc),
4122
econtext->ecxt_per_query_memory);
4123
fmgr_info_set_expr((Node *) acoerce, &(astate->elemfunc));
4127
* Use array_map to apply the function to each array element.
4129
* We pass on the desttypmod and isExplicit flags whether or not the
4130
* function wants them.
4132
* Note: coercion functions are assumed to not use collation.
4134
InitFunctionCallInfoData(locfcinfo, &(astate->elemfunc), 3,
4135
InvalidOid, NULL, NULL);
4136
locfcinfo.arg[0] = PointerGetDatum(array);
4137
locfcinfo.arg[1] = Int32GetDatum(acoerce->resulttypmod);
4138
locfcinfo.arg[2] = BoolGetDatum(acoerce->isExplicit);
4139
locfcinfo.argnull[0] = false;
4140
locfcinfo.argnull[1] = false;
4141
locfcinfo.argnull[2] = false;
4143
return array_map(&locfcinfo, ARR_ELEMTYPE(array), astate->resultelemtype,
4147
/* ----------------------------------------------------------------
4148
* ExecEvalCurrentOfExpr
4150
* The planner must convert CURRENT OF into a TidScan qualification.
4151
* So, we have to be able to do ExecInitExpr on a CurrentOfExpr,
4152
* but we shouldn't ever actually execute it.
4153
* ----------------------------------------------------------------
4156
ExecEvalCurrentOfExpr(ExprState *exprstate, ExprContext *econtext,
4157
bool *isNull, ExprDoneCond *isDone)
4159
elog(ERROR, "CURRENT OF cannot be executed");
4160
return 0; /* keep compiler quiet */
4165
* ExecEvalExprSwitchContext
4167
* Same as ExecEvalExpr, but get into the right allocation context explicitly.
4170
ExecEvalExprSwitchContext(ExprState *expression,
4171
ExprContext *econtext,
4173
ExprDoneCond *isDone)
4176
MemoryContext oldContext;
4178
oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
4179
retDatum = ExecEvalExpr(expression, econtext, isNull, isDone);
4180
MemoryContextSwitchTo(oldContext);
4186
* ExecInitExpr: prepare an expression tree for execution
4188
* This function builds and returns an ExprState tree paralleling the given
4189
* Expr node tree. The ExprState tree can then be handed to ExecEvalExpr
4190
* for execution. Because the Expr tree itself is read-only as far as
4191
* ExecInitExpr and ExecEvalExpr are concerned, several different executions
4192
* of the same plan tree can occur concurrently.
4194
* This must be called in a memory context that will last as long as repeated
4195
* executions of the expression are needed. Typically the context will be
4196
* the same as the per-query context of the associated ExprContext.
4198
* Any Aggref, WindowFunc, or SubPlan nodes found in the tree are added to the
4199
* lists of such nodes held by the parent PlanState. Otherwise, we do very
4200
* little initialization here other than building the state-node tree. Any
4201
* nontrivial work associated with initializing runtime info for a node should
4202
* happen during the first actual evaluation of that node. (This policy lets
4203
* us avoid work if the node is never actually evaluated.)
4205
* Note: there is no ExecEndExpr function; we assume that any resource
4206
* cleanup needed will be handled by just releasing the memory context
4207
* in which the state tree is built. Functions that require additional
4208
* cleanup work can register a shutdown callback in the ExprContext.
4210
* 'node' is the root of the expression tree to examine
4211
* 'parent' is the PlanState node that owns the expression.
4213
* 'parent' may be NULL if we are preparing an expression that is not
4214
* associated with a plan tree. (If so, it can't have aggs or subplans.)
4215
* This case should usually come through ExecPrepareExpr, not directly here.
4218
ExecInitExpr(Expr *node, PlanState *parent)
4225
/* Guard against stack overflow due to overly complex expressions */
4226
check_stack_depth();
4228
switch (nodeTag(node))
4231
state = (ExprState *) makeNode(ExprState);
4232
state->evalfunc = ExecEvalVar;
4235
state = (ExprState *) makeNode(ExprState);
4236
state->evalfunc = ExecEvalConst;
4239
state = (ExprState *) makeNode(ExprState);
4240
switch (((Param *) node)->paramkind)
4243
state->evalfunc = ExecEvalParamExec;
4246
state->evalfunc = ExecEvalParamExtern;
4249
elog(ERROR, "unrecognized paramkind: %d",
4250
(int) ((Param *) node)->paramkind);
4254
case T_CoerceToDomainValue:
4255
state = (ExprState *) makeNode(ExprState);
4256
state->evalfunc = ExecEvalCoerceToDomainValue;
4258
case T_CaseTestExpr:
4259
state = (ExprState *) makeNode(ExprState);
4260
state->evalfunc = ExecEvalCaseTestExpr;
4264
Aggref *aggref = (Aggref *) node;
4265
AggrefExprState *astate = makeNode(AggrefExprState);
4267
astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalAggref;
4268
if (parent && IsA(parent, AggState))
4270
AggState *aggstate = (AggState *) parent;
4273
aggstate->aggs = lcons(astate, aggstate->aggs);
4274
naggs = ++aggstate->numaggs;
4276
astate->args = (List *) ExecInitExpr((Expr *) aggref->args,
4280
* Complain if the aggregate's arguments contain any
4281
* aggregates; nested agg functions are semantically
4282
* nonsensical. (This should have been caught earlier,
4283
* but we defend against it here anyway.)
4285
if (naggs != aggstate->numaggs)
4287
(errcode(ERRCODE_GROUPING_ERROR),
4288
errmsg("aggregate function calls cannot be nested")));
4292
/* planner messed up */
4293
elog(ERROR, "Aggref found in non-Agg plan node");
4295
state = (ExprState *) astate;
4300
WindowFunc *wfunc = (WindowFunc *) node;
4301
WindowFuncExprState *wfstate = makeNode(WindowFuncExprState);
4303
wfstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalWindowFunc;
4304
if (parent && IsA(parent, WindowAggState))
4306
WindowAggState *winstate = (WindowAggState *) parent;
4309
winstate->funcs = lcons(wfstate, winstate->funcs);
4310
nfuncs = ++winstate->numfuncs;
4312
winstate->numaggs++;
4314
wfstate->args = (List *) ExecInitExpr((Expr *) wfunc->args,
4318
* Complain if the windowfunc's arguments contain any
4319
* windowfuncs; nested window functions are semantically
4320
* nonsensical. (This should have been caught earlier,
4321
* but we defend against it here anyway.)
4323
if (nfuncs != winstate->numfuncs)
4325
(errcode(ERRCODE_WINDOWING_ERROR),
4326
errmsg("window function calls cannot be nested")));
4330
/* planner messed up */
4331
elog(ERROR, "WindowFunc found in non-WindowAgg plan node");
4333
state = (ExprState *) wfstate;
4338
ArrayRef *aref = (ArrayRef *) node;
4339
ArrayRefExprState *astate = makeNode(ArrayRefExprState);
4341
astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArrayRef;
4342
astate->refupperindexpr = (List *)
4343
ExecInitExpr((Expr *) aref->refupperindexpr, parent);
4344
astate->reflowerindexpr = (List *)
4345
ExecInitExpr((Expr *) aref->reflowerindexpr, parent);
4346
astate->refexpr = ExecInitExpr(aref->refexpr, parent);
4347
astate->refassgnexpr = ExecInitExpr(aref->refassgnexpr,
4349
/* do one-time catalog lookups for type info */
4350
astate->refattrlength = get_typlen(aref->refarraytype);
4351
get_typlenbyvalalign(aref->refelemtype,
4352
&astate->refelemlength,
4353
&astate->refelembyval,
4354
&astate->refelemalign);
4355
state = (ExprState *) astate;
4360
FuncExpr *funcexpr = (FuncExpr *) node;
4361
FuncExprState *fstate = makeNode(FuncExprState);
4363
fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFunc;
4364
fstate->args = (List *)
4365
ExecInitExpr((Expr *) funcexpr->args, parent);
4366
fstate->func.fn_oid = InvalidOid; /* not initialized */
4367
state = (ExprState *) fstate;
4372
OpExpr *opexpr = (OpExpr *) node;
4373
FuncExprState *fstate = makeNode(FuncExprState);
4375
fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalOper;
4376
fstate->args = (List *)
4377
ExecInitExpr((Expr *) opexpr->args, parent);
4378
fstate->func.fn_oid = InvalidOid; /* not initialized */
4379
state = (ExprState *) fstate;
4382
case T_DistinctExpr:
4384
DistinctExpr *distinctexpr = (DistinctExpr *) node;
4385
FuncExprState *fstate = makeNode(FuncExprState);
4387
fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalDistinct;
4388
fstate->args = (List *)
4389
ExecInitExpr((Expr *) distinctexpr->args, parent);
4390
fstate->func.fn_oid = InvalidOid; /* not initialized */
4391
state = (ExprState *) fstate;
4396
NullIfExpr *nullifexpr = (NullIfExpr *) node;
4397
FuncExprState *fstate = makeNode(FuncExprState);
4399
fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNullIf;
4400
fstate->args = (List *)
4401
ExecInitExpr((Expr *) nullifexpr->args, parent);
4402
fstate->func.fn_oid = InvalidOid; /* not initialized */
4403
state = (ExprState *) fstate;
4406
case T_ScalarArrayOpExpr:
4408
ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) node;
4409
ScalarArrayOpExprState *sstate = makeNode(ScalarArrayOpExprState);
4411
sstate->fxprstate.xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalScalarArrayOp;
4412
sstate->fxprstate.args = (List *)
4413
ExecInitExpr((Expr *) opexpr->args, parent);
4414
sstate->fxprstate.func.fn_oid = InvalidOid; /* not initialized */
4415
sstate->element_type = InvalidOid; /* ditto */
4416
state = (ExprState *) sstate;
4421
BoolExpr *boolexpr = (BoolExpr *) node;
4422
BoolExprState *bstate = makeNode(BoolExprState);
4424
switch (boolexpr->boolop)
4427
bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalAnd;
4430
bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalOr;
4433
bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNot;
4436
elog(ERROR, "unrecognized boolop: %d",
4437
(int) boolexpr->boolop);
4440
bstate->args = (List *)
4441
ExecInitExpr((Expr *) boolexpr->args, parent);
4442
state = (ExprState *) bstate;
4447
SubPlan *subplan = (SubPlan *) node;
4448
SubPlanState *sstate;
4451
elog(ERROR, "SubPlan found with no parent plan");
4453
sstate = ExecInitSubPlan(subplan, parent);
4455
/* Add SubPlanState nodes to parent->subPlan */
4456
parent->subPlan = lappend(parent->subPlan, sstate);
4458
state = (ExprState *) sstate;
4461
case T_AlternativeSubPlan:
4463
AlternativeSubPlan *asplan = (AlternativeSubPlan *) node;
4464
AlternativeSubPlanState *asstate;
4467
elog(ERROR, "AlternativeSubPlan found with no parent plan");
4469
asstate = ExecInitAlternativeSubPlan(asplan, parent);
4471
state = (ExprState *) asstate;
4476
FieldSelect *fselect = (FieldSelect *) node;
4477
FieldSelectState *fstate = makeNode(FieldSelectState);
4479
fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFieldSelect;
4480
fstate->arg = ExecInitExpr(fselect->arg, parent);
4481
fstate->argdesc = NULL;
4482
state = (ExprState *) fstate;
4487
FieldStore *fstore = (FieldStore *) node;
4488
FieldStoreState *fstate = makeNode(FieldStoreState);
4490
fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFieldStore;
4491
fstate->arg = ExecInitExpr(fstore->arg, parent);
4492
fstate->newvals = (List *) ExecInitExpr((Expr *) fstore->newvals, parent);
4493
fstate->argdesc = NULL;
4494
state = (ExprState *) fstate;
4499
RelabelType *relabel = (RelabelType *) node;
4500
GenericExprState *gstate = makeNode(GenericExprState);
4502
gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRelabelType;
4503
gstate->arg = ExecInitExpr(relabel->arg, parent);
4504
state = (ExprState *) gstate;
4509
CoerceViaIO *iocoerce = (CoerceViaIO *) node;
4510
CoerceViaIOState *iostate = makeNode(CoerceViaIOState);
4514
iostate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoerceViaIO;
4515
iostate->arg = ExecInitExpr(iocoerce->arg, parent);
4516
/* lookup the result type's input function */
4517
getTypeInputInfo(iocoerce->resulttype, &iofunc,
4518
&iostate->intypioparam);
4519
fmgr_info(iofunc, &iostate->infunc);
4520
/* lookup the input type's output function */
4521
getTypeOutputInfo(exprType((Node *) iocoerce->arg),
4522
&iofunc, &typisvarlena);
4523
fmgr_info(iofunc, &iostate->outfunc);
4524
state = (ExprState *) iostate;
4527
case T_ArrayCoerceExpr:
4529
ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node;
4530
ArrayCoerceExprState *astate = makeNode(ArrayCoerceExprState);
4532
astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArrayCoerceExpr;
4533
astate->arg = ExecInitExpr(acoerce->arg, parent);
4534
astate->resultelemtype = get_element_type(acoerce->resulttype);
4535
if (astate->resultelemtype == InvalidOid)
4537
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4538
errmsg("target type is not an array")));
4539
/* Arrays over domains aren't supported yet */
4540
Assert(getBaseType(astate->resultelemtype) ==
4541
astate->resultelemtype);
4542
astate->elemfunc.fn_oid = InvalidOid; /* not initialized */
4543
astate->amstate = (ArrayMapState *) palloc0(sizeof(ArrayMapState));
4544
state = (ExprState *) astate;
4547
case T_ConvertRowtypeExpr:
4549
ConvertRowtypeExpr *convert = (ConvertRowtypeExpr *) node;
4550
ConvertRowtypeExprState *cstate = makeNode(ConvertRowtypeExprState);
4552
cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalConvertRowtype;
4553
cstate->arg = ExecInitExpr(convert->arg, parent);
4554
state = (ExprState *) cstate;
4559
CaseExpr *caseexpr = (CaseExpr *) node;
4560
CaseExprState *cstate = makeNode(CaseExprState);
4561
List *outlist = NIL;
4564
cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCase;
4565
cstate->arg = ExecInitExpr(caseexpr->arg, parent);
4566
foreach(l, caseexpr->args)
4568
CaseWhen *when = (CaseWhen *) lfirst(l);
4569
CaseWhenState *wstate = makeNode(CaseWhenState);
4571
Assert(IsA(when, CaseWhen));
4572
wstate->xprstate.evalfunc = NULL; /* not used */
4573
wstate->xprstate.expr = (Expr *) when;
4574
wstate->expr = ExecInitExpr(when->expr, parent);
4575
wstate->result = ExecInitExpr(when->result, parent);
4576
outlist = lappend(outlist, wstate);
4578
cstate->args = outlist;
4579
cstate->defresult = ExecInitExpr(caseexpr->defresult, parent);
4580
state = (ExprState *) cstate;
4585
ArrayExpr *arrayexpr = (ArrayExpr *) node;
4586
ArrayExprState *astate = makeNode(ArrayExprState);
4587
List *outlist = NIL;
4590
astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArray;
4591
foreach(l, arrayexpr->elements)
4593
Expr *e = (Expr *) lfirst(l);
4596
estate = ExecInitExpr(e, parent);
4597
outlist = lappend(outlist, estate);
4599
astate->elements = outlist;
4600
/* do one-time catalog lookup for type info */
4601
get_typlenbyvalalign(arrayexpr->element_typeid,
4602
&astate->elemlength,
4604
&astate->elemalign);
4605
state = (ExprState *) astate;
4610
RowExpr *rowexpr = (RowExpr *) node;
4611
RowExprState *rstate = makeNode(RowExprState);
4612
Form_pg_attribute *attrs;
4613
List *outlist = NIL;
4617
rstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRow;
4618
/* Build tupdesc to describe result tuples */
4619
if (rowexpr->row_typeid == RECORDOID)
4621
/* generic record, use runtime type assignment */
4622
rstate->tupdesc = ExecTypeFromExprList(rowexpr->args);
4623
BlessTupleDesc(rstate->tupdesc);
4624
/* we won't need to redo this at runtime */
4628
/* it's been cast to a named type, use that */
4629
rstate->tupdesc = lookup_rowtype_tupdesc_copy(rowexpr->row_typeid, -1);
4631
/* Set up evaluation, skipping any deleted columns */
4632
Assert(list_length(rowexpr->args) <= rstate->tupdesc->natts);
4633
attrs = rstate->tupdesc->attrs;
4635
foreach(l, rowexpr->args)
4637
Expr *e = (Expr *) lfirst(l);
4640
if (!attrs[i]->attisdropped)
4643
* Guard against ALTER COLUMN TYPE on rowtype since
4644
* the RowExpr was created. XXX should we check
4645
* typmod too? Not sure we can be sure it'll be the
4648
if (exprType((Node *) e) != attrs[i]->atttypid)
4650
(errcode(ERRCODE_DATATYPE_MISMATCH),
4651
errmsg("ROW() column has type %s instead of type %s",
4652
format_type_be(exprType((Node *) e)),
4653
format_type_be(attrs[i]->atttypid))));
4658
* Ignore original expression and insert a NULL. We
4659
* don't really care what type of NULL it is, so
4660
* always make an int4 NULL.
4662
e = (Expr *) makeNullConst(INT4OID, -1, InvalidOid);
4664
estate = ExecInitExpr(e, parent);
4665
outlist = lappend(outlist, estate);
4668
rstate->args = outlist;
4669
state = (ExprState *) rstate;
4672
case T_RowCompareExpr:
4674
RowCompareExpr *rcexpr = (RowCompareExpr *) node;
4675
RowCompareExprState *rstate = makeNode(RowCompareExprState);
4676
int nopers = list_length(rcexpr->opnos);
4683
rstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRowCompare;
4684
Assert(list_length(rcexpr->largs) == nopers);
4686
foreach(l, rcexpr->largs)
4688
Expr *e = (Expr *) lfirst(l);
4691
estate = ExecInitExpr(e, parent);
4692
outlist = lappend(outlist, estate);
4694
rstate->largs = outlist;
4695
Assert(list_length(rcexpr->rargs) == nopers);
4697
foreach(l, rcexpr->rargs)
4699
Expr *e = (Expr *) lfirst(l);
4702
estate = ExecInitExpr(e, parent);
4703
outlist = lappend(outlist, estate);
4705
rstate->rargs = outlist;
4706
Assert(list_length(rcexpr->opfamilies) == nopers);
4707
rstate->funcs = (FmgrInfo *) palloc(nopers * sizeof(FmgrInfo));
4708
rstate->collations = (Oid *) palloc(nopers * sizeof(Oid));
4710
forthree(l, rcexpr->opnos, l2, rcexpr->opfamilies, l3, rcexpr->inputcollids)
4712
Oid opno = lfirst_oid(l);
4713
Oid opfamily = lfirst_oid(l2);
4714
Oid inputcollid = lfirst_oid(l3);
4720
get_op_opfamily_properties(opno, opfamily, false,
4724
proc = get_opfamily_proc(opfamily,
4730
* If we enforced permissions checks on index support
4731
* functions, we'd need to make a check here. But the
4732
* index support machinery doesn't do that, and neither
4735
fmgr_info(proc, &(rstate->funcs[i]));
4736
rstate->collations[i] = inputcollid;
4739
state = (ExprState *) rstate;
4742
case T_CoalesceExpr:
4744
CoalesceExpr *coalesceexpr = (CoalesceExpr *) node;
4745
CoalesceExprState *cstate = makeNode(CoalesceExprState);
4746
List *outlist = NIL;
4749
cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoalesce;
4750
foreach(l, coalesceexpr->args)
4752
Expr *e = (Expr *) lfirst(l);
4755
estate = ExecInitExpr(e, parent);
4756
outlist = lappend(outlist, estate);
4758
cstate->args = outlist;
4759
state = (ExprState *) cstate;
4764
MinMaxExpr *minmaxexpr = (MinMaxExpr *) node;
4765
MinMaxExprState *mstate = makeNode(MinMaxExprState);
4766
List *outlist = NIL;
4768
TypeCacheEntry *typentry;
4770
mstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalMinMax;
4771
foreach(l, minmaxexpr->args)
4773
Expr *e = (Expr *) lfirst(l);
4776
estate = ExecInitExpr(e, parent);
4777
outlist = lappend(outlist, estate);
4779
mstate->args = outlist;
4780
/* Look up the btree comparison function for the datatype */
4781
typentry = lookup_type_cache(minmaxexpr->minmaxtype,
4782
TYPECACHE_CMP_PROC);
4783
if (!OidIsValid(typentry->cmp_proc))
4785
(errcode(ERRCODE_UNDEFINED_FUNCTION),
4786
errmsg("could not identify a comparison function for type %s",
4787
format_type_be(minmaxexpr->minmaxtype))));
4790
* If we enforced permissions checks on index support
4791
* functions, we'd need to make a check here. But the index
4792
* support machinery doesn't do that, and neither does this
4795
fmgr_info(typentry->cmp_proc, &(mstate->cfunc));
4796
state = (ExprState *) mstate;
4801
XmlExpr *xexpr = (XmlExpr *) node;
4802
XmlExprState *xstate = makeNode(XmlExprState);
4806
xstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalXml;
4808
foreach(arg, xexpr->named_args)
4810
Expr *e = (Expr *) lfirst(arg);
4813
estate = ExecInitExpr(e, parent);
4814
outlist = lappend(outlist, estate);
4816
xstate->named_args = outlist;
4819
foreach(arg, xexpr->args)
4821
Expr *e = (Expr *) lfirst(arg);
4824
estate = ExecInitExpr(e, parent);
4825
outlist = lappend(outlist, estate);
4827
xstate->args = outlist;
4829
state = (ExprState *) xstate;
4834
NullTest *ntest = (NullTest *) node;
4835
NullTestState *nstate = makeNode(NullTestState);
4837
nstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNullTest;
4838
nstate->arg = ExecInitExpr(ntest->arg, parent);
4839
nstate->argdesc = NULL;
4840
state = (ExprState *) nstate;
4845
BooleanTest *btest = (BooleanTest *) node;
4846
GenericExprState *gstate = makeNode(GenericExprState);
4848
gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalBooleanTest;
4849
gstate->arg = ExecInitExpr(btest->arg, parent);
4850
state = (ExprState *) gstate;
4853
case T_CoerceToDomain:
4855
CoerceToDomain *ctest = (CoerceToDomain *) node;
4856
CoerceToDomainState *cstate = makeNode(CoerceToDomainState);
4858
cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoerceToDomain;
4859
cstate->arg = ExecInitExpr(ctest->arg, parent);
4860
cstate->constraints = GetDomainConstraints(ctest->resulttype);
4861
state = (ExprState *) cstate;
4864
case T_CurrentOfExpr:
4865
state = (ExprState *) makeNode(ExprState);
4866
state->evalfunc = ExecEvalCurrentOfExpr;
4870
TargetEntry *tle = (TargetEntry *) node;
4871
GenericExprState *gstate = makeNode(GenericExprState);
4873
gstate->xprstate.evalfunc = NULL; /* not used */
4874
gstate->arg = ExecInitExpr(tle->expr, parent);
4875
state = (ExprState *) gstate;
4880
List *outlist = NIL;
4883
foreach(l, (List *) node)
4885
outlist = lappend(outlist,
4886
ExecInitExpr((Expr *) lfirst(l),
4889
/* Don't fall through to the "common" code below */
4890
return (ExprState *) outlist;
4893
elog(ERROR, "unrecognized node type: %d",
4894
(int) nodeTag(node));
4895
state = NULL; /* keep compiler quiet */
4899
/* Common code for all state-node types */
4906
* ExecPrepareExpr --- initialize for expression execution outside a normal
4907
* Plan tree context.
4909
* This differs from ExecInitExpr in that we don't assume the caller is
4910
* already running in the EState's per-query context. Also, we run the
4911
* passed expression tree through expression_planner() to prepare it for
4912
* execution. (In ordinary Plan trees the regular planning process will have
4913
* made the appropriate transformations on expressions, but for standalone
4914
* expressions this won't have happened.)
4917
ExecPrepareExpr(Expr *node, EState *estate)
4920
MemoryContext oldcontext;
4922
oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
4924
node = expression_planner(node);
4926
result = ExecInitExpr(node, NULL);
4928
MemoryContextSwitchTo(oldcontext);
4934
/* ----------------------------------------------------------------
4935
* ExecQual / ExecTargetList / ExecProject
4936
* ----------------------------------------------------------------
4939
/* ----------------------------------------------------------------
4942
* Evaluates a conjunctive boolean expression (qual list) and
4943
* returns true iff none of the subexpressions are false.
4944
* (We also return true if the list is empty.)
4946
* If some of the subexpressions yield NULL but none yield FALSE,
4947
* then the result of the conjunction is NULL (ie, unknown)
4948
* according to three-valued boolean logic. In this case,
4949
* we return the value specified by the "resultForNull" parameter.
4951
* Callers evaluating WHERE clauses should pass resultForNull=FALSE,
4952
* since SQL specifies that tuples with null WHERE results do not
4953
* get selected. On the other hand, callers evaluating constraint
4954
* conditions should pass resultForNull=TRUE, since SQL also specifies
4955
* that NULL constraint conditions are not failures.
4957
* NOTE: it would not be correct to use this routine to evaluate an
4958
* AND subclause of a boolean expression; for that purpose, a NULL
4959
* result must be returned as NULL so that it can be properly treated
4960
* in the next higher operator (cf. ExecEvalAnd and ExecEvalOr).
4961
* This routine is only used in contexts where a complete expression
4962
* is being evaluated and we know that NULL can be treated the same
4963
* as one boolean result or the other.
4965
* ----------------------------------------------------------------
4968
ExecQual(List *qual, ExprContext *econtext, bool resultForNull)
4971
MemoryContext oldContext;
4977
EV_printf("ExecQual: qual is ");
4978
EV_nodeDisplay(qual);
4982
* Run in short-lived per-tuple context while computing expressions.
4984
oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
4987
* Evaluate the qual conditions one at a time. If we find a FALSE result,
4988
* we can stop evaluating and return FALSE --- the AND result must be
4989
* FALSE. Also, if we find a NULL result when resultForNull is FALSE, we
4990
* can stop and return FALSE --- the AND result must be FALSE or NULL in
4991
* that case, and the caller doesn't care which.
4993
* If we get to the end of the list, we can return TRUE. This will happen
4994
* when the AND result is indeed TRUE, or when the AND result is NULL (one
4995
* or more NULL subresult, with all the rest TRUE) and the caller has
4996
* specified resultForNull = TRUE.
5002
ExprState *clause = (ExprState *) lfirst(l);
5006
expr_value = ExecEvalExpr(clause, econtext, &isNull, NULL);
5010
if (resultForNull == false)
5012
result = false; /* treat NULL as FALSE */
5018
if (!DatumGetBool(expr_value))
5020
result = false; /* definitely FALSE */
5026
MemoryContextSwitchTo(oldContext);
5032
* Number of items in a tlist (including any resjunk items!)
5035
ExecTargetListLength(List *targetlist)
5037
/* This used to be more complex, but fjoins are dead */
5038
return list_length(targetlist);
5042
* Number of items in a tlist, not including any resjunk items
5045
ExecCleanTargetListLength(List *targetlist)
5050
foreach(tl, targetlist)
5052
TargetEntry *curTle = (TargetEntry *) lfirst(tl);
5054
Assert(IsA(curTle, TargetEntry));
5055
if (!curTle->resjunk)
5063
* Evaluates a targetlist with respect to the given
5064
* expression context. Returns TRUE if we were able to create
5065
* a result, FALSE if we have exhausted a set-valued expression.
5067
* Results are stored into the passed values and isnull arrays.
5068
* The caller must provide an itemIsDone array that persists across calls.
5070
* As with ExecEvalExpr, the caller should pass isDone = NULL if not
5071
* prepared to deal with sets of result tuples. Otherwise, a return
5072
* of *isDone = ExprMultipleResult signifies a set element, and a return
5073
* of *isDone = ExprEndResult signifies end of the set of tuple.
5074
* We assume that *isDone has been initialized to ExprSingleResult by caller.
5077
ExecTargetList(List *targetlist,
5078
ExprContext *econtext,
5081
ExprDoneCond *itemIsDone,
5082
ExprDoneCond *isDone)
5084
MemoryContext oldContext;
5089
* Run in short-lived per-tuple context while computing expressions.
5091
oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
5094
* evaluate all the expressions in the target list
5096
haveDoneSets = false; /* any exhausted set exprs in tlist? */
5098
foreach(tl, targetlist)
5100
GenericExprState *gstate = (GenericExprState *) lfirst(tl);
5101
TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
5102
AttrNumber resind = tle->resno - 1;
5104
values[resind] = ExecEvalExpr(gstate->arg,
5107
&itemIsDone[resind]);
5109
if (itemIsDone[resind] != ExprSingleResult)
5111
/* We have a set-valued expression in the tlist */
5114
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5115
errmsg("set-valued function called in context that cannot accept a set")));
5116
if (itemIsDone[resind] == ExprMultipleResult)
5118
/* we have undone sets in the tlist, set flag */
5119
*isDone = ExprMultipleResult;
5123
/* we have done sets in the tlist, set flag for that */
5124
haveDoneSets = true;
5132
* note: can't get here unless we verified isDone != NULL
5134
if (*isDone == ExprSingleResult)
5137
* all sets are done, so report that tlist expansion is complete.
5139
*isDone = ExprEndResult;
5140
MemoryContextSwitchTo(oldContext);
5146
* We have some done and some undone sets. Restart the done ones
5147
* so that we can deliver a tuple (if possible).
5149
foreach(tl, targetlist)
5151
GenericExprState *gstate = (GenericExprState *) lfirst(tl);
5152
TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
5153
AttrNumber resind = tle->resno - 1;
5155
if (itemIsDone[resind] == ExprEndResult)
5157
values[resind] = ExecEvalExpr(gstate->arg,
5160
&itemIsDone[resind]);
5162
if (itemIsDone[resind] == ExprEndResult)
5165
* Oh dear, this item is returning an empty set. Guess
5166
* we can't make a tuple after all.
5168
*isDone = ExprEndResult;
5175
* If we cannot make a tuple because some sets are empty, we still
5176
* have to cycle the nonempty sets to completion, else resources
5177
* will not be released from subplans etc.
5179
* XXX is that still necessary?
5181
if (*isDone == ExprEndResult)
5183
foreach(tl, targetlist)
5185
GenericExprState *gstate = (GenericExprState *) lfirst(tl);
5186
TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
5187
AttrNumber resind = tle->resno - 1;
5189
while (itemIsDone[resind] == ExprMultipleResult)
5191
values[resind] = ExecEvalExpr(gstate->arg,
5194
&itemIsDone[resind]);
5198
MemoryContextSwitchTo(oldContext);
5204
/* Report success */
5205
MemoryContextSwitchTo(oldContext);
5213
* projects a tuple based on projection info and stores
5214
* it in the previously specified tuple table slot.
5216
* Note: the result is always a virtual tuple; therefore it
5217
* may reference the contents of the exprContext's scan tuples
5218
* and/or temporary results constructed in the exprContext.
5219
* If the caller wishes the result to be valid longer than that
5220
* data will be valid, he must call ExecMaterializeSlot on the
5224
ExecProject(ProjectionInfo *projInfo, ExprDoneCond *isDone)
5226
TupleTableSlot *slot;
5227
ExprContext *econtext;
5233
Assert(projInfo != NULL);
5236
* get the projection info we want
5238
slot = projInfo->pi_slot;
5239
econtext = projInfo->pi_exprContext;
5241
/* Assume single result row until proven otherwise */
5243
*isDone = ExprSingleResult;
5246
* Clear any former contents of the result slot. This makes it safe for
5247
* us to use the slot's Datum/isnull arrays as workspace. (Also, we can
5248
* return the slot as-is if we decide no rows can be projected.)
5250
ExecClearTuple(slot);
5253
* Force extraction of all input values that we'll need. The
5254
* Var-extraction loops below depend on this, and we are also prefetching
5255
* all attributes that will be referenced in the generic expressions.
5257
if (projInfo->pi_lastInnerVar > 0)
5258
slot_getsomeattrs(econtext->ecxt_innertuple,
5259
projInfo->pi_lastInnerVar);
5260
if (projInfo->pi_lastOuterVar > 0)
5261
slot_getsomeattrs(econtext->ecxt_outertuple,
5262
projInfo->pi_lastOuterVar);
5263
if (projInfo->pi_lastScanVar > 0)
5264
slot_getsomeattrs(econtext->ecxt_scantuple,
5265
projInfo->pi_lastScanVar);
5268
* Assign simple Vars to result by direct extraction of fields from source
5269
* slots ... a mite ugly, but fast ...
5271
numSimpleVars = projInfo->pi_numSimpleVars;
5272
if (numSimpleVars > 0)
5274
Datum *values = slot->tts_values;
5275
bool *isnull = slot->tts_isnull;
5276
int *varSlotOffsets = projInfo->pi_varSlotOffsets;
5277
int *varNumbers = projInfo->pi_varNumbers;
5280
if (projInfo->pi_directMap)
5282
/* especially simple case where vars go to output in order */
5283
for (i = 0; i < numSimpleVars; i++)
5285
char *slotptr = ((char *) econtext) + varSlotOffsets[i];
5286
TupleTableSlot *varSlot = *((TupleTableSlot **) slotptr);
5287
int varNumber = varNumbers[i] - 1;
5289
values[i] = varSlot->tts_values[varNumber];
5290
isnull[i] = varSlot->tts_isnull[varNumber];
5295
/* we have to pay attention to varOutputCols[] */
5296
int *varOutputCols = projInfo->pi_varOutputCols;
5298
for (i = 0; i < numSimpleVars; i++)
5300
char *slotptr = ((char *) econtext) + varSlotOffsets[i];
5301
TupleTableSlot *varSlot = *((TupleTableSlot **) slotptr);
5302
int varNumber = varNumbers[i] - 1;
5303
int varOutputCol = varOutputCols[i] - 1;
5305
values[varOutputCol] = varSlot->tts_values[varNumber];
5306
isnull[varOutputCol] = varSlot->tts_isnull[varNumber];
5312
* If there are any generic expressions, evaluate them. It's possible
5313
* that there are set-returning functions in such expressions; if so and
5314
* we have reached the end of the set, we return the result slot, which we
5315
* already marked empty.
5317
if (projInfo->pi_targetlist)
5319
if (!ExecTargetList(projInfo->pi_targetlist,
5323
projInfo->pi_itemIsDone,
5325
return slot; /* no more result rows, return empty slot */
5329
* Successfully formed a result row. Mark the result slot as containing a
5330
* valid virtual tuple.
5332
return ExecStoreVirtualTuple(slot);