00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "postgres.h"
00038
00039 #include "access/htup_details.h"
00040 #include "access/nbtree.h"
00041 #include "access/tupconvert.h"
00042 #include "catalog/objectaccess.h"
00043 #include "catalog/pg_type.h"
00044 #include "commands/typecmds.h"
00045 #include "executor/execdebug.h"
00046 #include "executor/nodeSubplan.h"
00047 #include "funcapi.h"
00048 #include "miscadmin.h"
00049 #include "nodes/makefuncs.h"
00050 #include "nodes/nodeFuncs.h"
00051 #include "optimizer/planner.h"
00052 #include "parser/parse_coerce.h"
00053 #include "pgstat.h"
00054 #include "utils/acl.h"
00055 #include "utils/builtins.h"
00056 #include "utils/lsyscache.h"
00057 #include "utils/memutils.h"
00058 #include "utils/typcache.h"
00059 #include "utils/xml.h"
00060
00061
00062
00063 static Datum ExecEvalArrayRef(ArrayRefExprState *astate,
00064 ExprContext *econtext,
00065 bool *isNull, ExprDoneCond *isDone);
00066 static bool isAssignmentIndirectionExpr(ExprState *exprstate);
00067 static Datum ExecEvalAggref(AggrefExprState *aggref,
00068 ExprContext *econtext,
00069 bool *isNull, ExprDoneCond *isDone);
00070 static Datum ExecEvalWindowFunc(WindowFuncExprState *wfunc,
00071 ExprContext *econtext,
00072 bool *isNull, ExprDoneCond *isDone);
00073 static Datum ExecEvalScalarVar(ExprState *exprstate, ExprContext *econtext,
00074 bool *isNull, ExprDoneCond *isDone);
00075 static Datum ExecEvalScalarVarFast(ExprState *exprstate, ExprContext *econtext,
00076 bool *isNull, ExprDoneCond *isDone);
00077 static Datum ExecEvalWholeRowVar(WholeRowVarExprState *wrvstate,
00078 ExprContext *econtext,
00079 bool *isNull, ExprDoneCond *isDone);
00080 static Datum ExecEvalWholeRowFast(WholeRowVarExprState *wrvstate,
00081 ExprContext *econtext,
00082 bool *isNull, ExprDoneCond *isDone);
00083 static Datum ExecEvalWholeRowSlow(WholeRowVarExprState *wrvstate,
00084 ExprContext *econtext,
00085 bool *isNull, ExprDoneCond *isDone);
00086 static Datum ExecEvalConst(ExprState *exprstate, ExprContext *econtext,
00087 bool *isNull, ExprDoneCond *isDone);
00088 static Datum ExecEvalParamExec(ExprState *exprstate, ExprContext *econtext,
00089 bool *isNull, ExprDoneCond *isDone);
00090 static Datum ExecEvalParamExtern(ExprState *exprstate, ExprContext *econtext,
00091 bool *isNull, ExprDoneCond *isDone);
00092 static void init_fcache(Oid foid, Oid input_collation, FuncExprState *fcache,
00093 MemoryContext fcacheCxt, bool needDescForSets);
00094 static void ShutdownFuncExpr(Datum arg);
00095 static TupleDesc get_cached_rowtype(Oid type_id, int32 typmod,
00096 TupleDesc *cache_field, ExprContext *econtext);
00097 static void ShutdownTupleDescRef(Datum arg);
00098 static ExprDoneCond ExecEvalFuncArgs(FunctionCallInfo fcinfo,
00099 List *argList, ExprContext *econtext);
00100 static void ExecPrepareTuplestoreResult(FuncExprState *fcache,
00101 ExprContext *econtext,
00102 Tuplestorestate *resultStore,
00103 TupleDesc resultDesc);
00104 static void tupledesc_match(TupleDesc dst_tupdesc, TupleDesc src_tupdesc);
00105 static Datum ExecMakeFunctionResult(FuncExprState *fcache,
00106 ExprContext *econtext,
00107 bool *isNull,
00108 ExprDoneCond *isDone);
00109 static Datum ExecMakeFunctionResultNoSets(FuncExprState *fcache,
00110 ExprContext *econtext,
00111 bool *isNull, ExprDoneCond *isDone);
00112 static Datum ExecEvalFunc(FuncExprState *fcache, ExprContext *econtext,
00113 bool *isNull, ExprDoneCond *isDone);
00114 static Datum ExecEvalOper(FuncExprState *fcache, ExprContext *econtext,
00115 bool *isNull, ExprDoneCond *isDone);
00116 static Datum ExecEvalDistinct(FuncExprState *fcache, ExprContext *econtext,
00117 bool *isNull, ExprDoneCond *isDone);
00118 static Datum ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate,
00119 ExprContext *econtext,
00120 bool *isNull, ExprDoneCond *isDone);
00121 static Datum ExecEvalNot(BoolExprState *notclause, ExprContext *econtext,
00122 bool *isNull, ExprDoneCond *isDone);
00123 static Datum ExecEvalOr(BoolExprState *orExpr, ExprContext *econtext,
00124 bool *isNull, ExprDoneCond *isDone);
00125 static Datum ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
00126 bool *isNull, ExprDoneCond *isDone);
00127 static Datum ExecEvalConvertRowtype(ConvertRowtypeExprState *cstate,
00128 ExprContext *econtext,
00129 bool *isNull, ExprDoneCond *isDone);
00130 static Datum ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
00131 bool *isNull, ExprDoneCond *isDone);
00132 static Datum ExecEvalCaseTestExpr(ExprState *exprstate,
00133 ExprContext *econtext,
00134 bool *isNull, ExprDoneCond *isDone);
00135 static Datum ExecEvalArray(ArrayExprState *astate,
00136 ExprContext *econtext,
00137 bool *isNull, ExprDoneCond *isDone);
00138 static Datum ExecEvalRow(RowExprState *rstate,
00139 ExprContext *econtext,
00140 bool *isNull, ExprDoneCond *isDone);
00141 static Datum ExecEvalRowCompare(RowCompareExprState *rstate,
00142 ExprContext *econtext,
00143 bool *isNull, ExprDoneCond *isDone);
00144 static Datum ExecEvalCoalesce(CoalesceExprState *coalesceExpr,
00145 ExprContext *econtext,
00146 bool *isNull, ExprDoneCond *isDone);
00147 static Datum ExecEvalMinMax(MinMaxExprState *minmaxExpr,
00148 ExprContext *econtext,
00149 bool *isNull, ExprDoneCond *isDone);
00150 static Datum ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
00151 bool *isNull, ExprDoneCond *isDone);
00152 static Datum ExecEvalNullIf(FuncExprState *nullIfExpr,
00153 ExprContext *econtext,
00154 bool *isNull, ExprDoneCond *isDone);
00155 static Datum ExecEvalNullTest(NullTestState *nstate,
00156 ExprContext *econtext,
00157 bool *isNull, ExprDoneCond *isDone);
00158 static Datum ExecEvalBooleanTest(GenericExprState *bstate,
00159 ExprContext *econtext,
00160 bool *isNull, ExprDoneCond *isDone);
00161 static Datum ExecEvalCoerceToDomain(CoerceToDomainState *cstate,
00162 ExprContext *econtext,
00163 bool *isNull, ExprDoneCond *isDone);
00164 static Datum ExecEvalCoerceToDomainValue(ExprState *exprstate,
00165 ExprContext *econtext,
00166 bool *isNull, ExprDoneCond *isDone);
00167 static Datum ExecEvalFieldSelect(FieldSelectState *fstate,
00168 ExprContext *econtext,
00169 bool *isNull, ExprDoneCond *isDone);
00170 static Datum ExecEvalFieldStore(FieldStoreState *fstate,
00171 ExprContext *econtext,
00172 bool *isNull, ExprDoneCond *isDone);
00173 static Datum ExecEvalRelabelType(GenericExprState *exprstate,
00174 ExprContext *econtext,
00175 bool *isNull, ExprDoneCond *isDone);
00176 static Datum ExecEvalCoerceViaIO(CoerceViaIOState *iostate,
00177 ExprContext *econtext,
00178 bool *isNull, ExprDoneCond *isDone);
00179 static Datum ExecEvalArrayCoerceExpr(ArrayCoerceExprState *astate,
00180 ExprContext *econtext,
00181 bool *isNull, ExprDoneCond *isDone);
00182 static Datum ExecEvalCurrentOfExpr(ExprState *exprstate, ExprContext *econtext,
00183 bool *isNull, ExprDoneCond *isDone);
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 static Datum
00263 ExecEvalArrayRef(ArrayRefExprState *astate,
00264 ExprContext *econtext,
00265 bool *isNull,
00266 ExprDoneCond *isDone)
00267 {
00268 ArrayRef *arrayRef = (ArrayRef *) astate->xprstate.expr;
00269 ArrayType *array_source;
00270 ArrayType *resultArray;
00271 bool isAssignment = (arrayRef->refassgnexpr != NULL);
00272 bool eisnull;
00273 ListCell *l;
00274 int i = 0,
00275 j = 0;
00276 IntArray upper,
00277 lower;
00278 int *lIndex;
00279
00280 array_source = (ArrayType *)
00281 DatumGetPointer(ExecEvalExpr(astate->refexpr,
00282 econtext,
00283 isNull,
00284 isDone));
00285
00286
00287
00288
00289
00290 if (*isNull)
00291 {
00292 if (isDone && *isDone == ExprEndResult)
00293 return (Datum) NULL;
00294 if (!isAssignment)
00295 return (Datum) NULL;
00296 }
00297
00298 foreach(l, astate->refupperindexpr)
00299 {
00300 ExprState *eltstate = (ExprState *) lfirst(l);
00301
00302 if (i >= MAXDIM)
00303 ereport(ERROR,
00304 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
00305 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
00306 i + 1, MAXDIM)));
00307
00308 upper.indx[i++] = DatumGetInt32(ExecEvalExpr(eltstate,
00309 econtext,
00310 &eisnull,
00311 NULL));
00312
00313 if (eisnull)
00314 {
00315 if (isAssignment)
00316 ereport(ERROR,
00317 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
00318 errmsg("array subscript in assignment must not be null")));
00319 *isNull = true;
00320 return (Datum) NULL;
00321 }
00322 }
00323
00324 if (astate->reflowerindexpr != NIL)
00325 {
00326 foreach(l, astate->reflowerindexpr)
00327 {
00328 ExprState *eltstate = (ExprState *) lfirst(l);
00329
00330 if (j >= MAXDIM)
00331 ereport(ERROR,
00332 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
00333 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
00334 j + 1, MAXDIM)));
00335
00336 lower.indx[j++] = DatumGetInt32(ExecEvalExpr(eltstate,
00337 econtext,
00338 &eisnull,
00339 NULL));
00340
00341 if (eisnull)
00342 {
00343 if (isAssignment)
00344 ereport(ERROR,
00345 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
00346 errmsg("array subscript in assignment must not be null")));
00347 *isNull = true;
00348 return (Datum) NULL;
00349 }
00350 }
00351
00352 if (i != j)
00353 elog(ERROR, "upper and lower index lists are not same length");
00354 lIndex = lower.indx;
00355 }
00356 else
00357 lIndex = NULL;
00358
00359 if (isAssignment)
00360 {
00361 Datum sourceData;
00362 Datum save_datum;
00363 bool save_isNull;
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379 save_datum = econtext->caseValue_datum;
00380 save_isNull = econtext->caseValue_isNull;
00381
00382 if (isAssignmentIndirectionExpr(astate->refassgnexpr))
00383 {
00384 if (*isNull)
00385 {
00386
00387 econtext->caseValue_datum = (Datum) 0;
00388 econtext->caseValue_isNull = true;
00389 }
00390 else if (lIndex == NULL)
00391 {
00392 econtext->caseValue_datum = array_ref(array_source, i,
00393 upper.indx,
00394 astate->refattrlength,
00395 astate->refelemlength,
00396 astate->refelembyval,
00397 astate->refelemalign,
00398 &econtext->caseValue_isNull);
00399 }
00400 else
00401 {
00402 resultArray = array_get_slice(array_source, i,
00403 upper.indx, lower.indx,
00404 astate->refattrlength,
00405 astate->refelemlength,
00406 astate->refelembyval,
00407 astate->refelemalign);
00408 econtext->caseValue_datum = PointerGetDatum(resultArray);
00409 econtext->caseValue_isNull = false;
00410 }
00411 }
00412 else
00413 {
00414
00415 econtext->caseValue_datum = (Datum) 0;
00416 econtext->caseValue_isNull = true;
00417 }
00418
00419
00420
00421
00422 sourceData = ExecEvalExpr(astate->refassgnexpr,
00423 econtext,
00424 &eisnull,
00425 NULL);
00426
00427 econtext->caseValue_datum = save_datum;
00428 econtext->caseValue_isNull = save_isNull;
00429
00430
00431
00432
00433
00434
00435 if (astate->refattrlength > 0)
00436 if (eisnull || *isNull)
00437 return PointerGetDatum(array_source);
00438
00439
00440
00441
00442
00443
00444
00445 if (*isNull)
00446 {
00447 array_source = construct_empty_array(arrayRef->refelemtype);
00448 *isNull = false;
00449 }
00450
00451 if (lIndex == NULL)
00452 resultArray = array_set(array_source, i,
00453 upper.indx,
00454 sourceData,
00455 eisnull,
00456 astate->refattrlength,
00457 astate->refelemlength,
00458 astate->refelembyval,
00459 astate->refelemalign);
00460 else
00461 resultArray = array_set_slice(array_source, i,
00462 upper.indx, lower.indx,
00463 (ArrayType *) DatumGetPointer(sourceData),
00464 eisnull,
00465 astate->refattrlength,
00466 astate->refelemlength,
00467 astate->refelembyval,
00468 astate->refelemalign);
00469 return PointerGetDatum(resultArray);
00470 }
00471
00472 if (lIndex == NULL)
00473 return array_ref(array_source, i, upper.indx,
00474 astate->refattrlength,
00475 astate->refelemlength,
00476 astate->refelembyval,
00477 astate->refelemalign,
00478 isNull);
00479 else
00480 {
00481 resultArray = array_get_slice(array_source, i,
00482 upper.indx, lower.indx,
00483 astate->refattrlength,
00484 astate->refelemlength,
00485 astate->refelembyval,
00486 astate->refelemalign);
00487 return PointerGetDatum(resultArray);
00488 }
00489 }
00490
00491
00492
00493
00494
00495
00496
00497
00498 static bool
00499 isAssignmentIndirectionExpr(ExprState *exprstate)
00500 {
00501 if (exprstate == NULL)
00502 return false;
00503 if (IsA(exprstate, FieldStoreState))
00504 {
00505 FieldStore *fstore = (FieldStore *) exprstate->expr;
00506
00507 if (fstore->arg && IsA(fstore->arg, CaseTestExpr))
00508 return true;
00509 }
00510 else if (IsA(exprstate, ArrayRefExprState))
00511 {
00512 ArrayRef *arrayRef = (ArrayRef *) exprstate->expr;
00513
00514 if (arrayRef->refexpr && IsA(arrayRef->refexpr, CaseTestExpr))
00515 return true;
00516 }
00517 return false;
00518 }
00519
00520
00521
00522
00523
00524
00525
00526
00527 static Datum
00528 ExecEvalAggref(AggrefExprState *aggref, ExprContext *econtext,
00529 bool *isNull, ExprDoneCond *isDone)
00530 {
00531 if (isDone)
00532 *isDone = ExprSingleResult;
00533
00534 if (econtext->ecxt_aggvalues == NULL)
00535 elog(ERROR, "no aggregates in this expression context");
00536
00537 *isNull = econtext->ecxt_aggnulls[aggref->aggno];
00538 return econtext->ecxt_aggvalues[aggref->aggno];
00539 }
00540
00541
00542
00543
00544
00545
00546
00547
00548 static Datum
00549 ExecEvalWindowFunc(WindowFuncExprState *wfunc, ExprContext *econtext,
00550 bool *isNull, ExprDoneCond *isDone)
00551 {
00552 if (isDone)
00553 *isDone = ExprSingleResult;
00554
00555 if (econtext->ecxt_aggvalues == NULL)
00556 elog(ERROR, "no window functions in this expression context");
00557
00558 *isNull = econtext->ecxt_aggnulls[wfunc->wfuncno];
00559 return econtext->ecxt_aggvalues[wfunc->wfuncno];
00560 }
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573 static Datum
00574 ExecEvalScalarVar(ExprState *exprstate, ExprContext *econtext,
00575 bool *isNull, ExprDoneCond *isDone)
00576 {
00577 Var *variable = (Var *) exprstate->expr;
00578 TupleTableSlot *slot;
00579 AttrNumber attnum;
00580
00581 if (isDone)
00582 *isDone = ExprSingleResult;
00583
00584
00585 switch (variable->varno)
00586 {
00587 case INNER_VAR:
00588 slot = econtext->ecxt_innertuple;
00589 break;
00590
00591 case OUTER_VAR:
00592 slot = econtext->ecxt_outertuple;
00593 break;
00594
00595
00596
00597 default:
00598
00599 slot = econtext->ecxt_scantuple;
00600 break;
00601 }
00602
00603 attnum = variable->varattno;
00604
00605
00606 Assert(attnum != InvalidAttrNumber);
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625 if (attnum > 0)
00626 {
00627 TupleDesc slot_tupdesc = slot->tts_tupleDescriptor;
00628 Form_pg_attribute attr;
00629
00630 if (attnum > slot_tupdesc->natts)
00631 elog(ERROR, "attribute number %d exceeds number of columns %d",
00632 attnum, slot_tupdesc->natts);
00633
00634 attr = slot_tupdesc->attrs[attnum - 1];
00635
00636
00637 if (!attr->attisdropped)
00638 {
00639 if (variable->vartype != attr->atttypid)
00640 ereport(ERROR,
00641 (errmsg("attribute %d has wrong type", attnum),
00642 errdetail("Table has type %s, but query expects %s.",
00643 format_type_be(attr->atttypid),
00644 format_type_be(variable->vartype))));
00645 }
00646 }
00647
00648
00649 exprstate->evalfunc = ExecEvalScalarVarFast;
00650
00651
00652 return slot_getattr(slot, attnum, isNull);
00653 }
00654
00655
00656
00657
00658
00659
00660
00661 static Datum
00662 ExecEvalScalarVarFast(ExprState *exprstate, ExprContext *econtext,
00663 bool *isNull, ExprDoneCond *isDone)
00664 {
00665 Var *variable = (Var *) exprstate->expr;
00666 TupleTableSlot *slot;
00667 AttrNumber attnum;
00668
00669 if (isDone)
00670 *isDone = ExprSingleResult;
00671
00672
00673 switch (variable->varno)
00674 {
00675 case INNER_VAR:
00676 slot = econtext->ecxt_innertuple;
00677 break;
00678
00679 case OUTER_VAR:
00680 slot = econtext->ecxt_outertuple;
00681 break;
00682
00683
00684
00685 default:
00686
00687 slot = econtext->ecxt_scantuple;
00688 break;
00689 }
00690
00691 attnum = variable->varattno;
00692
00693
00694 return slot_getattr(slot, attnum, isNull);
00695 }
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709 static Datum
00710 ExecEvalWholeRowVar(WholeRowVarExprState *wrvstate, ExprContext *econtext,
00711 bool *isNull, ExprDoneCond *isDone)
00712 {
00713 Var *variable = (Var *) wrvstate->xprstate.expr;
00714 TupleTableSlot *slot;
00715 TupleDesc slot_tupdesc;
00716 bool needslow = false;
00717
00718 if (isDone)
00719 *isDone = ExprSingleResult;
00720
00721
00722 Assert(variable->varattno == InvalidAttrNumber);
00723
00724
00725 switch (variable->varno)
00726 {
00727 case INNER_VAR:
00728 slot = econtext->ecxt_innertuple;
00729 break;
00730
00731 case OUTER_VAR:
00732 slot = econtext->ecxt_outertuple;
00733 break;
00734
00735
00736
00737 default:
00738
00739 slot = econtext->ecxt_scantuple;
00740 break;
00741 }
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755 if (wrvstate->parent)
00756 {
00757 PlanState *subplan = NULL;
00758
00759 switch (nodeTag(wrvstate->parent))
00760 {
00761 case T_SubqueryScanState:
00762 subplan = ((SubqueryScanState *) wrvstate->parent)->subplan;
00763 break;
00764 case T_CteScanState:
00765 subplan = ((CteScanState *) wrvstate->parent)->cteplanstate;
00766 break;
00767 default:
00768 break;
00769 }
00770
00771 if (subplan)
00772 {
00773 bool junk_filter_needed = false;
00774 ListCell *tlist;
00775
00776
00777 foreach(tlist, subplan->plan->targetlist)
00778 {
00779 TargetEntry *tle = (TargetEntry *) lfirst(tlist);
00780
00781 if (tle->resjunk)
00782 {
00783 junk_filter_needed = true;
00784 break;
00785 }
00786 }
00787
00788
00789 if (junk_filter_needed)
00790 {
00791 MemoryContext oldcontext;
00792
00793 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
00794 wrvstate->wrv_junkFilter =
00795 ExecInitJunkFilter(subplan->plan->targetlist,
00796 ExecGetResultType(subplan)->tdhasoid,
00797 ExecInitExtraTupleSlot(wrvstate->parent->state));
00798 MemoryContextSwitchTo(oldcontext);
00799 }
00800 }
00801 }
00802
00803
00804 if (wrvstate->wrv_junkFilter != NULL)
00805 slot = ExecFilterJunk(wrvstate->wrv_junkFilter, slot);
00806
00807 slot_tupdesc = slot->tts_tupleDescriptor;
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817 if (variable->vartype == RECORDOID)
00818 {
00819 if (slot_tupdesc->tdtypeid == RECORDOID &&
00820 slot_tupdesc->tdtypmod < 0)
00821 assign_record_type_typmod(slot_tupdesc);
00822 }
00823 else
00824 {
00825 TupleDesc var_tupdesc;
00826 int i;
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840 var_tupdesc = lookup_rowtype_tupdesc(variable->vartype, -1);
00841
00842 if (var_tupdesc->natts != slot_tupdesc->natts)
00843 ereport(ERROR,
00844 (errcode(ERRCODE_DATATYPE_MISMATCH),
00845 errmsg("table row type and query-specified row type do not match"),
00846 errdetail_plural("Table row contains %d attribute, but query expects %d.",
00847 "Table row contains %d attributes, but query expects %d.",
00848 slot_tupdesc->natts,
00849 slot_tupdesc->natts,
00850 var_tupdesc->natts)));
00851
00852 for (i = 0; i < var_tupdesc->natts; i++)
00853 {
00854 Form_pg_attribute vattr = var_tupdesc->attrs[i];
00855 Form_pg_attribute sattr = slot_tupdesc->attrs[i];
00856
00857 if (vattr->atttypid == sattr->atttypid)
00858 continue;
00859 if (!vattr->attisdropped)
00860 ereport(ERROR,
00861 (errcode(ERRCODE_DATATYPE_MISMATCH),
00862 errmsg("table row type and query-specified row type do not match"),
00863 errdetail("Table has type %s at ordinal position %d, but query expects %s.",
00864 format_type_be(sattr->atttypid),
00865 i + 1,
00866 format_type_be(vattr->atttypid))));
00867
00868 if (vattr->attlen != sattr->attlen ||
00869 vattr->attalign != sattr->attalign)
00870 needslow = true;
00871 }
00872
00873 ReleaseTupleDesc(var_tupdesc);
00874 }
00875
00876
00877 if (needslow)
00878 wrvstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalWholeRowSlow;
00879 else
00880 wrvstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalWholeRowFast;
00881
00882
00883 return (*wrvstate->xprstate.evalfunc) ((ExprState *) wrvstate, econtext,
00884 isNull, isDone);
00885 }
00886
00887
00888
00889
00890
00891
00892
00893 static Datum
00894 ExecEvalWholeRowFast(WholeRowVarExprState *wrvstate, ExprContext *econtext,
00895 bool *isNull, ExprDoneCond *isDone)
00896 {
00897 Var *variable = (Var *) wrvstate->xprstate.expr;
00898 TupleTableSlot *slot;
00899 HeapTuple tuple;
00900 TupleDesc tupleDesc;
00901 HeapTupleHeader dtuple;
00902
00903 if (isDone)
00904 *isDone = ExprSingleResult;
00905 *isNull = false;
00906
00907
00908 switch (variable->varno)
00909 {
00910 case INNER_VAR:
00911 slot = econtext->ecxt_innertuple;
00912 break;
00913
00914 case OUTER_VAR:
00915 slot = econtext->ecxt_outertuple;
00916 break;
00917
00918
00919
00920 default:
00921
00922 slot = econtext->ecxt_scantuple;
00923 break;
00924 }
00925
00926
00927 if (wrvstate->wrv_junkFilter != NULL)
00928 slot = ExecFilterJunk(wrvstate->wrv_junkFilter, slot);
00929
00930 tuple = ExecFetchSlotTuple(slot);
00931 tupleDesc = slot->tts_tupleDescriptor;
00932
00933
00934
00935
00936
00937 dtuple = (HeapTupleHeader) palloc(tuple->t_len);
00938 memcpy((char *) dtuple, (char *) tuple->t_data, tuple->t_len);
00939
00940 HeapTupleHeaderSetDatumLength(dtuple, tuple->t_len);
00941
00942
00943
00944
00945
00946 if (variable->vartype != RECORDOID)
00947 {
00948 HeapTupleHeaderSetTypeId(dtuple, variable->vartype);
00949 HeapTupleHeaderSetTypMod(dtuple, variable->vartypmod);
00950 }
00951 else
00952 {
00953 HeapTupleHeaderSetTypeId(dtuple, tupleDesc->tdtypeid);
00954 HeapTupleHeaderSetTypMod(dtuple, tupleDesc->tdtypmod);
00955 }
00956
00957 return PointerGetDatum(dtuple);
00958 }
00959
00960
00961
00962
00963
00964
00965
00966
00967 static Datum
00968 ExecEvalWholeRowSlow(WholeRowVarExprState *wrvstate, ExprContext *econtext,
00969 bool *isNull, ExprDoneCond *isDone)
00970 {
00971 Var *variable = (Var *) wrvstate->xprstate.expr;
00972 TupleTableSlot *slot;
00973 HeapTuple tuple;
00974 TupleDesc tupleDesc;
00975 TupleDesc var_tupdesc;
00976 HeapTupleHeader dtuple;
00977 int i;
00978
00979 if (isDone)
00980 *isDone = ExprSingleResult;
00981 *isNull = false;
00982
00983
00984 switch (variable->varno)
00985 {
00986 case INNER_VAR:
00987 slot = econtext->ecxt_innertuple;
00988 break;
00989
00990 case OUTER_VAR:
00991 slot = econtext->ecxt_outertuple;
00992 break;
00993
00994
00995
00996 default:
00997
00998 slot = econtext->ecxt_scantuple;
00999 break;
01000 }
01001
01002
01003 if (wrvstate->wrv_junkFilter != NULL)
01004 slot = ExecFilterJunk(wrvstate->wrv_junkFilter, slot);
01005
01006 tuple = ExecFetchSlotTuple(slot);
01007 tupleDesc = slot->tts_tupleDescriptor;
01008
01009 Assert(variable->vartype != RECORDOID);
01010 var_tupdesc = lookup_rowtype_tupdesc(variable->vartype, -1);
01011
01012
01013 for (i = 0; i < var_tupdesc->natts; i++)
01014 {
01015 Form_pg_attribute vattr = var_tupdesc->attrs[i];
01016 Form_pg_attribute sattr = tupleDesc->attrs[i];
01017
01018 if (!vattr->attisdropped)
01019 continue;
01020 if (heap_attisnull(tuple, i + 1))
01021 continue;
01022 if (vattr->attlen != sattr->attlen ||
01023 vattr->attalign != sattr->attalign)
01024 ereport(ERROR,
01025 (errcode(ERRCODE_DATATYPE_MISMATCH),
01026 errmsg("table row type and query-specified row type do not match"),
01027 errdetail("Physical storage mismatch on dropped attribute at ordinal position %d.",
01028 i + 1)));
01029 }
01030
01031
01032
01033
01034
01035 dtuple = (HeapTupleHeader) palloc(tuple->t_len);
01036 memcpy((char *) dtuple, (char *) tuple->t_data, tuple->t_len);
01037
01038 HeapTupleHeaderSetDatumLength(dtuple, tuple->t_len);
01039 HeapTupleHeaderSetTypeId(dtuple, variable->vartype);
01040 HeapTupleHeaderSetTypMod(dtuple, variable->vartypmod);
01041
01042 ReleaseTupleDesc(var_tupdesc);
01043
01044 return PointerGetDatum(dtuple);
01045 }
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057 static Datum
01058 ExecEvalConst(ExprState *exprstate, ExprContext *econtext,
01059 bool *isNull, ExprDoneCond *isDone)
01060 {
01061 Const *con = (Const *) exprstate->expr;
01062
01063 if (isDone)
01064 *isDone = ExprSingleResult;
01065
01066 *isNull = con->constisnull;
01067 return con->constvalue;
01068 }
01069
01070
01071
01072
01073
01074
01075
01076 static Datum
01077 ExecEvalParamExec(ExprState *exprstate, ExprContext *econtext,
01078 bool *isNull, ExprDoneCond *isDone)
01079 {
01080 Param *expression = (Param *) exprstate->expr;
01081 int thisParamId = expression->paramid;
01082 ParamExecData *prm;
01083
01084 if (isDone)
01085 *isDone = ExprSingleResult;
01086
01087
01088
01089
01090
01091 prm = &(econtext->ecxt_param_exec_vals[thisParamId]);
01092 if (prm->execPlan != NULL)
01093 {
01094
01095 ExecSetParamPlan(prm->execPlan, econtext);
01096
01097 Assert(prm->execPlan == NULL);
01098 }
01099 *isNull = prm->isnull;
01100 return prm->value;
01101 }
01102
01103
01104
01105
01106
01107
01108
01109 static Datum
01110 ExecEvalParamExtern(ExprState *exprstate, ExprContext *econtext,
01111 bool *isNull, ExprDoneCond *isDone)
01112 {
01113 Param *expression = (Param *) exprstate->expr;
01114 int thisParamId = expression->paramid;
01115 ParamListInfo paramInfo = econtext->ecxt_param_list_info;
01116
01117 if (isDone)
01118 *isDone = ExprSingleResult;
01119
01120
01121
01122
01123 if (paramInfo &&
01124 thisParamId > 0 && thisParamId <= paramInfo->numParams)
01125 {
01126 ParamExternData *prm = ¶mInfo->params[thisParamId - 1];
01127
01128
01129 if (!OidIsValid(prm->ptype) && paramInfo->paramFetch != NULL)
01130 (*paramInfo->paramFetch) (paramInfo, thisParamId);
01131
01132 if (OidIsValid(prm->ptype))
01133 {
01134
01135 if (prm->ptype != expression->paramtype)
01136 ereport(ERROR,
01137 (errcode(ERRCODE_DATATYPE_MISMATCH),
01138 errmsg("type of parameter %d (%s) does not match that when preparing the plan (%s)",
01139 thisParamId,
01140 format_type_be(prm->ptype),
01141 format_type_be(expression->paramtype))));
01142
01143 *isNull = prm->isnull;
01144 return prm->value;
01145 }
01146 }
01147
01148 ereport(ERROR,
01149 (errcode(ERRCODE_UNDEFINED_OBJECT),
01150 errmsg("no value found for parameter %d", thisParamId)));
01151 return (Datum) 0;
01152 }
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171 Datum
01172 GetAttributeByNum(HeapTupleHeader tuple,
01173 AttrNumber attrno,
01174 bool *isNull)
01175 {
01176 Datum result;
01177 Oid tupType;
01178 int32 tupTypmod;
01179 TupleDesc tupDesc;
01180 HeapTupleData tmptup;
01181
01182 if (!AttributeNumberIsValid(attrno))
01183 elog(ERROR, "invalid attribute number %d", attrno);
01184
01185 if (isNull == NULL)
01186 elog(ERROR, "a NULL isNull pointer was passed");
01187
01188 if (tuple == NULL)
01189 {
01190
01191 *isNull = true;
01192 return (Datum) 0;
01193 }
01194
01195 tupType = HeapTupleHeaderGetTypeId(tuple);
01196 tupTypmod = HeapTupleHeaderGetTypMod(tuple);
01197 tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
01198
01199
01200
01201
01202
01203
01204 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
01205 ItemPointerSetInvalid(&(tmptup.t_self));
01206 tmptup.t_tableOid = InvalidOid;
01207 tmptup.t_data = tuple;
01208
01209 result = heap_getattr(&tmptup,
01210 attrno,
01211 tupDesc,
01212 isNull);
01213
01214 ReleaseTupleDesc(tupDesc);
01215
01216 return result;
01217 }
01218
01219 Datum
01220 GetAttributeByName(HeapTupleHeader tuple, const char *attname, bool *isNull)
01221 {
01222 AttrNumber attrno;
01223 Datum result;
01224 Oid tupType;
01225 int32 tupTypmod;
01226 TupleDesc tupDesc;
01227 HeapTupleData tmptup;
01228 int i;
01229
01230 if (attname == NULL)
01231 elog(ERROR, "invalid attribute name");
01232
01233 if (isNull == NULL)
01234 elog(ERROR, "a NULL isNull pointer was passed");
01235
01236 if (tuple == NULL)
01237 {
01238
01239 *isNull = true;
01240 return (Datum) 0;
01241 }
01242
01243 tupType = HeapTupleHeaderGetTypeId(tuple);
01244 tupTypmod = HeapTupleHeaderGetTypMod(tuple);
01245 tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
01246
01247 attrno = InvalidAttrNumber;
01248 for (i = 0; i < tupDesc->natts; i++)
01249 {
01250 if (namestrcmp(&(tupDesc->attrs[i]->attname), attname) == 0)
01251 {
01252 attrno = tupDesc->attrs[i]->attnum;
01253 break;
01254 }
01255 }
01256
01257 if (attrno == InvalidAttrNumber)
01258 elog(ERROR, "attribute \"%s\" does not exist", attname);
01259
01260
01261
01262
01263
01264
01265 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
01266 ItemPointerSetInvalid(&(tmptup.t_self));
01267 tmptup.t_tableOid = InvalidOid;
01268 tmptup.t_data = tuple;
01269
01270 result = heap_getattr(&tmptup,
01271 attrno,
01272 tupDesc,
01273 isNull);
01274
01275 ReleaseTupleDesc(tupDesc);
01276
01277 return result;
01278 }
01279
01280
01281
01282
01283 static void
01284 init_fcache(Oid foid, Oid input_collation, FuncExprState *fcache,
01285 MemoryContext fcacheCxt, bool needDescForSets)
01286 {
01287 AclResult aclresult;
01288
01289
01290 aclresult = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE);
01291 if (aclresult != ACLCHECK_OK)
01292 aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(foid));
01293 InvokeFunctionExecuteHook(foid);
01294
01295
01296
01297
01298
01299
01300
01301 if (list_length(fcache->args) > FUNC_MAX_ARGS)
01302 ereport(ERROR,
01303 (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
01304 errmsg_plural("cannot pass more than %d argument to a function",
01305 "cannot pass more than %d arguments to a function",
01306 FUNC_MAX_ARGS,
01307 FUNC_MAX_ARGS)));
01308
01309
01310 fmgr_info_cxt(foid, &(fcache->func), fcacheCxt);
01311 fmgr_info_set_expr((Node *) fcache->xprstate.expr, &(fcache->func));
01312
01313
01314 InitFunctionCallInfoData(fcache->fcinfo_data, &(fcache->func),
01315 list_length(fcache->args),
01316 input_collation, NULL, NULL);
01317
01318
01319 if (fcache->func.fn_retset && needDescForSets)
01320 {
01321 TypeFuncClass functypclass;
01322 Oid funcrettype;
01323 TupleDesc tupdesc;
01324 MemoryContext oldcontext;
01325
01326 functypclass = get_expr_result_type(fcache->func.fn_expr,
01327 &funcrettype,
01328 &tupdesc);
01329
01330
01331 oldcontext = MemoryContextSwitchTo(fcacheCxt);
01332
01333 if (functypclass == TYPEFUNC_COMPOSITE)
01334 {
01335
01336 Assert(tupdesc);
01337
01338 fcache->funcResultDesc = CreateTupleDescCopy(tupdesc);
01339 fcache->funcReturnsTuple = true;
01340 }
01341 else if (functypclass == TYPEFUNC_SCALAR)
01342 {
01343
01344 tupdesc = CreateTemplateTupleDesc(1, false);
01345 TupleDescInitEntry(tupdesc,
01346 (AttrNumber) 1,
01347 NULL,
01348 funcrettype,
01349 -1,
01350 0);
01351 fcache->funcResultDesc = tupdesc;
01352 fcache->funcReturnsTuple = false;
01353 }
01354 else if (functypclass == TYPEFUNC_RECORD)
01355 {
01356
01357 fcache->funcResultDesc = NULL;
01358 fcache->funcReturnsTuple = true;
01359 }
01360 else
01361 {
01362
01363 fcache->funcResultDesc = NULL;
01364 }
01365
01366 MemoryContextSwitchTo(oldcontext);
01367 }
01368 else
01369 fcache->funcResultDesc = NULL;
01370
01371
01372 fcache->funcResultStore = NULL;
01373 fcache->funcResultSlot = NULL;
01374 fcache->setArgsValid = false;
01375 fcache->shutdown_reg = false;
01376 }
01377
01378
01379
01380
01381
01382 static void
01383 ShutdownFuncExpr(Datum arg)
01384 {
01385 FuncExprState *fcache = (FuncExprState *) DatumGetPointer(arg);
01386
01387
01388 if (fcache->funcResultSlot)
01389 ExecClearTuple(fcache->funcResultSlot);
01390
01391
01392 if (fcache->funcResultStore)
01393 tuplestore_end(fcache->funcResultStore);
01394 fcache->funcResultStore = NULL;
01395
01396
01397 fcache->setArgsValid = false;
01398
01399
01400 fcache->shutdown_reg = false;
01401 }
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415 static TupleDesc
01416 get_cached_rowtype(Oid type_id, int32 typmod,
01417 TupleDesc *cache_field, ExprContext *econtext)
01418 {
01419 TupleDesc tupDesc = *cache_field;
01420
01421
01422 if (tupDesc == NULL ||
01423 type_id != tupDesc->tdtypeid ||
01424 typmod != tupDesc->tdtypmod)
01425 {
01426 tupDesc = lookup_rowtype_tupdesc(type_id, typmod);
01427
01428 if (*cache_field)
01429 {
01430
01431 ReleaseTupleDesc(*cache_field);
01432 }
01433 else
01434 {
01435
01436 RegisterExprContextCallback(econtext,
01437 ShutdownTupleDescRef,
01438 PointerGetDatum(cache_field));
01439 }
01440 *cache_field = tupDesc;
01441 }
01442 return tupDesc;
01443 }
01444
01445
01446
01447
01448 static void
01449 ShutdownTupleDescRef(Datum arg)
01450 {
01451 TupleDesc *cache_field = (TupleDesc *) DatumGetPointer(arg);
01452
01453 if (*cache_field)
01454 ReleaseTupleDesc(*cache_field);
01455 *cache_field = NULL;
01456 }
01457
01458
01459
01460
01461 static ExprDoneCond
01462 ExecEvalFuncArgs(FunctionCallInfo fcinfo,
01463 List *argList,
01464 ExprContext *econtext)
01465 {
01466 ExprDoneCond argIsDone;
01467 int i;
01468 ListCell *arg;
01469
01470 argIsDone = ExprSingleResult;
01471
01472 i = 0;
01473 foreach(arg, argList)
01474 {
01475 ExprState *argstate = (ExprState *) lfirst(arg);
01476 ExprDoneCond thisArgIsDone;
01477
01478 fcinfo->arg[i] = ExecEvalExpr(argstate,
01479 econtext,
01480 &fcinfo->argnull[i],
01481 &thisArgIsDone);
01482
01483 if (thisArgIsDone != ExprSingleResult)
01484 {
01485
01486
01487
01488
01489
01490 if (argIsDone != ExprSingleResult)
01491 ereport(ERROR,
01492 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
01493 errmsg("functions and operators can take at most one set argument")));
01494 argIsDone = thisArgIsDone;
01495 }
01496 i++;
01497 }
01498
01499 Assert(i == fcinfo->nargs);
01500
01501 return argIsDone;
01502 }
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512 static void
01513 ExecPrepareTuplestoreResult(FuncExprState *fcache,
01514 ExprContext *econtext,
01515 Tuplestorestate *resultStore,
01516 TupleDesc resultDesc)
01517 {
01518 fcache->funcResultStore = resultStore;
01519
01520 if (fcache->funcResultSlot == NULL)
01521 {
01522
01523 TupleDesc slotDesc;
01524 MemoryContext oldcontext;
01525
01526 oldcontext = MemoryContextSwitchTo(fcache->func.fn_mcxt);
01527
01528
01529
01530
01531
01532 if (fcache->funcResultDesc)
01533 slotDesc = fcache->funcResultDesc;
01534 else if (resultDesc)
01535 {
01536
01537 slotDesc = CreateTupleDescCopy(resultDesc);
01538 }
01539 else
01540 {
01541 ereport(ERROR,
01542 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
01543 errmsg("function returning setof record called in "
01544 "context that cannot accept type record")));
01545 slotDesc = NULL;
01546 }
01547
01548 fcache->funcResultSlot = MakeSingleTupleTableSlot(slotDesc);
01549 MemoryContextSwitchTo(oldcontext);
01550 }
01551
01552
01553
01554
01555
01556 if (resultDesc)
01557 {
01558 if (fcache->funcResultDesc)
01559 tupledesc_match(fcache->funcResultDesc, resultDesc);
01560
01561
01562
01563
01564
01565
01566 if (resultDesc->tdrefcount == -1)
01567 FreeTupleDesc(resultDesc);
01568 }
01569
01570
01571 if (!fcache->shutdown_reg)
01572 {
01573 RegisterExprContextCallback(econtext,
01574 ShutdownFuncExpr,
01575 PointerGetDatum(fcache));
01576 fcache->shutdown_reg = true;
01577 }
01578 }
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590 static void
01591 tupledesc_match(TupleDesc dst_tupdesc, TupleDesc src_tupdesc)
01592 {
01593 int i;
01594
01595 if (dst_tupdesc->natts != src_tupdesc->natts)
01596 ereport(ERROR,
01597 (errcode(ERRCODE_DATATYPE_MISMATCH),
01598 errmsg("function return row and query-specified return row do not match"),
01599 errdetail_plural("Returned row contains %d attribute, but query expects %d.",
01600 "Returned row contains %d attributes, but query expects %d.",
01601 src_tupdesc->natts,
01602 src_tupdesc->natts, dst_tupdesc->natts)));
01603
01604 for (i = 0; i < dst_tupdesc->natts; i++)
01605 {
01606 Form_pg_attribute dattr = dst_tupdesc->attrs[i];
01607 Form_pg_attribute sattr = src_tupdesc->attrs[i];
01608
01609 if (IsBinaryCoercible(sattr->atttypid, dattr->atttypid))
01610 continue;
01611 if (!dattr->attisdropped)
01612 ereport(ERROR,
01613 (errcode(ERRCODE_DATATYPE_MISMATCH),
01614 errmsg("function return row and query-specified return row do not match"),
01615 errdetail("Returned type %s at ordinal position %d, but query expects %s.",
01616 format_type_be(sattr->atttypid),
01617 i + 1,
01618 format_type_be(dattr->atttypid))));
01619
01620 if (dattr->attlen != sattr->attlen ||
01621 dattr->attalign != sattr->attalign)
01622 ereport(ERROR,
01623 (errcode(ERRCODE_DATATYPE_MISMATCH),
01624 errmsg("function return row and query-specified return row do not match"),
01625 errdetail("Physical storage mismatch on dropped attribute at ordinal position %d.",
01626 i + 1)));
01627 }
01628 }
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641 static Datum
01642 ExecMakeFunctionResult(FuncExprState *fcache,
01643 ExprContext *econtext,
01644 bool *isNull,
01645 ExprDoneCond *isDone)
01646 {
01647 List *arguments;
01648 Datum result;
01649 FunctionCallInfo fcinfo;
01650 PgStat_FunctionCallUsage fcusage;
01651 ReturnSetInfo rsinfo;
01652 ExprDoneCond argDone;
01653 bool hasSetArg;
01654 int i;
01655
01656 restart:
01657
01658
01659 check_stack_depth();
01660
01661
01662
01663
01664
01665
01666 if (fcache->funcResultStore)
01667 {
01668 Assert(isDone);
01669 if (tuplestore_gettupleslot(fcache->funcResultStore, true, false,
01670 fcache->funcResultSlot))
01671 {
01672 *isDone = ExprMultipleResult;
01673 if (fcache->funcReturnsTuple)
01674 {
01675
01676 *isNull = false;
01677 return ExecFetchSlotTupleDatum(fcache->funcResultSlot);
01678 }
01679 else
01680 {
01681
01682 return slot_getattr(fcache->funcResultSlot, 1, isNull);
01683 }
01684 }
01685
01686 tuplestore_end(fcache->funcResultStore);
01687 fcache->funcResultStore = NULL;
01688
01689 if (!fcache->setHasSetArg)
01690 {
01691 *isDone = ExprEndResult;
01692 *isNull = true;
01693 return (Datum) 0;
01694 }
01695
01696 Assert(!fcache->setArgsValid);
01697 }
01698
01699
01700
01701
01702
01703
01704
01705 fcinfo = &fcache->fcinfo_data;
01706 arguments = fcache->args;
01707 if (!fcache->setArgsValid)
01708 {
01709 argDone = ExecEvalFuncArgs(fcinfo, arguments, econtext);
01710 if (argDone == ExprEndResult)
01711 {
01712
01713 *isNull = true;
01714 if (isDone)
01715 *isDone = ExprEndResult;
01716 else
01717 ereport(ERROR,
01718 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
01719 errmsg("set-valued function called in context that cannot accept a set")));
01720 return (Datum) 0;
01721 }
01722 hasSetArg = (argDone != ExprSingleResult);
01723 }
01724 else
01725 {
01726
01727 hasSetArg = fcache->setHasSetArg;
01728
01729 fcache->setArgsValid = false;
01730 }
01731
01732
01733
01734
01735 if (fcache->func.fn_retset || hasSetArg)
01736 {
01737
01738
01739
01740
01741 if (isDone == NULL)
01742 ereport(ERROR,
01743 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
01744 errmsg("set-valued function called in context that cannot accept a set")));
01745
01746
01747
01748
01749
01750
01751 if (fcache->func.fn_retset)
01752 fcinfo->resultinfo = (Node *) &rsinfo;
01753 rsinfo.type = T_ReturnSetInfo;
01754 rsinfo.econtext = econtext;
01755 rsinfo.expectedDesc = fcache->funcResultDesc;
01756 rsinfo.allowedModes = (int) (SFRM_ValuePerCall | SFRM_Materialize);
01757
01758 rsinfo.returnMode = SFRM_ValuePerCall;
01759
01760 rsinfo.setResult = NULL;
01761 rsinfo.setDesc = NULL;
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771 for (;;)
01772 {
01773
01774
01775
01776
01777 bool callit = true;
01778
01779 if (fcache->func.fn_strict)
01780 {
01781 for (i = 0; i < fcinfo->nargs; i++)
01782 {
01783 if (fcinfo->argnull[i])
01784 {
01785 callit = false;
01786 break;
01787 }
01788 }
01789 }
01790
01791 if (callit)
01792 {
01793 pgstat_init_function_usage(fcinfo, &fcusage);
01794
01795 fcinfo->isnull = false;
01796 rsinfo.isDone = ExprSingleResult;
01797 result = FunctionCallInvoke(fcinfo);
01798 *isNull = fcinfo->isnull;
01799 *isDone = rsinfo.isDone;
01800
01801 pgstat_end_function_usage(&fcusage,
01802 rsinfo.isDone != ExprMultipleResult);
01803 }
01804 else
01805 {
01806 result = (Datum) 0;
01807 *isNull = true;
01808 *isDone = ExprEndResult;
01809 }
01810
01811
01812 if (rsinfo.returnMode == SFRM_ValuePerCall)
01813 {
01814 if (*isDone != ExprEndResult)
01815 {
01816
01817
01818
01819
01820
01821 if (fcache->func.fn_retset &&
01822 *isDone == ExprMultipleResult)
01823 {
01824 fcache->setHasSetArg = hasSetArg;
01825 fcache->setArgsValid = true;
01826
01827 if (!fcache->shutdown_reg)
01828 {
01829 RegisterExprContextCallback(econtext,
01830 ShutdownFuncExpr,
01831 PointerGetDatum(fcache));
01832 fcache->shutdown_reg = true;
01833 }
01834 }
01835
01836
01837
01838
01839
01840 if (hasSetArg)
01841 *isDone = ExprMultipleResult;
01842 break;
01843 }
01844 }
01845 else if (rsinfo.returnMode == SFRM_Materialize)
01846 {
01847
01848 if (rsinfo.isDone != ExprSingleResult)
01849 ereport(ERROR,
01850 (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
01851 errmsg("table-function protocol for materialize mode was not followed")));
01852 if (rsinfo.setResult != NULL)
01853 {
01854
01855 ExecPrepareTuplestoreResult(fcache, econtext,
01856 rsinfo.setResult,
01857 rsinfo.setDesc);
01858
01859 fcache->setHasSetArg = hasSetArg;
01860
01861 goto restart;
01862 }
01863
01864 *isDone = ExprEndResult;
01865 *isNull = true;
01866 result = (Datum) 0;
01867 }
01868 else
01869 ereport(ERROR,
01870 (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
01871 errmsg("unrecognized table-function returnMode: %d",
01872 (int) rsinfo.returnMode)));
01873
01874
01875 if (!hasSetArg)
01876 break;
01877
01878
01879 argDone = ExecEvalFuncArgs(fcinfo, arguments, econtext);
01880
01881 if (argDone != ExprMultipleResult)
01882 {
01883
01884 *isNull = true;
01885 *isDone = ExprEndResult;
01886 result = (Datum) 0;
01887 break;
01888 }
01889
01890
01891
01892
01893
01894 }
01895 }
01896 else
01897 {
01898
01899
01900
01901
01902
01903
01904
01905
01906 fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResultNoSets;
01907
01908 if (isDone)
01909 *isDone = ExprSingleResult;
01910
01911
01912
01913
01914
01915 if (fcache->func.fn_strict)
01916 {
01917 for (i = 0; i < fcinfo->nargs; i++)
01918 {
01919 if (fcinfo->argnull[i])
01920 {
01921 *isNull = true;
01922 return (Datum) 0;
01923 }
01924 }
01925 }
01926
01927 pgstat_init_function_usage(fcinfo, &fcusage);
01928
01929 fcinfo->isnull = false;
01930 result = FunctionCallInvoke(fcinfo);
01931 *isNull = fcinfo->isnull;
01932
01933 pgstat_end_function_usage(&fcusage, true);
01934 }
01935
01936 return result;
01937 }
01938
01939
01940
01941
01942
01943
01944
01945 static Datum
01946 ExecMakeFunctionResultNoSets(FuncExprState *fcache,
01947 ExprContext *econtext,
01948 bool *isNull,
01949 ExprDoneCond *isDone)
01950 {
01951 ListCell *arg;
01952 Datum result;
01953 FunctionCallInfo fcinfo;
01954 PgStat_FunctionCallUsage fcusage;
01955 int i;
01956
01957
01958 check_stack_depth();
01959
01960 if (isDone)
01961 *isDone = ExprSingleResult;
01962
01963
01964 fcinfo = &fcache->fcinfo_data;
01965 i = 0;
01966 foreach(arg, fcache->args)
01967 {
01968 ExprState *argstate = (ExprState *) lfirst(arg);
01969
01970 fcinfo->arg[i] = ExecEvalExpr(argstate,
01971 econtext,
01972 &fcinfo->argnull[i],
01973 NULL);
01974 i++;
01975 }
01976
01977
01978
01979
01980
01981 if (fcache->func.fn_strict)
01982 {
01983 while (--i >= 0)
01984 {
01985 if (fcinfo->argnull[i])
01986 {
01987 *isNull = true;
01988 return (Datum) 0;
01989 }
01990 }
01991 }
01992
01993 pgstat_init_function_usage(fcinfo, &fcusage);
01994
01995 fcinfo->isnull = false;
01996 result = FunctionCallInvoke(fcinfo);
01997 *isNull = fcinfo->isnull;
01998
01999 pgstat_end_function_usage(&fcusage, true);
02000
02001 return result;
02002 }
02003
02004
02005
02006
02007
02008
02009
02010
02011 Tuplestorestate *
02012 ExecMakeTableFunctionResult(ExprState *funcexpr,
02013 ExprContext *econtext,
02014 TupleDesc expectedDesc,
02015 bool randomAccess)
02016 {
02017 Tuplestorestate *tupstore = NULL;
02018 TupleDesc tupdesc = NULL;
02019 Oid funcrettype;
02020 bool returnsTuple;
02021 bool returnsSet = false;
02022 FunctionCallInfoData fcinfo;
02023 PgStat_FunctionCallUsage fcusage;
02024 ReturnSetInfo rsinfo;
02025 HeapTupleData tmptup;
02026 MemoryContext callerContext;
02027 MemoryContext oldcontext;
02028 bool direct_function_call;
02029 bool first_time = true;
02030
02031 callerContext = CurrentMemoryContext;
02032
02033 funcrettype = exprType((Node *) funcexpr->expr);
02034
02035 returnsTuple = type_is_rowtype(funcrettype);
02036
02037
02038
02039
02040
02041
02042
02043
02044 rsinfo.type = T_ReturnSetInfo;
02045 rsinfo.econtext = econtext;
02046 rsinfo.expectedDesc = expectedDesc;
02047 rsinfo.allowedModes = (int) (SFRM_ValuePerCall | SFRM_Materialize | SFRM_Materialize_Preferred);
02048 if (randomAccess)
02049 rsinfo.allowedModes |= (int) SFRM_Materialize_Random;
02050 rsinfo.returnMode = SFRM_ValuePerCall;
02051
02052 rsinfo.setResult = NULL;
02053 rsinfo.setDesc = NULL;
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065 if (funcexpr && IsA(funcexpr, FuncExprState) &&
02066 IsA(funcexpr->expr, FuncExpr))
02067 {
02068 FuncExprState *fcache = (FuncExprState *) funcexpr;
02069 ExprDoneCond argDone;
02070
02071
02072
02073
02074 direct_function_call = true;
02075
02076
02077
02078
02079 if (fcache->func.fn_oid == InvalidOid)
02080 {
02081 FuncExpr *func = (FuncExpr *) fcache->xprstate.expr;
02082
02083 init_fcache(func->funcid, func->inputcollid, fcache,
02084 econtext->ecxt_per_query_memory, false);
02085 }
02086 returnsSet = fcache->func.fn_retset;
02087 InitFunctionCallInfoData(fcinfo, &(fcache->func),
02088 list_length(fcache->args),
02089 fcache->fcinfo_data.fncollation,
02090 NULL, (Node *) &rsinfo);
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100 argDone = ExecEvalFuncArgs(&fcinfo, fcache->args, econtext);
02101
02102 if (argDone != ExprSingleResult)
02103 ereport(ERROR,
02104 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02105 errmsg("set-valued function called in context that cannot accept a set")));
02106
02107
02108
02109
02110
02111
02112 if (fcache->func.fn_strict)
02113 {
02114 int i;
02115
02116 for (i = 0; i < fcinfo.nargs; i++)
02117 {
02118 if (fcinfo.argnull[i])
02119 goto no_function_result;
02120 }
02121 }
02122 }
02123 else
02124 {
02125
02126 direct_function_call = false;
02127 InitFunctionCallInfoData(fcinfo, NULL, 0, InvalidOid, NULL, NULL);
02128 }
02129
02130
02131
02132
02133 MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
02134
02135
02136
02137
02138
02139 for (;;)
02140 {
02141 Datum result;
02142
02143 CHECK_FOR_INTERRUPTS();
02144
02145
02146
02147
02148
02149
02150 ResetExprContext(econtext);
02151
02152
02153 if (direct_function_call)
02154 {
02155 pgstat_init_function_usage(&fcinfo, &fcusage);
02156
02157 fcinfo.isnull = false;
02158 rsinfo.isDone = ExprSingleResult;
02159 result = FunctionCallInvoke(&fcinfo);
02160
02161 pgstat_end_function_usage(&fcusage,
02162 rsinfo.isDone != ExprMultipleResult);
02163 }
02164 else
02165 {
02166 result = ExecEvalExpr(funcexpr, econtext,
02167 &fcinfo.isnull, &rsinfo.isDone);
02168 }
02169
02170
02171 if (rsinfo.returnMode == SFRM_ValuePerCall)
02172 {
02173
02174
02175
02176 if (rsinfo.isDone == ExprEndResult)
02177 break;
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187 if (returnsTuple && fcinfo.isnull)
02188 {
02189 if (!returnsSet)
02190 break;
02191 ereport(ERROR,
02192 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
02193 errmsg("function returning set of rows cannot return null value")));
02194 }
02195
02196
02197
02198
02199 if (first_time)
02200 {
02201 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
02202 if (returnsTuple)
02203 {
02204
02205
02206
02207
02208 HeapTupleHeader td;
02209
02210 td = DatumGetHeapTupleHeader(result);
02211 tupdesc = lookup_rowtype_tupdesc_copy(HeapTupleHeaderGetTypeId(td),
02212 HeapTupleHeaderGetTypMod(td));
02213 }
02214 else
02215 {
02216
02217
02218
02219 tupdesc = CreateTemplateTupleDesc(1, false);
02220 TupleDescInitEntry(tupdesc,
02221 (AttrNumber) 1,
02222 "column",
02223 funcrettype,
02224 -1,
02225 0);
02226 }
02227 tupstore = tuplestore_begin_heap(randomAccess, false, work_mem);
02228 MemoryContextSwitchTo(oldcontext);
02229 rsinfo.setResult = tupstore;
02230 rsinfo.setDesc = tupdesc;
02231 }
02232
02233
02234
02235
02236 if (returnsTuple)
02237 {
02238 HeapTupleHeader td;
02239
02240 td = DatumGetHeapTupleHeader(result);
02241
02242
02243
02244
02245
02246 if (HeapTupleHeaderGetTypeId(td) != tupdesc->tdtypeid ||
02247 HeapTupleHeaderGetTypMod(td) != tupdesc->tdtypmod)
02248 ereport(ERROR,
02249 (errcode(ERRCODE_DATATYPE_MISMATCH),
02250 errmsg("rows returned by function are not all of the same row type")));
02251
02252
02253
02254
02255
02256 tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
02257 tmptup.t_data = td;
02258
02259 tuplestore_puttuple(tupstore, &tmptup);
02260 }
02261 else
02262 tuplestore_putvalues(tupstore, tupdesc, &result, &fcinfo.isnull);
02263
02264
02265
02266
02267 if (rsinfo.isDone != ExprMultipleResult)
02268 break;
02269 }
02270 else if (rsinfo.returnMode == SFRM_Materialize)
02271 {
02272
02273 if (!first_time || rsinfo.isDone != ExprSingleResult)
02274 ereport(ERROR,
02275 (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
02276 errmsg("table-function protocol for materialize mode was not followed")));
02277
02278 break;
02279 }
02280 else
02281 ereport(ERROR,
02282 (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
02283 errmsg("unrecognized table-function returnMode: %d",
02284 (int) rsinfo.returnMode)));
02285
02286 first_time = false;
02287 }
02288
02289 no_function_result:
02290
02291
02292
02293
02294
02295
02296 if (rsinfo.setResult == NULL)
02297 {
02298 MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
02299 tupstore = tuplestore_begin_heap(randomAccess, false, work_mem);
02300 rsinfo.setResult = tupstore;
02301 if (!returnsSet)
02302 {
02303 int natts = expectedDesc->natts;
02304 Datum *nulldatums;
02305 bool *nullflags;
02306
02307 MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
02308 nulldatums = (Datum *) palloc0(natts * sizeof(Datum));
02309 nullflags = (bool *) palloc(natts * sizeof(bool));
02310 memset(nullflags, true, natts * sizeof(bool));
02311 MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
02312 tuplestore_putvalues(tupstore, expectedDesc, nulldatums, nullflags);
02313 }
02314 }
02315
02316
02317
02318
02319
02320 if (rsinfo.setDesc)
02321 {
02322 tupledesc_match(expectedDesc, rsinfo.setDesc);
02323
02324
02325
02326
02327
02328
02329 if (rsinfo.setDesc->tdrefcount == -1)
02330 FreeTupleDesc(rsinfo.setDesc);
02331 }
02332
02333 MemoryContextSwitchTo(callerContext);
02334
02335
02336 return rsinfo.setResult;
02337 }
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353 static Datum
02354 ExecEvalFunc(FuncExprState *fcache,
02355 ExprContext *econtext,
02356 bool *isNull,
02357 ExprDoneCond *isDone)
02358 {
02359
02360 FuncExpr *func = (FuncExpr *) fcache->xprstate.expr;
02361
02362
02363 init_fcache(func->funcid, func->inputcollid, fcache,
02364 econtext->ecxt_per_query_memory, true);
02365
02366
02367 fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResult;
02368
02369 return ExecMakeFunctionResult(fcache, econtext, isNull, isDone);
02370 }
02371
02372
02373
02374
02375
02376 static Datum
02377 ExecEvalOper(FuncExprState *fcache,
02378 ExprContext *econtext,
02379 bool *isNull,
02380 ExprDoneCond *isDone)
02381 {
02382
02383 OpExpr *op = (OpExpr *) fcache->xprstate.expr;
02384
02385
02386 init_fcache(op->opfuncid, op->inputcollid, fcache,
02387 econtext->ecxt_per_query_memory, true);
02388
02389
02390 fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResult;
02391
02392 return ExecMakeFunctionResult(fcache, econtext, isNull, isDone);
02393 }
02394
02395
02396
02397
02398
02399
02400
02401
02402
02403
02404
02405
02406 static Datum
02407 ExecEvalDistinct(FuncExprState *fcache,
02408 ExprContext *econtext,
02409 bool *isNull,
02410 ExprDoneCond *isDone)
02411 {
02412 Datum result;
02413 FunctionCallInfo fcinfo;
02414 ExprDoneCond argDone;
02415
02416
02417 *isNull = false;
02418 if (isDone)
02419 *isDone = ExprSingleResult;
02420
02421
02422
02423
02424 if (fcache->func.fn_oid == InvalidOid)
02425 {
02426 DistinctExpr *op = (DistinctExpr *) fcache->xprstate.expr;
02427
02428 init_fcache(op->opfuncid, op->inputcollid, fcache,
02429 econtext->ecxt_per_query_memory, true);
02430 Assert(!fcache->func.fn_retset);
02431 }
02432
02433
02434
02435
02436 fcinfo = &fcache->fcinfo_data;
02437 argDone = ExecEvalFuncArgs(fcinfo, fcache->args, econtext);
02438 if (argDone != ExprSingleResult)
02439 ereport(ERROR,
02440 (errcode(ERRCODE_DATATYPE_MISMATCH),
02441 errmsg("IS DISTINCT FROM does not support set arguments")));
02442 Assert(fcinfo->nargs == 2);
02443
02444 if (fcinfo->argnull[0] && fcinfo->argnull[1])
02445 {
02446
02447 result = BoolGetDatum(FALSE);
02448 }
02449 else if (fcinfo->argnull[0] || fcinfo->argnull[1])
02450 {
02451
02452 result = BoolGetDatum(TRUE);
02453 }
02454 else
02455 {
02456 fcinfo->isnull = false;
02457 result = FunctionCallInvoke(fcinfo);
02458 *isNull = fcinfo->isnull;
02459
02460 result = BoolGetDatum(!DatumGetBool(result));
02461 }
02462
02463 return result;
02464 }
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474 static Datum
02475 ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate,
02476 ExprContext *econtext,
02477 bool *isNull, ExprDoneCond *isDone)
02478 {
02479 ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) sstate->fxprstate.xprstate.expr;
02480 bool useOr = opexpr->useOr;
02481 ArrayType *arr;
02482 int nitems;
02483 Datum result;
02484 bool resultnull;
02485 FunctionCallInfo fcinfo;
02486 ExprDoneCond argDone;
02487 int i;
02488 int16 typlen;
02489 bool typbyval;
02490 char typalign;
02491 char *s;
02492 bits8 *bitmap;
02493 int bitmask;
02494
02495
02496 *isNull = false;
02497 if (isDone)
02498 *isDone = ExprSingleResult;
02499
02500
02501
02502
02503 if (sstate->fxprstate.func.fn_oid == InvalidOid)
02504 {
02505 init_fcache(opexpr->opfuncid, opexpr->inputcollid, &sstate->fxprstate,
02506 econtext->ecxt_per_query_memory, true);
02507 Assert(!sstate->fxprstate.func.fn_retset);
02508 }
02509
02510
02511
02512
02513 fcinfo = &sstate->fxprstate.fcinfo_data;
02514 argDone = ExecEvalFuncArgs(fcinfo, sstate->fxprstate.args, econtext);
02515 if (argDone != ExprSingleResult)
02516 ereport(ERROR,
02517 (errcode(ERRCODE_DATATYPE_MISMATCH),
02518 errmsg("op ANY/ALL (array) does not support set arguments")));
02519 Assert(fcinfo->nargs == 2);
02520
02521
02522
02523
02524
02525 if (fcinfo->argnull[1])
02526 {
02527 *isNull = true;
02528 return (Datum) 0;
02529 }
02530
02531 arr = DatumGetArrayTypeP(fcinfo->arg[1]);
02532
02533
02534
02535
02536
02537
02538
02539 nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
02540 if (nitems <= 0)
02541 return BoolGetDatum(!useOr);
02542
02543
02544
02545
02546
02547 if (fcinfo->argnull[0] && sstate->fxprstate.func.fn_strict)
02548 {
02549 *isNull = true;
02550 return (Datum) 0;
02551 }
02552
02553
02554
02555
02556
02557 if (sstate->element_type != ARR_ELEMTYPE(arr))
02558 {
02559 get_typlenbyvalalign(ARR_ELEMTYPE(arr),
02560 &sstate->typlen,
02561 &sstate->typbyval,
02562 &sstate->typalign);
02563 sstate->element_type = ARR_ELEMTYPE(arr);
02564 }
02565 typlen = sstate->typlen;
02566 typbyval = sstate->typbyval;
02567 typalign = sstate->typalign;
02568
02569 result = BoolGetDatum(!useOr);
02570 resultnull = false;
02571
02572
02573 s = (char *) ARR_DATA_PTR(arr);
02574 bitmap = ARR_NULLBITMAP(arr);
02575 bitmask = 1;
02576
02577 for (i = 0; i < nitems; i++)
02578 {
02579 Datum elt;
02580 Datum thisresult;
02581
02582
02583 if (bitmap && (*bitmap & bitmask) == 0)
02584 {
02585 fcinfo->arg[1] = (Datum) 0;
02586 fcinfo->argnull[1] = true;
02587 }
02588 else
02589 {
02590 elt = fetch_att(s, typbyval, typlen);
02591 s = att_addlength_pointer(s, typlen, s);
02592 s = (char *) att_align_nominal(s, typalign);
02593 fcinfo->arg[1] = elt;
02594 fcinfo->argnull[1] = false;
02595 }
02596
02597
02598 if (fcinfo->argnull[1] && sstate->fxprstate.func.fn_strict)
02599 {
02600 fcinfo->isnull = true;
02601 thisresult = (Datum) 0;
02602 }
02603 else
02604 {
02605 fcinfo->isnull = false;
02606 thisresult = FunctionCallInvoke(fcinfo);
02607 }
02608
02609
02610 if (fcinfo->isnull)
02611 resultnull = true;
02612 else if (useOr)
02613 {
02614 if (DatumGetBool(thisresult))
02615 {
02616 result = BoolGetDatum(true);
02617 resultnull = false;
02618 break;
02619 }
02620 }
02621 else
02622 {
02623 if (!DatumGetBool(thisresult))
02624 {
02625 result = BoolGetDatum(false);
02626 resultnull = false;
02627 break;
02628 }
02629 }
02630
02631
02632 if (bitmap)
02633 {
02634 bitmask <<= 1;
02635 if (bitmask == 0x100)
02636 {
02637 bitmap++;
02638 bitmask = 1;
02639 }
02640 }
02641 }
02642
02643 *isNull = resultnull;
02644 return result;
02645 }
02646
02647
02648
02649
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661
02662 static Datum
02663 ExecEvalNot(BoolExprState *notclause, ExprContext *econtext,
02664 bool *isNull, ExprDoneCond *isDone)
02665 {
02666 ExprState *clause = linitial(notclause->args);
02667 Datum expr_value;
02668
02669 if (isDone)
02670 *isDone = ExprSingleResult;
02671
02672 expr_value = ExecEvalExpr(clause, econtext, isNull, NULL);
02673
02674
02675
02676
02677
02678 if (*isNull)
02679 return expr_value;
02680
02681
02682
02683
02684
02685 return BoolGetDatum(!DatumGetBool(expr_value));
02686 }
02687
02688
02689
02690
02691
02692 static Datum
02693 ExecEvalOr(BoolExprState *orExpr, ExprContext *econtext,
02694 bool *isNull, ExprDoneCond *isDone)
02695 {
02696 List *clauses = orExpr->args;
02697 ListCell *clause;
02698 bool AnyNull;
02699
02700 if (isDone)
02701 *isDone = ExprSingleResult;
02702
02703 AnyNull = false;
02704
02705
02706
02707
02708
02709
02710
02711
02712
02713
02714
02715
02716
02717
02718 foreach(clause, clauses)
02719 {
02720 ExprState *clausestate = (ExprState *) lfirst(clause);
02721 Datum clause_value;
02722
02723 clause_value = ExecEvalExpr(clausestate, econtext, isNull, NULL);
02724
02725
02726
02727
02728 if (*isNull)
02729 AnyNull = true;
02730 else if (DatumGetBool(clause_value))
02731 return clause_value;
02732 }
02733
02734
02735 *isNull = AnyNull;
02736 return BoolGetDatum(false);
02737 }
02738
02739
02740
02741
02742
02743 static Datum
02744 ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
02745 bool *isNull, ExprDoneCond *isDone)
02746 {
02747 List *clauses = andExpr->args;
02748 ListCell *clause;
02749 bool AnyNull;
02750
02751 if (isDone)
02752 *isDone = ExprSingleResult;
02753
02754 AnyNull = false;
02755
02756
02757
02758
02759
02760
02761
02762
02763
02764
02765 foreach(clause, clauses)
02766 {
02767 ExprState *clausestate = (ExprState *) lfirst(clause);
02768 Datum clause_value;
02769
02770 clause_value = ExecEvalExpr(clausestate, econtext, isNull, NULL);
02771
02772
02773
02774
02775 if (*isNull)
02776 AnyNull = true;
02777 else if (!DatumGetBool(clause_value))
02778 return clause_value;
02779 }
02780
02781
02782 *isNull = AnyNull;
02783 return BoolGetDatum(!AnyNull);
02784 }
02785
02786
02787
02788
02789
02790
02791
02792
02793 static Datum
02794 ExecEvalConvertRowtype(ConvertRowtypeExprState *cstate,
02795 ExprContext *econtext,
02796 bool *isNull, ExprDoneCond *isDone)
02797 {
02798 ConvertRowtypeExpr *convert = (ConvertRowtypeExpr *) cstate->xprstate.expr;
02799 HeapTuple result;
02800 Datum tupDatum;
02801 HeapTupleHeader tuple;
02802 HeapTupleData tmptup;
02803
02804 tupDatum = ExecEvalExpr(cstate->arg, econtext, isNull, isDone);
02805
02806
02807 if (*isNull)
02808 return tupDatum;
02809
02810 tuple = DatumGetHeapTupleHeader(tupDatum);
02811
02812
02813 if (cstate->indesc == NULL)
02814 {
02815 get_cached_rowtype(exprType((Node *) convert->arg), -1,
02816 &cstate->indesc, econtext);
02817 cstate->initialized = false;
02818 }
02819 if (cstate->outdesc == NULL)
02820 {
02821 get_cached_rowtype(convert->resulttype, -1,
02822 &cstate->outdesc, econtext);
02823 cstate->initialized = false;
02824 }
02825
02826 Assert(HeapTupleHeaderGetTypeId(tuple) == cstate->indesc->tdtypeid);
02827 Assert(HeapTupleHeaderGetTypMod(tuple) == cstate->indesc->tdtypmod);
02828
02829
02830 if (!cstate->initialized)
02831 {
02832 MemoryContext old_cxt;
02833
02834
02835 old_cxt = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
02836
02837
02838 cstate->map = convert_tuples_by_name(cstate->indesc,
02839 cstate->outdesc,
02840 gettext_noop("could not convert row type"));
02841 cstate->initialized = true;
02842
02843 MemoryContextSwitchTo(old_cxt);
02844 }
02845
02846
02847
02848
02849 if (cstate->map == NULL)
02850 return tupDatum;
02851
02852
02853
02854
02855 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
02856 tmptup.t_data = tuple;
02857
02858 result = do_convert_tuple(&tmptup, cstate->map);
02859
02860 return HeapTupleGetDatum(result);
02861 }
02862
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872 static Datum
02873 ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
02874 bool *isNull, ExprDoneCond *isDone)
02875 {
02876 List *clauses = caseExpr->args;
02877 ListCell *clause;
02878 Datum save_datum;
02879 bool save_isNull;
02880
02881 if (isDone)
02882 *isDone = ExprSingleResult;
02883
02884
02885
02886
02887
02888
02889
02890 save_datum = econtext->caseValue_datum;
02891 save_isNull = econtext->caseValue_isNull;
02892
02893 if (caseExpr->arg)
02894 {
02895 econtext->caseValue_datum = ExecEvalExpr(caseExpr->arg,
02896 econtext,
02897 &econtext->caseValue_isNull,
02898 NULL);
02899 }
02900
02901
02902
02903
02904
02905
02906 foreach(clause, clauses)
02907 {
02908 CaseWhenState *wclause = lfirst(clause);
02909 Datum clause_value;
02910
02911 clause_value = ExecEvalExpr(wclause->expr,
02912 econtext,
02913 isNull,
02914 NULL);
02915
02916
02917
02918
02919
02920
02921 if (DatumGetBool(clause_value) && !*isNull)
02922 {
02923 econtext->caseValue_datum = save_datum;
02924 econtext->caseValue_isNull = save_isNull;
02925 return ExecEvalExpr(wclause->result,
02926 econtext,
02927 isNull,
02928 isDone);
02929 }
02930 }
02931
02932 econtext->caseValue_datum = save_datum;
02933 econtext->caseValue_isNull = save_isNull;
02934
02935 if (caseExpr->defresult)
02936 {
02937 return ExecEvalExpr(caseExpr->defresult,
02938 econtext,
02939 isNull,
02940 isDone);
02941 }
02942
02943 *isNull = true;
02944 return (Datum) 0;
02945 }
02946
02947
02948
02949
02950
02951
02952 static Datum
02953 ExecEvalCaseTestExpr(ExprState *exprstate,
02954 ExprContext *econtext,
02955 bool *isNull, ExprDoneCond *isDone)
02956 {
02957 if (isDone)
02958 *isDone = ExprSingleResult;
02959 *isNull = econtext->caseValue_isNull;
02960 return econtext->caseValue_datum;
02961 }
02962
02963
02964
02965
02966
02967 static Datum
02968 ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
02969 bool *isNull, ExprDoneCond *isDone)
02970 {
02971 ArrayExpr *arrayExpr = (ArrayExpr *) astate->xprstate.expr;
02972 ArrayType *result;
02973 ListCell *element;
02974 Oid element_type = arrayExpr->element_typeid;
02975 int ndims = 0;
02976 int dims[MAXDIM];
02977 int lbs[MAXDIM];
02978
02979
02980 *isNull = false;
02981 if (isDone)
02982 *isDone = ExprSingleResult;
02983
02984 if (!arrayExpr->multidims)
02985 {
02986
02987 int nelems;
02988 Datum *dvalues;
02989 bool *dnulls;
02990 int i = 0;
02991
02992 ndims = 1;
02993 nelems = list_length(astate->elements);
02994
02995
02996 if (nelems == 0)
02997 return PointerGetDatum(construct_empty_array(element_type));
02998
02999 dvalues = (Datum *) palloc(nelems * sizeof(Datum));
03000 dnulls = (bool *) palloc(nelems * sizeof(bool));
03001
03002
03003 foreach(element, astate->elements)
03004 {
03005 ExprState *e = (ExprState *) lfirst(element);
03006
03007 dvalues[i] = ExecEvalExpr(e, econtext, &dnulls[i], NULL);
03008 i++;
03009 }
03010
03011
03012 dims[0] = nelems;
03013 lbs[0] = 1;
03014
03015 result = construct_md_array(dvalues, dnulls, ndims, dims, lbs,
03016 element_type,
03017 astate->elemlength,
03018 astate->elembyval,
03019 astate->elemalign);
03020 }
03021 else
03022 {
03023
03024 int nbytes = 0;
03025 int nitems = 0;
03026 int outer_nelems = 0;
03027 int elem_ndims = 0;
03028 int *elem_dims = NULL;
03029 int *elem_lbs = NULL;
03030 bool firstone = true;
03031 bool havenulls = false;
03032 bool haveempty = false;
03033 char **subdata;
03034 bits8 **subbitmaps;
03035 int *subbytes;
03036 int *subnitems;
03037 int i;
03038 int32 dataoffset;
03039 char *dat;
03040 int iitem;
03041
03042 i = list_length(astate->elements);
03043 subdata = (char **) palloc(i * sizeof(char *));
03044 subbitmaps = (bits8 **) palloc(i * sizeof(bits8 *));
03045 subbytes = (int *) palloc(i * sizeof(int));
03046 subnitems = (int *) palloc(i * sizeof(int));
03047
03048
03049 foreach(element, astate->elements)
03050 {
03051 ExprState *e = (ExprState *) lfirst(element);
03052 bool eisnull;
03053 Datum arraydatum;
03054 ArrayType *array;
03055 int this_ndims;
03056
03057 arraydatum = ExecEvalExpr(e, econtext, &eisnull, NULL);
03058
03059 if (eisnull)
03060 {
03061 haveempty = true;
03062 continue;
03063 }
03064
03065 array = DatumGetArrayTypeP(arraydatum);
03066
03067
03068 if (element_type != ARR_ELEMTYPE(array))
03069 ereport(ERROR,
03070 (errcode(ERRCODE_DATATYPE_MISMATCH),
03071 errmsg("cannot merge incompatible arrays"),
03072 errdetail("Array with element type %s cannot be "
03073 "included in ARRAY construct with element type %s.",
03074 format_type_be(ARR_ELEMTYPE(array)),
03075 format_type_be(element_type))));
03076
03077 this_ndims = ARR_NDIM(array);
03078
03079 if (this_ndims <= 0)
03080 {
03081 haveempty = true;
03082 continue;
03083 }
03084
03085 if (firstone)
03086 {
03087
03088 elem_ndims = this_ndims;
03089 ndims = elem_ndims + 1;
03090 if (ndims <= 0 || ndims > MAXDIM)
03091 ereport(ERROR,
03092 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
03093 errmsg("number of array dimensions (%d) exceeds " \
03094 "the maximum allowed (%d)", ndims, MAXDIM)));
03095
03096 elem_dims = (int *) palloc(elem_ndims * sizeof(int));
03097 memcpy(elem_dims, ARR_DIMS(array), elem_ndims * sizeof(int));
03098 elem_lbs = (int *) palloc(elem_ndims * sizeof(int));
03099 memcpy(elem_lbs, ARR_LBOUND(array), elem_ndims * sizeof(int));
03100
03101 firstone = false;
03102 }
03103 else
03104 {
03105
03106 if (elem_ndims != this_ndims ||
03107 memcmp(elem_dims, ARR_DIMS(array),
03108 elem_ndims * sizeof(int)) != 0 ||
03109 memcmp(elem_lbs, ARR_LBOUND(array),
03110 elem_ndims * sizeof(int)) != 0)
03111 ereport(ERROR,
03112 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
03113 errmsg("multidimensional arrays must have array "
03114 "expressions with matching dimensions")));
03115 }
03116
03117 subdata[outer_nelems] = ARR_DATA_PTR(array);
03118 subbitmaps[outer_nelems] = ARR_NULLBITMAP(array);
03119 subbytes[outer_nelems] = ARR_SIZE(array) - ARR_DATA_OFFSET(array);
03120 nbytes += subbytes[outer_nelems];
03121 subnitems[outer_nelems] = ArrayGetNItems(this_ndims,
03122 ARR_DIMS(array));
03123 nitems += subnitems[outer_nelems];
03124 havenulls |= ARR_HASNULL(array);
03125 outer_nelems++;
03126 }
03127
03128
03129
03130
03131
03132
03133
03134 if (haveempty)
03135 {
03136 if (ndims == 0)
03137 return PointerGetDatum(construct_empty_array(element_type));
03138 ereport(ERROR,
03139 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
03140 errmsg("multidimensional arrays must have array "
03141 "expressions with matching dimensions")));
03142 }
03143
03144
03145 dims[0] = outer_nelems;
03146 lbs[0] = 1;
03147 for (i = 1; i < ndims; i++)
03148 {
03149 dims[i] = elem_dims[i - 1];
03150 lbs[i] = elem_lbs[i - 1];
03151 }
03152
03153 if (havenulls)
03154 {
03155 dataoffset = ARR_OVERHEAD_WITHNULLS(ndims, nitems);
03156 nbytes += dataoffset;
03157 }
03158 else
03159 {
03160 dataoffset = 0;
03161 nbytes += ARR_OVERHEAD_NONULLS(ndims);
03162 }
03163
03164 result = (ArrayType *) palloc(nbytes);
03165 SET_VARSIZE(result, nbytes);
03166 result->ndim = ndims;
03167 result->dataoffset = dataoffset;
03168 result->elemtype = element_type;
03169 memcpy(ARR_DIMS(result), dims, ndims * sizeof(int));
03170 memcpy(ARR_LBOUND(result), lbs, ndims * sizeof(int));
03171
03172 dat = ARR_DATA_PTR(result);
03173 iitem = 0;
03174 for (i = 0; i < outer_nelems; i++)
03175 {
03176 memcpy(dat, subdata[i], subbytes[i]);
03177 dat += subbytes[i];
03178 if (havenulls)
03179 array_bitmap_copy(ARR_NULLBITMAP(result), iitem,
03180 subbitmaps[i], 0,
03181 subnitems[i]);
03182 iitem += subnitems[i];
03183 }
03184 }
03185
03186 return PointerGetDatum(result);
03187 }
03188
03189
03190
03191
03192
03193 static Datum
03194 ExecEvalRow(RowExprState *rstate,
03195 ExprContext *econtext,
03196 bool *isNull, ExprDoneCond *isDone)
03197 {
03198 HeapTuple tuple;
03199 Datum *values;
03200 bool *isnull;
03201 int natts;
03202 ListCell *arg;
03203 int i;
03204
03205
03206 *isNull = false;
03207 if (isDone)
03208 *isDone = ExprSingleResult;
03209
03210
03211 natts = rstate->tupdesc->natts;
03212 values = (Datum *) palloc0(natts * sizeof(Datum));
03213 isnull = (bool *) palloc(natts * sizeof(bool));
03214
03215
03216 memset(isnull, true, natts * sizeof(bool));
03217
03218
03219 i = 0;
03220 foreach(arg, rstate->args)
03221 {
03222 ExprState *e = (ExprState *) lfirst(arg);
03223
03224 values[i] = ExecEvalExpr(e, econtext, &isnull[i], NULL);
03225 i++;
03226 }
03227
03228 tuple = heap_form_tuple(rstate->tupdesc, values, isnull);
03229
03230 pfree(values);
03231 pfree(isnull);
03232
03233 return HeapTupleGetDatum(tuple);
03234 }
03235
03236
03237
03238
03239
03240 static Datum
03241 ExecEvalRowCompare(RowCompareExprState *rstate,
03242 ExprContext *econtext,
03243 bool *isNull, ExprDoneCond *isDone)
03244 {
03245 bool result;
03246 RowCompareType rctype = ((RowCompareExpr *) rstate->xprstate.expr)->rctype;
03247 int32 cmpresult = 0;
03248 ListCell *l;
03249 ListCell *r;
03250 int i;
03251
03252 if (isDone)
03253 *isDone = ExprSingleResult;
03254 *isNull = true;
03255
03256 i = 0;
03257 forboth(l, rstate->largs, r, rstate->rargs)
03258 {
03259 ExprState *le = (ExprState *) lfirst(l);
03260 ExprState *re = (ExprState *) lfirst(r);
03261 FunctionCallInfoData locfcinfo;
03262
03263 InitFunctionCallInfoData(locfcinfo, &(rstate->funcs[i]), 2,
03264 rstate->collations[i],
03265 NULL, NULL);
03266 locfcinfo.arg[0] = ExecEvalExpr(le, econtext,
03267 &locfcinfo.argnull[0], NULL);
03268 locfcinfo.arg[1] = ExecEvalExpr(re, econtext,
03269 &locfcinfo.argnull[1], NULL);
03270 if (rstate->funcs[i].fn_strict &&
03271 (locfcinfo.argnull[0] || locfcinfo.argnull[1]))
03272 return (Datum) 0;
03273 locfcinfo.isnull = false;
03274 cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo));
03275 if (locfcinfo.isnull)
03276 return (Datum) 0;
03277 if (cmpresult != 0)
03278 break;
03279 i++;
03280 }
03281
03282 switch (rctype)
03283 {
03284
03285 case ROWCOMPARE_LT:
03286 result = (cmpresult < 0);
03287 break;
03288 case ROWCOMPARE_LE:
03289 result = (cmpresult <= 0);
03290 break;
03291 case ROWCOMPARE_GE:
03292 result = (cmpresult >= 0);
03293 break;
03294 case ROWCOMPARE_GT:
03295 result = (cmpresult > 0);
03296 break;
03297 default:
03298 elog(ERROR, "unrecognized RowCompareType: %d", (int) rctype);
03299 result = 0;
03300 break;
03301 }
03302
03303 *isNull = false;
03304 return BoolGetDatum(result);
03305 }
03306
03307
03308
03309
03310
03311 static Datum
03312 ExecEvalCoalesce(CoalesceExprState *coalesceExpr, ExprContext *econtext,
03313 bool *isNull, ExprDoneCond *isDone)
03314 {
03315 ListCell *arg;
03316
03317 if (isDone)
03318 *isDone = ExprSingleResult;
03319
03320
03321 foreach(arg, coalesceExpr->args)
03322 {
03323 ExprState *e = (ExprState *) lfirst(arg);
03324 Datum value;
03325
03326 value = ExecEvalExpr(e, econtext, isNull, NULL);
03327 if (!*isNull)
03328 return value;
03329 }
03330
03331
03332 *isNull = true;
03333 return (Datum) 0;
03334 }
03335
03336
03337
03338
03339
03340 static Datum
03341 ExecEvalMinMax(MinMaxExprState *minmaxExpr, ExprContext *econtext,
03342 bool *isNull, ExprDoneCond *isDone)
03343 {
03344 Datum result = (Datum) 0;
03345 MinMaxExpr *minmax = (MinMaxExpr *) minmaxExpr->xprstate.expr;
03346 Oid collation = minmax->inputcollid;
03347 MinMaxOp op = minmax->op;
03348 FunctionCallInfoData locfcinfo;
03349 ListCell *arg;
03350
03351 if (isDone)
03352 *isDone = ExprSingleResult;
03353 *isNull = true;
03354
03355 InitFunctionCallInfoData(locfcinfo, &minmaxExpr->cfunc, 2,
03356 collation, NULL, NULL);
03357 locfcinfo.argnull[0] = false;
03358 locfcinfo.argnull[1] = false;
03359
03360 foreach(arg, minmaxExpr->args)
03361 {
03362 ExprState *e = (ExprState *) lfirst(arg);
03363 Datum value;
03364 bool valueIsNull;
03365 int32 cmpresult;
03366
03367 value = ExecEvalExpr(e, econtext, &valueIsNull, NULL);
03368 if (valueIsNull)
03369 continue;
03370
03371 if (*isNull)
03372 {
03373
03374 result = value;
03375 *isNull = false;
03376 }
03377 else
03378 {
03379
03380 locfcinfo.arg[0] = result;
03381 locfcinfo.arg[1] = value;
03382 locfcinfo.isnull = false;
03383 cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo));
03384 if (locfcinfo.isnull)
03385 continue;
03386 if (cmpresult > 0 && op == IS_LEAST)
03387 result = value;
03388 else if (cmpresult < 0 && op == IS_GREATEST)
03389 result = value;
03390 }
03391 }
03392
03393 return result;
03394 }
03395
03396
03397
03398
03399
03400 static Datum
03401 ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
03402 bool *isNull, ExprDoneCond *isDone)
03403 {
03404 XmlExpr *xexpr = (XmlExpr *) xmlExpr->xprstate.expr;
03405 Datum value;
03406 bool isnull;
03407 ListCell *arg;
03408 ListCell *narg;
03409
03410 if (isDone)
03411 *isDone = ExprSingleResult;
03412 *isNull = true;
03413
03414 switch (xexpr->op)
03415 {
03416 case IS_XMLCONCAT:
03417 {
03418 List *values = NIL;
03419
03420 foreach(arg, xmlExpr->args)
03421 {
03422 ExprState *e = (ExprState *) lfirst(arg);
03423
03424 value = ExecEvalExpr(e, econtext, &isnull, NULL);
03425 if (!isnull)
03426 values = lappend(values, DatumGetPointer(value));
03427 }
03428
03429 if (list_length(values) > 0)
03430 {
03431 *isNull = false;
03432 return PointerGetDatum(xmlconcat(values));
03433 }
03434 else
03435 return (Datum) 0;
03436 }
03437 break;
03438
03439 case IS_XMLFOREST:
03440 {
03441 StringInfoData buf;
03442
03443 initStringInfo(&buf);
03444 forboth(arg, xmlExpr->named_args, narg, xexpr->arg_names)
03445 {
03446 ExprState *e = (ExprState *) lfirst(arg);
03447 char *argname = strVal(lfirst(narg));
03448
03449 value = ExecEvalExpr(e, econtext, &isnull, NULL);
03450 if (!isnull)
03451 {
03452 appendStringInfo(&buf, "<%s>%s</%s>",
03453 argname,
03454 map_sql_value_to_xml_value(value, exprType((Node *) e->expr), true),
03455 argname);
03456 *isNull = false;
03457 }
03458 }
03459
03460 if (*isNull)
03461 {
03462 pfree(buf.data);
03463 return (Datum) 0;
03464 }
03465 else
03466 {
03467 text *result;
03468
03469 result = cstring_to_text_with_len(buf.data, buf.len);
03470 pfree(buf.data);
03471
03472 return PointerGetDatum(result);
03473 }
03474 }
03475 break;
03476
03477 case IS_XMLELEMENT:
03478 *isNull = false;
03479 return PointerGetDatum(xmlelement(xmlExpr, econtext));
03480 break;
03481
03482 case IS_XMLPARSE:
03483 {
03484 ExprState *e;
03485 text *data;
03486 bool preserve_whitespace;
03487
03488
03489 Assert(list_length(xmlExpr->args) == 2);
03490
03491 e = (ExprState *) linitial(xmlExpr->args);
03492 value = ExecEvalExpr(e, econtext, &isnull, NULL);
03493 if (isnull)
03494 return (Datum) 0;
03495 data = DatumGetTextP(value);
03496
03497 e = (ExprState *) lsecond(xmlExpr->args);
03498 value = ExecEvalExpr(e, econtext, &isnull, NULL);
03499 if (isnull)
03500 return (Datum) 0;
03501 preserve_whitespace = DatumGetBool(value);
03502
03503 *isNull = false;
03504
03505 return PointerGetDatum(xmlparse(data,
03506 xexpr->xmloption,
03507 preserve_whitespace));
03508 }
03509 break;
03510
03511 case IS_XMLPI:
03512 {
03513 ExprState *e;
03514 text *arg;
03515
03516
03517 Assert(list_length(xmlExpr->args) <= 1);
03518
03519 if (xmlExpr->args)
03520 {
03521 e = (ExprState *) linitial(xmlExpr->args);
03522 value = ExecEvalExpr(e, econtext, &isnull, NULL);
03523 if (isnull)
03524 arg = NULL;
03525 else
03526 arg = DatumGetTextP(value);
03527 }
03528 else
03529 {
03530 arg = NULL;
03531 isnull = false;
03532 }
03533
03534 return PointerGetDatum(xmlpi(xexpr->name, arg, isnull, isNull));
03535 }
03536 break;
03537
03538 case IS_XMLROOT:
03539 {
03540 ExprState *e;
03541 xmltype *data;
03542 text *version;
03543 int standalone;
03544
03545
03546 Assert(list_length(xmlExpr->args) == 3);
03547
03548 e = (ExprState *) linitial(xmlExpr->args);
03549 value = ExecEvalExpr(e, econtext, &isnull, NULL);
03550 if (isnull)
03551 return (Datum) 0;
03552 data = DatumGetXmlP(value);
03553
03554 e = (ExprState *) lsecond(xmlExpr->args);
03555 value = ExecEvalExpr(e, econtext, &isnull, NULL);
03556 if (isnull)
03557 version = NULL;
03558 else
03559 version = DatumGetTextP(value);
03560
03561 e = (ExprState *) lthird(xmlExpr->args);
03562 value = ExecEvalExpr(e, econtext, &isnull, NULL);
03563 standalone = DatumGetInt32(value);
03564
03565 *isNull = false;
03566
03567 return PointerGetDatum(xmlroot(data,
03568 version,
03569 standalone));
03570 }
03571 break;
03572
03573 case IS_XMLSERIALIZE:
03574 {
03575 ExprState *e;
03576
03577
03578 Assert(list_length(xmlExpr->args) == 1);
03579
03580 e = (ExprState *) linitial(xmlExpr->args);
03581 value = ExecEvalExpr(e, econtext, &isnull, NULL);
03582 if (isnull)
03583 return (Datum) 0;
03584
03585 *isNull = false;
03586
03587 return PointerGetDatum(xmltotext_with_xmloption(DatumGetXmlP(value), xexpr->xmloption));
03588 }
03589 break;
03590
03591 case IS_DOCUMENT:
03592 {
03593 ExprState *e;
03594
03595
03596 Assert(list_length(xmlExpr->args) == 1);
03597
03598 e = (ExprState *) linitial(xmlExpr->args);
03599 value = ExecEvalExpr(e, econtext, &isnull, NULL);
03600 if (isnull)
03601 return (Datum) 0;
03602 else
03603 {
03604 *isNull = false;
03605 return BoolGetDatum(xml_is_document(DatumGetXmlP(value)));
03606 }
03607 }
03608 break;
03609 }
03610
03611 elog(ERROR, "unrecognized XML operation");
03612 return (Datum) 0;
03613 }
03614
03615
03616
03617
03618
03619
03620
03621
03622
03623 static Datum
03624 ExecEvalNullIf(FuncExprState *nullIfExpr,
03625 ExprContext *econtext,
03626 bool *isNull, ExprDoneCond *isDone)
03627 {
03628 Datum result;
03629 FunctionCallInfo fcinfo;
03630 ExprDoneCond argDone;
03631
03632 if (isDone)
03633 *isDone = ExprSingleResult;
03634
03635
03636
03637
03638 if (nullIfExpr->func.fn_oid == InvalidOid)
03639 {
03640 NullIfExpr *op = (NullIfExpr *) nullIfExpr->xprstate.expr;
03641
03642 init_fcache(op->opfuncid, op->inputcollid, nullIfExpr,
03643 econtext->ecxt_per_query_memory, true);
03644 Assert(!nullIfExpr->func.fn_retset);
03645 }
03646
03647
03648
03649
03650 fcinfo = &nullIfExpr->fcinfo_data;
03651 argDone = ExecEvalFuncArgs(fcinfo, nullIfExpr->args, econtext);
03652 if (argDone != ExprSingleResult)
03653 ereport(ERROR,
03654 (errcode(ERRCODE_DATATYPE_MISMATCH),
03655 errmsg("NULLIF does not support set arguments")));
03656 Assert(fcinfo->nargs == 2);
03657
03658
03659 if (!fcinfo->argnull[0] && !fcinfo->argnull[1])
03660 {
03661 fcinfo->isnull = false;
03662 result = FunctionCallInvoke(fcinfo);
03663
03664 if (!fcinfo->isnull && DatumGetBool(result))
03665 {
03666 *isNull = true;
03667 return (Datum) 0;
03668 }
03669 }
03670
03671
03672 *isNull = fcinfo->argnull[0];
03673 return fcinfo->arg[0];
03674 }
03675
03676
03677
03678
03679
03680
03681
03682 static Datum
03683 ExecEvalNullTest(NullTestState *nstate,
03684 ExprContext *econtext,
03685 bool *isNull,
03686 ExprDoneCond *isDone)
03687 {
03688 NullTest *ntest = (NullTest *) nstate->xprstate.expr;
03689 Datum result;
03690
03691 result = ExecEvalExpr(nstate->arg, econtext, isNull, isDone);
03692
03693 if (isDone && *isDone == ExprEndResult)
03694 return result;
03695
03696 if (ntest->argisrow && !(*isNull))
03697 {
03698 HeapTupleHeader tuple;
03699 Oid tupType;
03700 int32 tupTypmod;
03701 TupleDesc tupDesc;
03702 HeapTupleData tmptup;
03703 int att;
03704
03705 tuple = DatumGetHeapTupleHeader(result);
03706
03707 tupType = HeapTupleHeaderGetTypeId(tuple);
03708 tupTypmod = HeapTupleHeaderGetTypMod(tuple);
03709
03710
03711 tupDesc = get_cached_rowtype(tupType, tupTypmod,
03712 &nstate->argdesc, econtext);
03713
03714
03715
03716
03717 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
03718 tmptup.t_data = tuple;
03719
03720 for (att = 1; att <= tupDesc->natts; att++)
03721 {
03722
03723 if (tupDesc->attrs[att - 1]->attisdropped)
03724 continue;
03725 if (heap_attisnull(&tmptup, att))
03726 {
03727
03728 if (ntest->nulltesttype == IS_NOT_NULL)
03729 return BoolGetDatum(false);
03730 }
03731 else
03732 {
03733
03734 if (ntest->nulltesttype == IS_NULL)
03735 return BoolGetDatum(false);
03736 }
03737 }
03738
03739 return BoolGetDatum(true);
03740 }
03741 else
03742 {
03743
03744 switch (ntest->nulltesttype)
03745 {
03746 case IS_NULL:
03747 if (*isNull)
03748 {
03749 *isNull = false;
03750 return BoolGetDatum(true);
03751 }
03752 else
03753 return BoolGetDatum(false);
03754 case IS_NOT_NULL:
03755 if (*isNull)
03756 {
03757 *isNull = false;
03758 return BoolGetDatum(false);
03759 }
03760 else
03761 return BoolGetDatum(true);
03762 default:
03763 elog(ERROR, "unrecognized nulltesttype: %d",
03764 (int) ntest->nulltesttype);
03765 return (Datum) 0;
03766 }
03767 }
03768 }
03769
03770
03771
03772
03773
03774
03775
03776 static Datum
03777 ExecEvalBooleanTest(GenericExprState *bstate,
03778 ExprContext *econtext,
03779 bool *isNull,
03780 ExprDoneCond *isDone)
03781 {
03782 BooleanTest *btest = (BooleanTest *) bstate->xprstate.expr;
03783 Datum result;
03784
03785 result = ExecEvalExpr(bstate->arg, econtext, isNull, isDone);
03786
03787 if (isDone && *isDone == ExprEndResult)
03788 return result;
03789
03790 switch (btest->booltesttype)
03791 {
03792 case IS_TRUE:
03793 if (*isNull)
03794 {
03795 *isNull = false;
03796 return BoolGetDatum(false);
03797 }
03798 else if (DatumGetBool(result))
03799 return BoolGetDatum(true);
03800 else
03801 return BoolGetDatum(false);
03802 case IS_NOT_TRUE:
03803 if (*isNull)
03804 {
03805 *isNull = false;
03806 return BoolGetDatum(true);
03807 }
03808 else if (DatumGetBool(result))
03809 return BoolGetDatum(false);
03810 else
03811 return BoolGetDatum(true);
03812 case IS_FALSE:
03813 if (*isNull)
03814 {
03815 *isNull = false;
03816 return BoolGetDatum(false);
03817 }
03818 else if (DatumGetBool(result))
03819 return BoolGetDatum(false);
03820 else
03821 return BoolGetDatum(true);
03822 case IS_NOT_FALSE:
03823 if (*isNull)
03824 {
03825 *isNull = false;
03826 return BoolGetDatum(true);
03827 }
03828 else if (DatumGetBool(result))
03829 return BoolGetDatum(true);
03830 else
03831 return BoolGetDatum(false);
03832 case IS_UNKNOWN:
03833 if (*isNull)
03834 {
03835 *isNull = false;
03836 return BoolGetDatum(true);
03837 }
03838 else
03839 return BoolGetDatum(false);
03840 case IS_NOT_UNKNOWN:
03841 if (*isNull)
03842 {
03843 *isNull = false;
03844 return BoolGetDatum(false);
03845 }
03846 else
03847 return BoolGetDatum(true);
03848 default:
03849 elog(ERROR, "unrecognized booltesttype: %d",
03850 (int) btest->booltesttype);
03851 return (Datum) 0;
03852 }
03853 }
03854
03855
03856
03857
03858
03859
03860
03861
03862 static Datum
03863 ExecEvalCoerceToDomain(CoerceToDomainState *cstate, ExprContext *econtext,
03864 bool *isNull, ExprDoneCond *isDone)
03865 {
03866 CoerceToDomain *ctest = (CoerceToDomain *) cstate->xprstate.expr;
03867 Datum result;
03868 ListCell *l;
03869
03870 result = ExecEvalExpr(cstate->arg, econtext, isNull, isDone);
03871
03872 if (isDone && *isDone == ExprEndResult)
03873 return result;
03874
03875 foreach(l, cstate->constraints)
03876 {
03877 DomainConstraintState *con = (DomainConstraintState *) lfirst(l);
03878
03879 switch (con->constrainttype)
03880 {
03881 case DOM_CONSTRAINT_NOTNULL:
03882 if (*isNull)
03883 ereport(ERROR,
03884 (errcode(ERRCODE_NOT_NULL_VIOLATION),
03885 errmsg("domain %s does not allow null values",
03886 format_type_be(ctest->resulttype)),
03887 errdatatype(ctest->resulttype)));
03888 break;
03889 case DOM_CONSTRAINT_CHECK:
03890 {
03891 Datum conResult;
03892 bool conIsNull;
03893 Datum save_datum;
03894 bool save_isNull;
03895
03896
03897
03898
03899
03900
03901
03902 save_datum = econtext->domainValue_datum;
03903 save_isNull = econtext->domainValue_isNull;
03904
03905 econtext->domainValue_datum = result;
03906 econtext->domainValue_isNull = *isNull;
03907
03908 conResult = ExecEvalExpr(con->check_expr,
03909 econtext, &conIsNull, NULL);
03910
03911 if (!conIsNull &&
03912 !DatumGetBool(conResult))
03913 ereport(ERROR,
03914 (errcode(ERRCODE_CHECK_VIOLATION),
03915 errmsg("value for domain %s violates check constraint \"%s\"",
03916 format_type_be(ctest->resulttype),
03917 con->name),
03918 errdomainconstraint(ctest->resulttype,
03919 con->name)));
03920 econtext->domainValue_datum = save_datum;
03921 econtext->domainValue_isNull = save_isNull;
03922
03923 break;
03924 }
03925 default:
03926 elog(ERROR, "unrecognized constraint type: %d",
03927 (int) con->constrainttype);
03928 break;
03929 }
03930 }
03931
03932
03933 return result;
03934 }
03935
03936
03937
03938
03939
03940
03941 static Datum
03942 ExecEvalCoerceToDomainValue(ExprState *exprstate,
03943 ExprContext *econtext,
03944 bool *isNull, ExprDoneCond *isDone)
03945 {
03946 if (isDone)
03947 *isDone = ExprSingleResult;
03948 *isNull = econtext->domainValue_isNull;
03949 return econtext->domainValue_datum;
03950 }
03951
03952
03953
03954
03955
03956
03957
03958 static Datum
03959 ExecEvalFieldSelect(FieldSelectState *fstate,
03960 ExprContext *econtext,
03961 bool *isNull,
03962 ExprDoneCond *isDone)
03963 {
03964 FieldSelect *fselect = (FieldSelect *) fstate->xprstate.expr;
03965 AttrNumber fieldnum = fselect->fieldnum;
03966 Datum result;
03967 Datum tupDatum;
03968 HeapTupleHeader tuple;
03969 Oid tupType;
03970 int32 tupTypmod;
03971 TupleDesc tupDesc;
03972 Form_pg_attribute attr;
03973 HeapTupleData tmptup;
03974
03975 tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull, isDone);
03976
03977
03978 if (*isNull)
03979 return tupDatum;
03980
03981 tuple = DatumGetHeapTupleHeader(tupDatum);
03982
03983 tupType = HeapTupleHeaderGetTypeId(tuple);
03984 tupTypmod = HeapTupleHeaderGetTypMod(tuple);
03985
03986
03987 tupDesc = get_cached_rowtype(tupType, tupTypmod,
03988 &fstate->argdesc, econtext);
03989
03990
03991
03992
03993
03994
03995 if (fieldnum <= 0)
03996 elog(ERROR, "unsupported reference to system column %d in FieldSelect",
03997 fieldnum);
03998 if (fieldnum > tupDesc->natts)
03999 elog(ERROR, "attribute number %d exceeds number of columns %d",
04000 fieldnum, tupDesc->natts);
04001 attr = tupDesc->attrs[fieldnum - 1];
04002
04003
04004 if (attr->attisdropped)
04005 {
04006 *isNull = true;
04007 return (Datum) 0;
04008 }
04009
04010
04011
04012 if (fselect->resulttype != attr->atttypid)
04013 ereport(ERROR,
04014 (errmsg("attribute %d has wrong type", fieldnum),
04015 errdetail("Table has type %s, but query expects %s.",
04016 format_type_be(attr->atttypid),
04017 format_type_be(fselect->resulttype))));
04018
04019
04020 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
04021 tmptup.t_data = tuple;
04022
04023 result = heap_getattr(&tmptup,
04024 fieldnum,
04025 tupDesc,
04026 isNull);
04027 return result;
04028 }
04029
04030
04031
04032
04033
04034
04035
04036 static Datum
04037 ExecEvalFieldStore(FieldStoreState *fstate,
04038 ExprContext *econtext,
04039 bool *isNull,
04040 ExprDoneCond *isDone)
04041 {
04042 FieldStore *fstore = (FieldStore *) fstate->xprstate.expr;
04043 HeapTuple tuple;
04044 Datum tupDatum;
04045 TupleDesc tupDesc;
04046 Datum *values;
04047 bool *isnull;
04048 Datum save_datum;
04049 bool save_isNull;
04050 ListCell *l1,
04051 *l2;
04052
04053 tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull, isDone);
04054
04055 if (isDone && *isDone == ExprEndResult)
04056 return tupDatum;
04057
04058
04059 tupDesc = get_cached_rowtype(fstore->resulttype, -1,
04060 &fstate->argdesc, econtext);
04061
04062
04063 values = (Datum *) palloc(tupDesc->natts * sizeof(Datum));
04064 isnull = (bool *) palloc(tupDesc->natts * sizeof(bool));
04065
04066 if (!*isNull)
04067 {
04068
04069
04070
04071
04072 HeapTupleHeader tuphdr;
04073 HeapTupleData tmptup;
04074
04075 tuphdr = DatumGetHeapTupleHeader(tupDatum);
04076 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuphdr);
04077 ItemPointerSetInvalid(&(tmptup.t_self));
04078 tmptup.t_tableOid = InvalidOid;
04079 tmptup.t_data = tuphdr;
04080
04081 heap_deform_tuple(&tmptup, tupDesc, values, isnull);
04082 }
04083 else
04084 {
04085
04086 memset(isnull, true, tupDesc->natts * sizeof(bool));
04087 }
04088
04089
04090 *isNull = false;
04091
04092 save_datum = econtext->caseValue_datum;
04093 save_isNull = econtext->caseValue_isNull;
04094
04095 forboth(l1, fstate->newvals, l2, fstore->fieldnums)
04096 {
04097 ExprState *newval = (ExprState *) lfirst(l1);
04098 AttrNumber fieldnum = lfirst_int(l2);
04099
04100 Assert(fieldnum > 0 && fieldnum <= tupDesc->natts);
04101
04102
04103
04104
04105
04106
04107
04108
04109
04110
04111 econtext->caseValue_datum = values[fieldnum - 1];
04112 econtext->caseValue_isNull = isnull[fieldnum - 1];
04113
04114 values[fieldnum - 1] = ExecEvalExpr(newval,
04115 econtext,
04116 &isnull[fieldnum - 1],
04117 NULL);
04118 }
04119
04120 econtext->caseValue_datum = save_datum;
04121 econtext->caseValue_isNull = save_isNull;
04122
04123 tuple = heap_form_tuple(tupDesc, values, isnull);
04124
04125 pfree(values);
04126 pfree(isnull);
04127
04128 return HeapTupleGetDatum(tuple);
04129 }
04130
04131
04132
04133
04134
04135
04136
04137 static Datum
04138 ExecEvalRelabelType(GenericExprState *exprstate,
04139 ExprContext *econtext,
04140 bool *isNull, ExprDoneCond *isDone)
04141 {
04142 return ExecEvalExpr(exprstate->arg, econtext, isNull, isDone);
04143 }
04144
04145
04146
04147
04148
04149
04150
04151 static Datum
04152 ExecEvalCoerceViaIO(CoerceViaIOState *iostate,
04153 ExprContext *econtext,
04154 bool *isNull, ExprDoneCond *isDone)
04155 {
04156 Datum result;
04157 Datum inputval;
04158 char *string;
04159
04160 inputval = ExecEvalExpr(iostate->arg, econtext, isNull, isDone);
04161
04162 if (isDone && *isDone == ExprEndResult)
04163 return inputval;
04164
04165 if (*isNull)
04166 string = NULL;
04167 else
04168 string = OutputFunctionCall(&iostate->outfunc, inputval);
04169
04170 result = InputFunctionCall(&iostate->infunc,
04171 string,
04172 iostate->intypioparam,
04173 -1);
04174
04175
04176 return result;
04177 }
04178
04179
04180
04181
04182
04183
04184
04185 static Datum
04186 ExecEvalArrayCoerceExpr(ArrayCoerceExprState *astate,
04187 ExprContext *econtext,
04188 bool *isNull, ExprDoneCond *isDone)
04189 {
04190 ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) astate->xprstate.expr;
04191 Datum result;
04192 ArrayType *array;
04193 FunctionCallInfoData locfcinfo;
04194
04195 result = ExecEvalExpr(astate->arg, econtext, isNull, isDone);
04196
04197 if (isDone && *isDone == ExprEndResult)
04198 return result;
04199 if (*isNull)
04200 return result;
04201
04202
04203
04204
04205
04206 if (!OidIsValid(acoerce->elemfuncid))
04207 {
04208
04209 array = DatumGetArrayTypePCopy(result);
04210 ARR_ELEMTYPE(array) = astate->resultelemtype;
04211 PG_RETURN_ARRAYTYPE_P(array);
04212 }
04213
04214
04215 array = DatumGetArrayTypeP(result);
04216
04217
04218 if (astate->elemfunc.fn_oid == InvalidOid)
04219 {
04220 AclResult aclresult;
04221
04222
04223 aclresult = pg_proc_aclcheck(acoerce->elemfuncid, GetUserId(),
04224 ACL_EXECUTE);
04225 if (aclresult != ACLCHECK_OK)
04226 aclcheck_error(aclresult, ACL_KIND_PROC,
04227 get_func_name(acoerce->elemfuncid));
04228 InvokeFunctionExecuteHook(acoerce->elemfuncid);
04229
04230
04231 fmgr_info_cxt(acoerce->elemfuncid, &(astate->elemfunc),
04232 econtext->ecxt_per_query_memory);
04233 fmgr_info_set_expr((Node *) acoerce, &(astate->elemfunc));
04234 }
04235
04236
04237
04238
04239
04240
04241
04242
04243
04244 InitFunctionCallInfoData(locfcinfo, &(astate->elemfunc), 3,
04245 InvalidOid, NULL, NULL);
04246 locfcinfo.arg[0] = PointerGetDatum(array);
04247 locfcinfo.arg[1] = Int32GetDatum(acoerce->resulttypmod);
04248 locfcinfo.arg[2] = BoolGetDatum(acoerce->isExplicit);
04249 locfcinfo.argnull[0] = false;
04250 locfcinfo.argnull[1] = false;
04251 locfcinfo.argnull[2] = false;
04252
04253 return array_map(&locfcinfo, ARR_ELEMTYPE(array), astate->resultelemtype,
04254 astate->amstate);
04255 }
04256
04257
04258
04259
04260
04261
04262
04263
04264
04265
04266
04267 static Datum
04268 ExecEvalCurrentOfExpr(ExprState *exprstate, ExprContext *econtext,
04269 bool *isNull, ExprDoneCond *isDone)
04270 {
04271 ereport(ERROR,
04272 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
04273 errmsg("WHERE CURRENT OF is not supported for this table type")));
04274 return 0;
04275 }
04276
04277
04278
04279
04280
04281
04282
04283 Datum
04284 ExecEvalExprSwitchContext(ExprState *expression,
04285 ExprContext *econtext,
04286 bool *isNull,
04287 ExprDoneCond *isDone)
04288 {
04289 Datum retDatum;
04290 MemoryContext oldContext;
04291
04292 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
04293 retDatum = ExecEvalExpr(expression, econtext, isNull, isDone);
04294 MemoryContextSwitchTo(oldContext);
04295 return retDatum;
04296 }
04297
04298
04299
04300
04301
04302
04303
04304
04305
04306
04307
04308
04309
04310
04311
04312
04313
04314
04315
04316
04317
04318
04319
04320
04321
04322
04323
04324
04325
04326
04327
04328
04329
04330
04331 ExprState *
04332 ExecInitExpr(Expr *node, PlanState *parent)
04333 {
04334 ExprState *state;
04335
04336 if (node == NULL)
04337 return NULL;
04338
04339
04340 check_stack_depth();
04341
04342 switch (nodeTag(node))
04343 {
04344 case T_Var:
04345
04346 if (((Var *) node)->varattno == InvalidAttrNumber)
04347 {
04348 WholeRowVarExprState *wstate = makeNode(WholeRowVarExprState);
04349
04350 wstate->parent = parent;
04351 wstate->wrv_junkFilter = NULL;
04352 state = (ExprState *) wstate;
04353 state->evalfunc = (ExprStateEvalFunc) ExecEvalWholeRowVar;
04354 }
04355 else
04356 {
04357 state = (ExprState *) makeNode(ExprState);
04358 state->evalfunc = ExecEvalScalarVar;
04359 }
04360 break;
04361 case T_Const:
04362 state = (ExprState *) makeNode(ExprState);
04363 state->evalfunc = ExecEvalConst;
04364 break;
04365 case T_Param:
04366 state = (ExprState *) makeNode(ExprState);
04367 switch (((Param *) node)->paramkind)
04368 {
04369 case PARAM_EXEC:
04370 state->evalfunc = ExecEvalParamExec;
04371 break;
04372 case PARAM_EXTERN:
04373 state->evalfunc = ExecEvalParamExtern;
04374 break;
04375 default:
04376 elog(ERROR, "unrecognized paramkind: %d",
04377 (int) ((Param *) node)->paramkind);
04378 break;
04379 }
04380 break;
04381 case T_CoerceToDomainValue:
04382 state = (ExprState *) makeNode(ExprState);
04383 state->evalfunc = ExecEvalCoerceToDomainValue;
04384 break;
04385 case T_CaseTestExpr:
04386 state = (ExprState *) makeNode(ExprState);
04387 state->evalfunc = ExecEvalCaseTestExpr;
04388 break;
04389 case T_Aggref:
04390 {
04391 Aggref *aggref = (Aggref *) node;
04392 AggrefExprState *astate = makeNode(AggrefExprState);
04393
04394 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalAggref;
04395 if (parent && IsA(parent, AggState))
04396 {
04397 AggState *aggstate = (AggState *) parent;
04398 int naggs;
04399
04400 aggstate->aggs = lcons(astate, aggstate->aggs);
04401 naggs = ++aggstate->numaggs;
04402
04403 astate->args = (List *) ExecInitExpr((Expr *) aggref->args,
04404 parent);
04405
04406
04407
04408
04409
04410
04411
04412 if (naggs != aggstate->numaggs)
04413 ereport(ERROR,
04414 (errcode(ERRCODE_GROUPING_ERROR),
04415 errmsg("aggregate function calls cannot be nested")));
04416 }
04417 else
04418 {
04419
04420 elog(ERROR, "Aggref found in non-Agg plan node");
04421 }
04422 state = (ExprState *) astate;
04423 }
04424 break;
04425 case T_WindowFunc:
04426 {
04427 WindowFunc *wfunc = (WindowFunc *) node;
04428 WindowFuncExprState *wfstate = makeNode(WindowFuncExprState);
04429
04430 wfstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalWindowFunc;
04431 if (parent && IsA(parent, WindowAggState))
04432 {
04433 WindowAggState *winstate = (WindowAggState *) parent;
04434 int nfuncs;
04435
04436 winstate->funcs = lcons(wfstate, winstate->funcs);
04437 nfuncs = ++winstate->numfuncs;
04438 if (wfunc->winagg)
04439 winstate->numaggs++;
04440
04441 wfstate->args = (List *) ExecInitExpr((Expr *) wfunc->args,
04442 parent);
04443
04444
04445
04446
04447
04448
04449
04450 if (nfuncs != winstate->numfuncs)
04451 ereport(ERROR,
04452 (errcode(ERRCODE_WINDOWING_ERROR),
04453 errmsg("window function calls cannot be nested")));
04454 }
04455 else
04456 {
04457
04458 elog(ERROR, "WindowFunc found in non-WindowAgg plan node");
04459 }
04460 state = (ExprState *) wfstate;
04461 }
04462 break;
04463 case T_ArrayRef:
04464 {
04465 ArrayRef *aref = (ArrayRef *) node;
04466 ArrayRefExprState *astate = makeNode(ArrayRefExprState);
04467
04468 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArrayRef;
04469 astate->refupperindexpr = (List *)
04470 ExecInitExpr((Expr *) aref->refupperindexpr, parent);
04471 astate->reflowerindexpr = (List *)
04472 ExecInitExpr((Expr *) aref->reflowerindexpr, parent);
04473 astate->refexpr = ExecInitExpr(aref->refexpr, parent);
04474 astate->refassgnexpr = ExecInitExpr(aref->refassgnexpr,
04475 parent);
04476
04477 astate->refattrlength = get_typlen(aref->refarraytype);
04478 get_typlenbyvalalign(aref->refelemtype,
04479 &astate->refelemlength,
04480 &astate->refelembyval,
04481 &astate->refelemalign);
04482 state = (ExprState *) astate;
04483 }
04484 break;
04485 case T_FuncExpr:
04486 {
04487 FuncExpr *funcexpr = (FuncExpr *) node;
04488 FuncExprState *fstate = makeNode(FuncExprState);
04489
04490 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFunc;
04491 fstate->args = (List *)
04492 ExecInitExpr((Expr *) funcexpr->args, parent);
04493 fstate->func.fn_oid = InvalidOid;
04494 state = (ExprState *) fstate;
04495 }
04496 break;
04497 case T_OpExpr:
04498 {
04499 OpExpr *opexpr = (OpExpr *) node;
04500 FuncExprState *fstate = makeNode(FuncExprState);
04501
04502 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalOper;
04503 fstate->args = (List *)
04504 ExecInitExpr((Expr *) opexpr->args, parent);
04505 fstate->func.fn_oid = InvalidOid;
04506 state = (ExprState *) fstate;
04507 }
04508 break;
04509 case T_DistinctExpr:
04510 {
04511 DistinctExpr *distinctexpr = (DistinctExpr *) node;
04512 FuncExprState *fstate = makeNode(FuncExprState);
04513
04514 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalDistinct;
04515 fstate->args = (List *)
04516 ExecInitExpr((Expr *) distinctexpr->args, parent);
04517 fstate->func.fn_oid = InvalidOid;
04518 state = (ExprState *) fstate;
04519 }
04520 break;
04521 case T_NullIfExpr:
04522 {
04523 NullIfExpr *nullifexpr = (NullIfExpr *) node;
04524 FuncExprState *fstate = makeNode(FuncExprState);
04525
04526 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNullIf;
04527 fstate->args = (List *)
04528 ExecInitExpr((Expr *) nullifexpr->args, parent);
04529 fstate->func.fn_oid = InvalidOid;
04530 state = (ExprState *) fstate;
04531 }
04532 break;
04533 case T_ScalarArrayOpExpr:
04534 {
04535 ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) node;
04536 ScalarArrayOpExprState *sstate = makeNode(ScalarArrayOpExprState);
04537
04538 sstate->fxprstate.xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalScalarArrayOp;
04539 sstate->fxprstate.args = (List *)
04540 ExecInitExpr((Expr *) opexpr->args, parent);
04541 sstate->fxprstate.func.fn_oid = InvalidOid;
04542 sstate->element_type = InvalidOid;
04543 state = (ExprState *) sstate;
04544 }
04545 break;
04546 case T_BoolExpr:
04547 {
04548 BoolExpr *boolexpr = (BoolExpr *) node;
04549 BoolExprState *bstate = makeNode(BoolExprState);
04550
04551 switch (boolexpr->boolop)
04552 {
04553 case AND_EXPR:
04554 bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalAnd;
04555 break;
04556 case OR_EXPR:
04557 bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalOr;
04558 break;
04559 case NOT_EXPR:
04560 bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNot;
04561 break;
04562 default:
04563 elog(ERROR, "unrecognized boolop: %d",
04564 (int) boolexpr->boolop);
04565 break;
04566 }
04567 bstate->args = (List *)
04568 ExecInitExpr((Expr *) boolexpr->args, parent);
04569 state = (ExprState *) bstate;
04570 }
04571 break;
04572 case T_SubPlan:
04573 {
04574 SubPlan *subplan = (SubPlan *) node;
04575 SubPlanState *sstate;
04576
04577 if (!parent)
04578 elog(ERROR, "SubPlan found with no parent plan");
04579
04580 sstate = ExecInitSubPlan(subplan, parent);
04581
04582
04583 parent->subPlan = lappend(parent->subPlan, sstate);
04584
04585 state = (ExprState *) sstate;
04586 }
04587 break;
04588 case T_AlternativeSubPlan:
04589 {
04590 AlternativeSubPlan *asplan = (AlternativeSubPlan *) node;
04591 AlternativeSubPlanState *asstate;
04592
04593 if (!parent)
04594 elog(ERROR, "AlternativeSubPlan found with no parent plan");
04595
04596 asstate = ExecInitAlternativeSubPlan(asplan, parent);
04597
04598 state = (ExprState *) asstate;
04599 }
04600 break;
04601 case T_FieldSelect:
04602 {
04603 FieldSelect *fselect = (FieldSelect *) node;
04604 FieldSelectState *fstate = makeNode(FieldSelectState);
04605
04606 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFieldSelect;
04607 fstate->arg = ExecInitExpr(fselect->arg, parent);
04608 fstate->argdesc = NULL;
04609 state = (ExprState *) fstate;
04610 }
04611 break;
04612 case T_FieldStore:
04613 {
04614 FieldStore *fstore = (FieldStore *) node;
04615 FieldStoreState *fstate = makeNode(FieldStoreState);
04616
04617 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFieldStore;
04618 fstate->arg = ExecInitExpr(fstore->arg, parent);
04619 fstate->newvals = (List *) ExecInitExpr((Expr *) fstore->newvals, parent);
04620 fstate->argdesc = NULL;
04621 state = (ExprState *) fstate;
04622 }
04623 break;
04624 case T_RelabelType:
04625 {
04626 RelabelType *relabel = (RelabelType *) node;
04627 GenericExprState *gstate = makeNode(GenericExprState);
04628
04629 gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRelabelType;
04630 gstate->arg = ExecInitExpr(relabel->arg, parent);
04631 state = (ExprState *) gstate;
04632 }
04633 break;
04634 case T_CoerceViaIO:
04635 {
04636 CoerceViaIO *iocoerce = (CoerceViaIO *) node;
04637 CoerceViaIOState *iostate = makeNode(CoerceViaIOState);
04638 Oid iofunc;
04639 bool typisvarlena;
04640
04641 iostate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoerceViaIO;
04642 iostate->arg = ExecInitExpr(iocoerce->arg, parent);
04643
04644 getTypeInputInfo(iocoerce->resulttype, &iofunc,
04645 &iostate->intypioparam);
04646 fmgr_info(iofunc, &iostate->infunc);
04647
04648 getTypeOutputInfo(exprType((Node *) iocoerce->arg),
04649 &iofunc, &typisvarlena);
04650 fmgr_info(iofunc, &iostate->outfunc);
04651 state = (ExprState *) iostate;
04652 }
04653 break;
04654 case T_ArrayCoerceExpr:
04655 {
04656 ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node;
04657 ArrayCoerceExprState *astate = makeNode(ArrayCoerceExprState);
04658
04659 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArrayCoerceExpr;
04660 astate->arg = ExecInitExpr(acoerce->arg, parent);
04661 astate->resultelemtype = get_element_type(acoerce->resulttype);
04662 if (astate->resultelemtype == InvalidOid)
04663 ereport(ERROR,
04664 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
04665 errmsg("target type is not an array")));
04666
04667 Assert(getBaseType(astate->resultelemtype) ==
04668 astate->resultelemtype);
04669 astate->elemfunc.fn_oid = InvalidOid;
04670 astate->amstate = (ArrayMapState *) palloc0(sizeof(ArrayMapState));
04671 state = (ExprState *) astate;
04672 }
04673 break;
04674 case T_ConvertRowtypeExpr:
04675 {
04676 ConvertRowtypeExpr *convert = (ConvertRowtypeExpr *) node;
04677 ConvertRowtypeExprState *cstate = makeNode(ConvertRowtypeExprState);
04678
04679 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalConvertRowtype;
04680 cstate->arg = ExecInitExpr(convert->arg, parent);
04681 state = (ExprState *) cstate;
04682 }
04683 break;
04684 case T_CaseExpr:
04685 {
04686 CaseExpr *caseexpr = (CaseExpr *) node;
04687 CaseExprState *cstate = makeNode(CaseExprState);
04688 List *outlist = NIL;
04689 ListCell *l;
04690
04691 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCase;
04692 cstate->arg = ExecInitExpr(caseexpr->arg, parent);
04693 foreach(l, caseexpr->args)
04694 {
04695 CaseWhen *when = (CaseWhen *) lfirst(l);
04696 CaseWhenState *wstate = makeNode(CaseWhenState);
04697
04698 Assert(IsA(when, CaseWhen));
04699 wstate->xprstate.evalfunc = NULL;
04700 wstate->xprstate.expr = (Expr *) when;
04701 wstate->expr = ExecInitExpr(when->expr, parent);
04702 wstate->result = ExecInitExpr(when->result, parent);
04703 outlist = lappend(outlist, wstate);
04704 }
04705 cstate->args = outlist;
04706 cstate->defresult = ExecInitExpr(caseexpr->defresult, parent);
04707 state = (ExprState *) cstate;
04708 }
04709 break;
04710 case T_ArrayExpr:
04711 {
04712 ArrayExpr *arrayexpr = (ArrayExpr *) node;
04713 ArrayExprState *astate = makeNode(ArrayExprState);
04714 List *outlist = NIL;
04715 ListCell *l;
04716
04717 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArray;
04718 foreach(l, arrayexpr->elements)
04719 {
04720 Expr *e = (Expr *) lfirst(l);
04721 ExprState *estate;
04722
04723 estate = ExecInitExpr(e, parent);
04724 outlist = lappend(outlist, estate);
04725 }
04726 astate->elements = outlist;
04727
04728 get_typlenbyvalalign(arrayexpr->element_typeid,
04729 &astate->elemlength,
04730 &astate->elembyval,
04731 &astate->elemalign);
04732 state = (ExprState *) astate;
04733 }
04734 break;
04735 case T_RowExpr:
04736 {
04737 RowExpr *rowexpr = (RowExpr *) node;
04738 RowExprState *rstate = makeNode(RowExprState);
04739 Form_pg_attribute *attrs;
04740 List *outlist = NIL;
04741 ListCell *l;
04742 int i;
04743
04744 rstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRow;
04745
04746 if (rowexpr->row_typeid == RECORDOID)
04747 {
04748
04749 rstate->tupdesc = ExecTypeFromExprList(rowexpr->args,
04750 rowexpr->colnames);
04751 BlessTupleDesc(rstate->tupdesc);
04752
04753 }
04754 else
04755 {
04756
04757 rstate->tupdesc = lookup_rowtype_tupdesc_copy(rowexpr->row_typeid, -1);
04758 }
04759
04760 Assert(list_length(rowexpr->args) <= rstate->tupdesc->natts);
04761 attrs = rstate->tupdesc->attrs;
04762 i = 0;
04763 foreach(l, rowexpr->args)
04764 {
04765 Expr *e = (Expr *) lfirst(l);
04766 ExprState *estate;
04767
04768 if (!attrs[i]->attisdropped)
04769 {
04770
04771
04772
04773
04774
04775
04776 if (exprType((Node *) e) != attrs[i]->atttypid)
04777 ereport(ERROR,
04778 (errcode(ERRCODE_DATATYPE_MISMATCH),
04779 errmsg("ROW() column has type %s instead of type %s",
04780 format_type_be(exprType((Node *) e)),
04781 format_type_be(attrs[i]->atttypid))));
04782 }
04783 else
04784 {
04785
04786
04787
04788
04789
04790 e = (Expr *) makeNullConst(INT4OID, -1, InvalidOid);
04791 }
04792 estate = ExecInitExpr(e, parent);
04793 outlist = lappend(outlist, estate);
04794 i++;
04795 }
04796 rstate->args = outlist;
04797 state = (ExprState *) rstate;
04798 }
04799 break;
04800 case T_RowCompareExpr:
04801 {
04802 RowCompareExpr *rcexpr = (RowCompareExpr *) node;
04803 RowCompareExprState *rstate = makeNode(RowCompareExprState);
04804 int nopers = list_length(rcexpr->opnos);
04805 List *outlist;
04806 ListCell *l;
04807 ListCell *l2;
04808 ListCell *l3;
04809 int i;
04810
04811 rstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRowCompare;
04812 Assert(list_length(rcexpr->largs) == nopers);
04813 outlist = NIL;
04814 foreach(l, rcexpr->largs)
04815 {
04816 Expr *e = (Expr *) lfirst(l);
04817 ExprState *estate;
04818
04819 estate = ExecInitExpr(e, parent);
04820 outlist = lappend(outlist, estate);
04821 }
04822 rstate->largs = outlist;
04823 Assert(list_length(rcexpr->rargs) == nopers);
04824 outlist = NIL;
04825 foreach(l, rcexpr->rargs)
04826 {
04827 Expr *e = (Expr *) lfirst(l);
04828 ExprState *estate;
04829
04830 estate = ExecInitExpr(e, parent);
04831 outlist = lappend(outlist, estate);
04832 }
04833 rstate->rargs = outlist;
04834 Assert(list_length(rcexpr->opfamilies) == nopers);
04835 rstate->funcs = (FmgrInfo *) palloc(nopers * sizeof(FmgrInfo));
04836 rstate->collations = (Oid *) palloc(nopers * sizeof(Oid));
04837 i = 0;
04838 forthree(l, rcexpr->opnos, l2, rcexpr->opfamilies, l3, rcexpr->inputcollids)
04839 {
04840 Oid opno = lfirst_oid(l);
04841 Oid opfamily = lfirst_oid(l2);
04842 Oid inputcollid = lfirst_oid(l3);
04843 int strategy;
04844 Oid lefttype;
04845 Oid righttype;
04846 Oid proc;
04847
04848 get_op_opfamily_properties(opno, opfamily, false,
04849 &strategy,
04850 &lefttype,
04851 &righttype);
04852 proc = get_opfamily_proc(opfamily,
04853 lefttype,
04854 righttype,
04855 BTORDER_PROC);
04856
04857
04858
04859
04860
04861
04862
04863 fmgr_info(proc, &(rstate->funcs[i]));
04864 rstate->collations[i] = inputcollid;
04865 i++;
04866 }
04867 state = (ExprState *) rstate;
04868 }
04869 break;
04870 case T_CoalesceExpr:
04871 {
04872 CoalesceExpr *coalesceexpr = (CoalesceExpr *) node;
04873 CoalesceExprState *cstate = makeNode(CoalesceExprState);
04874 List *outlist = NIL;
04875 ListCell *l;
04876
04877 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoalesce;
04878 foreach(l, coalesceexpr->args)
04879 {
04880 Expr *e = (Expr *) lfirst(l);
04881 ExprState *estate;
04882
04883 estate = ExecInitExpr(e, parent);
04884 outlist = lappend(outlist, estate);
04885 }
04886 cstate->args = outlist;
04887 state = (ExprState *) cstate;
04888 }
04889 break;
04890 case T_MinMaxExpr:
04891 {
04892 MinMaxExpr *minmaxexpr = (MinMaxExpr *) node;
04893 MinMaxExprState *mstate = makeNode(MinMaxExprState);
04894 List *outlist = NIL;
04895 ListCell *l;
04896 TypeCacheEntry *typentry;
04897
04898 mstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalMinMax;
04899 foreach(l, minmaxexpr->args)
04900 {
04901 Expr *e = (Expr *) lfirst(l);
04902 ExprState *estate;
04903
04904 estate = ExecInitExpr(e, parent);
04905 outlist = lappend(outlist, estate);
04906 }
04907 mstate->args = outlist;
04908
04909 typentry = lookup_type_cache(minmaxexpr->minmaxtype,
04910 TYPECACHE_CMP_PROC);
04911 if (!OidIsValid(typentry->cmp_proc))
04912 ereport(ERROR,
04913 (errcode(ERRCODE_UNDEFINED_FUNCTION),
04914 errmsg("could not identify a comparison function for type %s",
04915 format_type_be(minmaxexpr->minmaxtype))));
04916
04917
04918
04919
04920
04921
04922
04923 fmgr_info(typentry->cmp_proc, &(mstate->cfunc));
04924 state = (ExprState *) mstate;
04925 }
04926 break;
04927 case T_XmlExpr:
04928 {
04929 XmlExpr *xexpr = (XmlExpr *) node;
04930 XmlExprState *xstate = makeNode(XmlExprState);
04931 List *outlist;
04932 ListCell *arg;
04933
04934 xstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalXml;
04935 outlist = NIL;
04936 foreach(arg, xexpr->named_args)
04937 {
04938 Expr *e = (Expr *) lfirst(arg);
04939 ExprState *estate;
04940
04941 estate = ExecInitExpr(e, parent);
04942 outlist = lappend(outlist, estate);
04943 }
04944 xstate->named_args = outlist;
04945
04946 outlist = NIL;
04947 foreach(arg, xexpr->args)
04948 {
04949 Expr *e = (Expr *) lfirst(arg);
04950 ExprState *estate;
04951
04952 estate = ExecInitExpr(e, parent);
04953 outlist = lappend(outlist, estate);
04954 }
04955 xstate->args = outlist;
04956
04957 state = (ExprState *) xstate;
04958 }
04959 break;
04960 case T_NullTest:
04961 {
04962 NullTest *ntest = (NullTest *) node;
04963 NullTestState *nstate = makeNode(NullTestState);
04964
04965 nstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNullTest;
04966 nstate->arg = ExecInitExpr(ntest->arg, parent);
04967 nstate->argdesc = NULL;
04968 state = (ExprState *) nstate;
04969 }
04970 break;
04971 case T_BooleanTest:
04972 {
04973 BooleanTest *btest = (BooleanTest *) node;
04974 GenericExprState *gstate = makeNode(GenericExprState);
04975
04976 gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalBooleanTest;
04977 gstate->arg = ExecInitExpr(btest->arg, parent);
04978 state = (ExprState *) gstate;
04979 }
04980 break;
04981 case T_CoerceToDomain:
04982 {
04983 CoerceToDomain *ctest = (CoerceToDomain *) node;
04984 CoerceToDomainState *cstate = makeNode(CoerceToDomainState);
04985
04986 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoerceToDomain;
04987 cstate->arg = ExecInitExpr(ctest->arg, parent);
04988 cstate->constraints = GetDomainConstraints(ctest->resulttype);
04989 state = (ExprState *) cstate;
04990 }
04991 break;
04992 case T_CurrentOfExpr:
04993 state = (ExprState *) makeNode(ExprState);
04994 state->evalfunc = ExecEvalCurrentOfExpr;
04995 break;
04996 case T_TargetEntry:
04997 {
04998 TargetEntry *tle = (TargetEntry *) node;
04999 GenericExprState *gstate = makeNode(GenericExprState);
05000
05001 gstate->xprstate.evalfunc = NULL;
05002 gstate->arg = ExecInitExpr(tle->expr, parent);
05003 state = (ExprState *) gstate;
05004 }
05005 break;
05006 case T_List:
05007 {
05008 List *outlist = NIL;
05009 ListCell *l;
05010
05011 foreach(l, (List *) node)
05012 {
05013 outlist = lappend(outlist,
05014 ExecInitExpr((Expr *) lfirst(l),
05015 parent));
05016 }
05017
05018 return (ExprState *) outlist;
05019 }
05020 default:
05021 elog(ERROR, "unrecognized node type: %d",
05022 (int) nodeTag(node));
05023 state = NULL;
05024 break;
05025 }
05026
05027
05028 state->expr = node;
05029
05030 return state;
05031 }
05032
05033
05034
05035
05036
05037
05038
05039
05040
05041
05042
05043
05044 ExprState *
05045 ExecPrepareExpr(Expr *node, EState *estate)
05046 {
05047 ExprState *result;
05048 MemoryContext oldcontext;
05049
05050 oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
05051
05052 node = expression_planner(node);
05053
05054 result = ExecInitExpr(node, NULL);
05055
05056 MemoryContextSwitchTo(oldcontext);
05057
05058 return result;
05059 }
05060
05061
05062
05063
05064
05065
05066
05067
05068
05069
05070
05071
05072
05073
05074
05075
05076
05077
05078
05079
05080
05081
05082
05083
05084
05085
05086
05087
05088
05089
05090
05091
05092
05093
05094
05095 bool
05096 ExecQual(List *qual, ExprContext *econtext, bool resultForNull)
05097 {
05098 bool result;
05099 MemoryContext oldContext;
05100 ListCell *l;
05101
05102
05103
05104
05105 EV_printf("ExecQual: qual is ");
05106 EV_nodeDisplay(qual);
05107 EV_printf("\n");
05108
05109
05110
05111
05112 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
05113
05114
05115
05116
05117
05118
05119
05120
05121
05122
05123
05124
05125
05126 result = true;
05127
05128 foreach(l, qual)
05129 {
05130 ExprState *clause = (ExprState *) lfirst(l);
05131 Datum expr_value;
05132 bool isNull;
05133
05134 expr_value = ExecEvalExpr(clause, econtext, &isNull, NULL);
05135
05136 if (isNull)
05137 {
05138 if (resultForNull == false)
05139 {
05140 result = false;
05141 break;
05142 }
05143 }
05144 else
05145 {
05146 if (!DatumGetBool(expr_value))
05147 {
05148 result = false;
05149 break;
05150 }
05151 }
05152 }
05153
05154 MemoryContextSwitchTo(oldContext);
05155
05156 return result;
05157 }
05158
05159
05160
05161
05162 int
05163 ExecTargetListLength(List *targetlist)
05164 {
05165
05166 return list_length(targetlist);
05167 }
05168
05169
05170
05171
05172 int
05173 ExecCleanTargetListLength(List *targetlist)
05174 {
05175 int len = 0;
05176 ListCell *tl;
05177
05178 foreach(tl, targetlist)
05179 {
05180 TargetEntry *curTle = (TargetEntry *) lfirst(tl);
05181
05182 Assert(IsA(curTle, TargetEntry));
05183 if (!curTle->resjunk)
05184 len++;
05185 }
05186 return len;
05187 }
05188
05189
05190
05191
05192
05193
05194
05195
05196
05197
05198
05199
05200
05201
05202
05203
05204 static bool
05205 ExecTargetList(List *targetlist,
05206 ExprContext *econtext,
05207 Datum *values,
05208 bool *isnull,
05209 ExprDoneCond *itemIsDone,
05210 ExprDoneCond *isDone)
05211 {
05212 MemoryContext oldContext;
05213 ListCell *tl;
05214 bool haveDoneSets;
05215
05216
05217
05218
05219 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
05220
05221
05222
05223
05224 haveDoneSets = false;
05225
05226 foreach(tl, targetlist)
05227 {
05228 GenericExprState *gstate = (GenericExprState *) lfirst(tl);
05229 TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
05230 AttrNumber resind = tle->resno - 1;
05231
05232 values[resind] = ExecEvalExpr(gstate->arg,
05233 econtext,
05234 &isnull[resind],
05235 &itemIsDone[resind]);
05236
05237 if (itemIsDone[resind] != ExprSingleResult)
05238 {
05239
05240 if (isDone == NULL)
05241 ereport(ERROR,
05242 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
05243 errmsg("set-valued function called in context that cannot accept a set")));
05244 if (itemIsDone[resind] == ExprMultipleResult)
05245 {
05246
05247 *isDone = ExprMultipleResult;
05248 }
05249 else
05250 {
05251
05252 haveDoneSets = true;
05253 }
05254 }
05255 }
05256
05257 if (haveDoneSets)
05258 {
05259
05260
05261
05262 if (*isDone == ExprSingleResult)
05263 {
05264
05265
05266
05267 *isDone = ExprEndResult;
05268 MemoryContextSwitchTo(oldContext);
05269 return false;
05270 }
05271 else
05272 {
05273
05274
05275
05276
05277 foreach(tl, targetlist)
05278 {
05279 GenericExprState *gstate = (GenericExprState *) lfirst(tl);
05280 TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
05281 AttrNumber resind = tle->resno - 1;
05282
05283 if (itemIsDone[resind] == ExprEndResult)
05284 {
05285 values[resind] = ExecEvalExpr(gstate->arg,
05286 econtext,
05287 &isnull[resind],
05288 &itemIsDone[resind]);
05289
05290 if (itemIsDone[resind] == ExprEndResult)
05291 {
05292
05293
05294
05295
05296 *isDone = ExprEndResult;
05297 break;
05298 }
05299 }
05300 }
05301
05302
05303
05304
05305
05306
05307
05308
05309 if (*isDone == ExprEndResult)
05310 {
05311 foreach(tl, targetlist)
05312 {
05313 GenericExprState *gstate = (GenericExprState *) lfirst(tl);
05314 TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
05315 AttrNumber resind = tle->resno - 1;
05316
05317 while (itemIsDone[resind] == ExprMultipleResult)
05318 {
05319 values[resind] = ExecEvalExpr(gstate->arg,
05320 econtext,
05321 &isnull[resind],
05322 &itemIsDone[resind]);
05323 }
05324 }
05325
05326 MemoryContextSwitchTo(oldContext);
05327 return false;
05328 }
05329 }
05330 }
05331
05332
05333 MemoryContextSwitchTo(oldContext);
05334
05335 return true;
05336 }
05337
05338
05339
05340
05341
05342
05343
05344
05345
05346
05347
05348
05349
05350
05351 TupleTableSlot *
05352 ExecProject(ProjectionInfo *projInfo, ExprDoneCond *isDone)
05353 {
05354 TupleTableSlot *slot;
05355 ExprContext *econtext;
05356 int numSimpleVars;
05357
05358
05359
05360
05361 Assert(projInfo != NULL);
05362
05363
05364
05365
05366 slot = projInfo->pi_slot;
05367 econtext = projInfo->pi_exprContext;
05368
05369
05370 if (isDone)
05371 *isDone = ExprSingleResult;
05372
05373
05374
05375
05376
05377
05378 ExecClearTuple(slot);
05379
05380
05381
05382
05383
05384
05385 if (projInfo->pi_lastInnerVar > 0)
05386 slot_getsomeattrs(econtext->ecxt_innertuple,
05387 projInfo->pi_lastInnerVar);
05388 if (projInfo->pi_lastOuterVar > 0)
05389 slot_getsomeattrs(econtext->ecxt_outertuple,
05390 projInfo->pi_lastOuterVar);
05391 if (projInfo->pi_lastScanVar > 0)
05392 slot_getsomeattrs(econtext->ecxt_scantuple,
05393 projInfo->pi_lastScanVar);
05394
05395
05396
05397
05398
05399 numSimpleVars = projInfo->pi_numSimpleVars;
05400 if (numSimpleVars > 0)
05401 {
05402 Datum *values = slot->tts_values;
05403 bool *isnull = slot->tts_isnull;
05404 int *varSlotOffsets = projInfo->pi_varSlotOffsets;
05405 int *varNumbers = projInfo->pi_varNumbers;
05406 int i;
05407
05408 if (projInfo->pi_directMap)
05409 {
05410
05411 for (i = 0; i < numSimpleVars; i++)
05412 {
05413 char *slotptr = ((char *) econtext) + varSlotOffsets[i];
05414 TupleTableSlot *varSlot = *((TupleTableSlot **) slotptr);
05415 int varNumber = varNumbers[i] - 1;
05416
05417 values[i] = varSlot->tts_values[varNumber];
05418 isnull[i] = varSlot->tts_isnull[varNumber];
05419 }
05420 }
05421 else
05422 {
05423
05424 int *varOutputCols = projInfo->pi_varOutputCols;
05425
05426 for (i = 0; i < numSimpleVars; i++)
05427 {
05428 char *slotptr = ((char *) econtext) + varSlotOffsets[i];
05429 TupleTableSlot *varSlot = *((TupleTableSlot **) slotptr);
05430 int varNumber = varNumbers[i] - 1;
05431 int varOutputCol = varOutputCols[i] - 1;
05432
05433 values[varOutputCol] = varSlot->tts_values[varNumber];
05434 isnull[varOutputCol] = varSlot->tts_isnull[varNumber];
05435 }
05436 }
05437 }
05438
05439
05440
05441
05442
05443
05444
05445 if (projInfo->pi_targetlist)
05446 {
05447 if (!ExecTargetList(projInfo->pi_targetlist,
05448 econtext,
05449 slot->tts_values,
05450 slot->tts_isnull,
05451 projInfo->pi_itemIsDone,
05452 isDone))
05453 return slot;
05454 }
05455
05456
05457
05458
05459
05460 return ExecStoreVirtualTuple(slot);
05461 }