Header And Logo

PostgreSQL
| The world's most advanced open source database.

execQual.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * execQual.c
00004  *    Routines to evaluate qualification and targetlist expressions
00005  *
00006  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00007  * Portions Copyright (c) 1994, Regents of the University of California
00008  *
00009  *
00010  * IDENTIFICATION
00011  *    src/backend/executor/execQual.c
00012  *
00013  *-------------------------------------------------------------------------
00014  */
00015 /*
00016  *   INTERFACE ROUTINES
00017  *      ExecEvalExpr    - (now a macro) evaluate an expression, return a datum
00018  *      ExecEvalExprSwitchContext - same, but switch into eval memory context
00019  *      ExecQual        - return true/false if qualification is satisfied
00020  *      ExecProject     - form a new tuple by projecting the given tuple
00021  *
00022  *   NOTES
00023  *      The more heavily used ExecEvalExpr routines, such as ExecEvalScalarVar,
00024  *      are hotspots. Making these faster will speed up the entire system.
00025  *
00026  *      ExecProject() is used to make tuple projections.  Rather then
00027  *      trying to speed it up, the execution plan should be pre-processed
00028  *      to facilitate attribute sharing between nodes wherever possible,
00029  *      instead of doing needless copying.  -cim 5/31/91
00030  *
00031  *      During expression evaluation, we check_stack_depth only in
00032  *      ExecMakeFunctionResult (and substitute routines) rather than at every
00033  *      single node.  This is a compromise that trades off precision of the
00034  *      stack limit setting to gain speed.
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 /* static function decls */
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  *      ExecEvalExpr routines
00188  *
00189  *      Recursively evaluate a targetlist or qualification expression.
00190  *
00191  * Each of the following routines having the signature
00192  *      Datum ExecEvalFoo(ExprState *expression,
00193  *                        ExprContext *econtext,
00194  *                        bool *isNull,
00195  *                        ExprDoneCond *isDone);
00196  * is responsible for evaluating one type or subtype of ExprState node.
00197  * They are normally called via the ExecEvalExpr macro, which makes use of
00198  * the function pointer set up when the ExprState node was built by
00199  * ExecInitExpr.  (In some cases, we change this pointer later to avoid
00200  * re-executing one-time overhead.)
00201  *
00202  * Note: for notational simplicity we declare these functions as taking the
00203  * specific type of ExprState that they work on.  This requires casting when
00204  * assigning the function pointer in ExecInitExpr.  Be careful that the
00205  * function signature is declared correctly, because the cast suppresses
00206  * automatic checking!
00207  *
00208  *
00209  * All these functions share this calling convention:
00210  *
00211  * Inputs:
00212  *      expression: the expression state tree to evaluate
00213  *      econtext: evaluation context information
00214  *
00215  * Outputs:
00216  *      return value: Datum value of result
00217  *      *isNull: set to TRUE if result is NULL (actual return value is
00218  *               meaningless if so); set to FALSE if non-null result
00219  *      *isDone: set to indicator of set-result status
00220  *
00221  * A caller that can only accept a singleton (non-set) result should pass
00222  * NULL for isDone; if the expression computes a set result then an error
00223  * will be reported via ereport.  If the caller does pass an isDone pointer
00224  * then *isDone is set to one of these three states:
00225  *      ExprSingleResult        singleton result (not a set)
00226  *      ExprMultipleResult      return value is one element of a set
00227  *      ExprEndResult           there are no more elements in the set
00228  * When ExprMultipleResult is returned, the caller should invoke
00229  * ExecEvalExpr() repeatedly until ExprEndResult is returned.  ExprEndResult
00230  * is returned after the last real set element.  For convenience isNull will
00231  * always be set TRUE when ExprEndResult is returned, but this should not be
00232  * taken as indicating a NULL element of the set.  Note that these return
00233  * conventions allow us to distinguish among a singleton NULL, a NULL element
00234  * of a set, and an empty set.
00235  *
00236  * The caller should already have switched into the temporary memory
00237  * context econtext->ecxt_per_tuple_memory.  The convenience entry point
00238  * ExecEvalExprSwitchContext() is provided for callers who don't prefer to
00239  * do the switch in an outer loop.  We do not do the switch in these routines
00240  * because it'd be a waste of cycles during nested expression evaluation.
00241  * ----------------------------------------------------------------
00242  */
00243 
00244 
00245 /*----------
00246  *    ExecEvalArrayRef
00247  *
00248  *     This function takes an ArrayRef and returns the extracted Datum
00249  *     if it's a simple reference, or the modified array value if it's
00250  *     an array assignment (i.e., array element or slice insertion).
00251  *
00252  * NOTE: if we get a NULL result from a subscript expression, we return NULL
00253  * when it's an array reference, or raise an error when it's an assignment.
00254  *
00255  * NOTE: we deliberately refrain from applying DatumGetArrayTypeP() here,
00256  * even though that might seem natural, because this code needs to support
00257  * both varlena arrays and fixed-length array types.  DatumGetArrayTypeP()
00258  * only works for the varlena kind.  The routines we call in arrayfuncs.c
00259  * have to know the difference (that's what they need refattrlength for).
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      * If refexpr yields NULL, and it's a fetch, then result is NULL. In the
00288      * assignment case, we'll cons up something below.
00289      */
00290     if (*isNull)
00291     {
00292         if (isDone && *isDone == ExprEndResult)
00293             return (Datum) NULL;    /* end of set result */
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         /* If any index expr yields NULL, result is NULL or error */
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             /* If any index expr yields NULL, result is NULL or error */
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         /* this can't happen unless parser messed up */
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          * We might have a nested-assignment situation, in which the
00367          * refassgnexpr is itself a FieldStore or ArrayRef that needs to
00368          * obtain and modify the previous value of the array element or slice
00369          * being replaced.  If so, we have to extract that value from the
00370          * array and pass it down via the econtext's caseValue.  It's safe to
00371          * reuse the CASE mechanism because there cannot be a CASE between
00372          * here and where the value would be needed, and an array assignment
00373          * can't be within a CASE either.  (So saving and restoring the
00374          * caseValue is just paranoia, but let's do it anyway.)
00375          *
00376          * Since fetching the old element might be a nontrivial expense, do it
00377          * only if the argument appears to actually need it.
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                 /* whole array is null, so any element or slice is too */
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             /* argument shouldn't need caseValue, but for safety set it null */
00415             econtext->caseValue_datum = (Datum) 0;
00416             econtext->caseValue_isNull = true;
00417         }
00418 
00419         /*
00420          * Evaluate the value to be assigned into the array.
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          * For an assignment to a fixed-length array type, both the original
00432          * array and the value to be assigned into it must be non-NULL, else
00433          * we punt and return the original array.
00434          */
00435         if (astate->refattrlength > 0)  /* fixed-length array? */
00436             if (eisnull || *isNull)
00437                 return PointerGetDatum(array_source);
00438 
00439         /*
00440          * For assignment to varlena arrays, we handle a NULL original array
00441          * by substituting an empty (zero-dimensional) array; insertion of the
00442          * new element will result in a singleton array value.  It does not
00443          * matter whether the new element is NULL.
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  * Helper for ExecEvalArrayRef: is expr a nested FieldStore or ArrayRef
00493  * that might need the old element value passed down?
00494  *
00495  * (We could use this in ExecEvalFieldStore too, but in that case passing
00496  * the old value is so cheap there's no need.)
00497  */
00498 static bool
00499 isAssignmentIndirectionExpr(ExprState *exprstate)
00500 {
00501     if (exprstate == NULL)
00502         return false;           /* just paranoia */
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  *      ExecEvalAggref
00522  *
00523  *      Returns a Datum whose value is the value of the precomputed
00524  *      aggregate found in the given expression context.
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)       /* safety check */
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  *      ExecEvalWindowFunc
00543  *
00544  *      Returns a Datum whose value is the value of the precomputed
00545  *      window function found in the given expression context.
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)       /* safety check */
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  *      ExecEvalScalarVar
00564  *
00565  *      Returns a Datum whose value is the value of a scalar (not whole-row)
00566  *      range variable with respect to given expression context.
00567  *
00568  * Note: ExecEvalScalarVar is executed only the first time through in a given
00569  * plan; it changes the ExprState's function pointer to pass control directly
00570  * to ExecEvalScalarVarFast after making one-time checks.
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     /* Get the input slot and attribute number we want */
00585     switch (variable->varno)
00586     {
00587         case INNER_VAR: /* get the tuple from the inner node */
00588             slot = econtext->ecxt_innertuple;
00589             break;
00590 
00591         case OUTER_VAR: /* get the tuple from the outer node */
00592             slot = econtext->ecxt_outertuple;
00593             break;
00594 
00595             /* INDEX_VAR is handled by default case */
00596 
00597         default:                /* get the tuple from the relation being
00598                                  * scanned */
00599             slot = econtext->ecxt_scantuple;
00600             break;
00601     }
00602 
00603     attnum = variable->varattno;
00604 
00605     /* This was checked by ExecInitExpr */
00606     Assert(attnum != InvalidAttrNumber);
00607 
00608     /*
00609      * If it's a user attribute, check validity (bogus system attnums will be
00610      * caught inside slot_getattr).  What we have to check for here is the
00611      * possibility of an attribute having been changed in type since the plan
00612      * tree was created.  Ideally the plan will get invalidated and not
00613      * re-used, but just in case, we keep these defenses.  Fortunately it's
00614      * sufficient to check once on the first time through.
00615      *
00616      * Note: we allow a reference to a dropped attribute.  slot_getattr will
00617      * force a NULL result in such cases.
00618      *
00619      * Note: ideally we'd check typmod as well as typid, but that seems
00620      * impractical at the moment: in many cases the tupdesc will have been
00621      * generated by ExecTypeFromTL(), and that can't guarantee to generate an
00622      * accurate typmod in all cases, because some expression node types don't
00623      * carry typmod.
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)       /* should never happen */
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         /* can't check type if dropped, since atttypid is probably 0 */
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     /* Skip the checking on future executions of node */
00649     exprstate->evalfunc = ExecEvalScalarVarFast;
00650 
00651     /* Fetch the value from the slot */
00652     return slot_getattr(slot, attnum, isNull);
00653 }
00654 
00655 /* ----------------------------------------------------------------
00656  *      ExecEvalScalarVarFast
00657  *
00658  *      Returns a Datum for a scalar variable.
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     /* Get the input slot and attribute number we want */
00673     switch (variable->varno)
00674     {
00675         case INNER_VAR: /* get the tuple from the inner node */
00676             slot = econtext->ecxt_innertuple;
00677             break;
00678 
00679         case OUTER_VAR: /* get the tuple from the outer node */
00680             slot = econtext->ecxt_outertuple;
00681             break;
00682 
00683             /* INDEX_VAR is handled by default case */
00684 
00685         default:                /* get the tuple from the relation being
00686                                  * scanned */
00687             slot = econtext->ecxt_scantuple;
00688             break;
00689     }
00690 
00691     attnum = variable->varattno;
00692 
00693     /* Fetch the value from the slot */
00694     return slot_getattr(slot, attnum, isNull);
00695 }
00696 
00697 /* ----------------------------------------------------------------
00698  *      ExecEvalWholeRowVar
00699  *
00700  *      Returns a Datum whose value is the value of a whole-row range
00701  *      variable with respect to given expression context.
00702  *
00703  * Note: ExecEvalWholeRowVar is executed only the first time through in a
00704  * given plan; it changes the ExprState's function pointer to pass control
00705  * directly to ExecEvalWholeRowFast or ExecEvalWholeRowSlow after making
00706  * one-time checks.
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     /* This was checked by ExecInitExpr */
00722     Assert(variable->varattno == InvalidAttrNumber);
00723 
00724     /* Get the input slot we want */
00725     switch (variable->varno)
00726     {
00727         case INNER_VAR: /* get the tuple from the inner node */
00728             slot = econtext->ecxt_innertuple;
00729             break;
00730 
00731         case OUTER_VAR: /* get the tuple from the outer node */
00732             slot = econtext->ecxt_outertuple;
00733             break;
00734 
00735             /* INDEX_VAR is handled by default case */
00736 
00737         default:                /* get the tuple from the relation being
00738                                  * scanned */
00739             slot = econtext->ecxt_scantuple;
00740             break;
00741     }
00742 
00743     /*
00744      * If the input tuple came from a subquery, it might contain "resjunk"
00745      * columns (such as GROUP BY or ORDER BY columns), which we don't want to
00746      * keep in the whole-row result.  We can get rid of such columns by
00747      * passing the tuple through a JunkFilter --- but to make one, we have to
00748      * lay our hands on the subquery's targetlist.  Fortunately, there are not
00749      * very many cases where this can happen, and we can identify all of them
00750      * by examining our parent PlanState.  We assume this is not an issue in
00751      * standalone expressions that don't have parent plans.  (Whole-row Vars
00752      * can occur in such expressions, but they will always be referencing
00753      * table rows.)
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             /* Detect whether subplan tlist actually has any junk columns */
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             /* If so, build the junkfilter in the query memory context */
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     /* Apply the junkfilter if any */
00804     if (wrvstate->wrv_junkFilter != NULL)
00805         slot = ExecFilterJunk(wrvstate->wrv_junkFilter, slot);
00806 
00807     slot_tupdesc = slot->tts_tupleDescriptor;
00808 
00809     /*
00810      * If it's a RECORD Var, we'll use the slot's type ID info.  It's likely
00811      * that the slot's type is also RECORD; if so, make sure it's been
00812      * "blessed", so that the Datum can be interpreted later.
00813      *
00814      * If the Var identifies a named composite type, we must check that the
00815      * actual tuple type is compatible with it.
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          * We really only care about numbers of attributes and data types.
00830          * Also, we can ignore type mismatch on columns that are dropped in
00831          * the destination type, so long as (1) the physical storage matches
00832          * or (2) the actual column value is NULL.  Case (1) is helpful in
00833          * some cases involving out-of-date cached plans, while case (2) is
00834          * expected behavior in situations such as an INSERT into a table with
00835          * dropped columns (the planner typically generates an INT4 NULL
00836          * regardless of the dropped column type).  If we find a dropped
00837          * column and cannot verify that case (1) holds, we have to use
00838          * ExecEvalWholeRowSlow to check (2) for each row.
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;       /* no worries */
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;    /* need runtime check for null */
00871         }
00872 
00873         ReleaseTupleDesc(var_tupdesc);
00874     }
00875 
00876     /* Skip the checking on future executions of node */
00877     if (needslow)
00878         wrvstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalWholeRowSlow;
00879     else
00880         wrvstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalWholeRowFast;
00881 
00882     /* Fetch the value */
00883     return (*wrvstate->xprstate.evalfunc) ((ExprState *) wrvstate, econtext,
00884                                            isNull, isDone);
00885 }
00886 
00887 /* ----------------------------------------------------------------
00888  *      ExecEvalWholeRowFast
00889  *
00890  *      Returns a Datum for a whole-row variable.
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     /* Get the input slot we want */
00908     switch (variable->varno)
00909     {
00910         case INNER_VAR: /* get the tuple from the inner node */
00911             slot = econtext->ecxt_innertuple;
00912             break;
00913 
00914         case OUTER_VAR: /* get the tuple from the outer node */
00915             slot = econtext->ecxt_outertuple;
00916             break;
00917 
00918             /* INDEX_VAR is handled by default case */
00919 
00920         default:                /* get the tuple from the relation being
00921                                  * scanned */
00922             slot = econtext->ecxt_scantuple;
00923             break;
00924     }
00925 
00926     /* Apply the junkfilter if any */
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      * We have to make a copy of the tuple so we can safely insert the Datum
00935      * overhead fields, which are not set in on-disk tuples.
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      * If the Var identifies a named composite type, label the tuple with that
00944      * type; otherwise use what is in the tupleDesc.
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  *      ExecEvalWholeRowSlow
00962  *
00963  *      Returns a Datum for a whole-row variable, in the "slow" case where
00964  *      we can't just copy the subplan's output.
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     /* Get the input slot we want */
00984     switch (variable->varno)
00985     {
00986         case INNER_VAR: /* get the tuple from the inner node */
00987             slot = econtext->ecxt_innertuple;
00988             break;
00989 
00990         case OUTER_VAR: /* get the tuple from the outer node */
00991             slot = econtext->ecxt_outertuple;
00992             break;
00993 
00994             /* INDEX_VAR is handled by default case */
00995 
00996         default:                /* get the tuple from the relation being
00997                                  * scanned */
00998             slot = econtext->ecxt_scantuple;
00999             break;
01000     }
01001 
01002     /* Apply the junkfilter if any */
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     /* Check to see if any dropped attributes are non-null */
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;           /* already checked non-dropped cols */
01020         if (heap_attisnull(tuple, i + 1))
01021             continue;           /* null is always okay */
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      * We have to make a copy of the tuple so we can safely insert the Datum
01033      * overhead fields, which are not set in on-disk tuples.
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  *      ExecEvalConst
01049  *
01050  *      Returns the value of a constant.
01051  *
01052  *      Note that for pass-by-ref datatypes, we return a pointer to the
01053  *      actual constant node.  This is one of the reasons why functions
01054  *      must treat their input arguments as read-only.
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  *      ExecEvalParamExec
01072  *
01073  *      Returns the value of a PARAM_EXEC parameter.
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      * PARAM_EXEC params (internal executor parameters) are stored in the
01089      * ecxt_param_exec_vals array, and can be accessed by array index.
01090      */
01091     prm = &(econtext->ecxt_param_exec_vals[thisParamId]);
01092     if (prm->execPlan != NULL)
01093     {
01094         /* Parameter not evaluated yet, so go do it */
01095         ExecSetParamPlan(prm->execPlan, econtext);
01096         /* ExecSetParamPlan should have processed this param... */
01097         Assert(prm->execPlan == NULL);
01098     }
01099     *isNull = prm->isnull;
01100     return prm->value;
01101 }
01102 
01103 /* ----------------------------------------------------------------
01104  *      ExecEvalParamExtern
01105  *
01106  *      Returns the value of a PARAM_EXTERN parameter.
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      * PARAM_EXTERN parameters must be sought in ecxt_param_list_info.
01122      */
01123     if (paramInfo &&
01124         thisParamId > 0 && thisParamId <= paramInfo->numParams)
01125     {
01126         ParamExternData *prm = &paramInfo->params[thisParamId - 1];
01127 
01128         /* give hook a chance in case parameter is dynamic */
01129         if (!OidIsValid(prm->ptype) && paramInfo->paramFetch != NULL)
01130             (*paramInfo->paramFetch) (paramInfo, thisParamId);
01131 
01132         if (OidIsValid(prm->ptype))
01133         {
01134             /* safety check in case hook did something unexpected */
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;           /* keep compiler quiet */
01152 }
01153 
01154 
01155 /* ----------------------------------------------------------------
01156  *      ExecEvalOper / ExecEvalFunc support routines
01157  * ----------------------------------------------------------------
01158  */
01159 
01160 /*
01161  *      GetAttributeByName
01162  *      GetAttributeByNum
01163  *
01164  *      These functions return the value of the requested attribute
01165  *      out of the given tuple Datum.
01166  *      C functions which take a tuple as an argument are expected
01167  *      to use these.  Ex: overpaid(EMP) might call GetAttributeByNum().
01168  *      Note: these are actually rather slow because they do a typcache
01169  *      lookup on each call.
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         /* Kinda bogus but compatible with old behavior... */
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      * heap_getattr needs a HeapTuple not a bare HeapTupleHeader.  We set all
01201      * the fields in the struct just in case user tries to inspect system
01202      * columns.
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         /* Kinda bogus but compatible with old behavior... */
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      * heap_getattr needs a HeapTuple not a bare HeapTupleHeader.  We set all
01262      * the fields in the struct just in case user tries to inspect system
01263      * columns.
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  * init_fcache - initialize a FuncExprState node during first use
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     /* Check permission to call function */
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      * Safety check on nargs.  Under normal circumstances this should never
01297      * fail, as parser should check sooner.  But possibly it might fail if
01298      * server has been compiled with FUNC_MAX_ARGS smaller than some functions
01299      * declared in pg_proc?
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     /* Set up the primary fmgr lookup information */
01310     fmgr_info_cxt(foid, &(fcache->func), fcacheCxt);
01311     fmgr_info_set_expr((Node *) fcache->xprstate.expr, &(fcache->func));
01312 
01313     /* Initialize the function call parameter struct as well */
01314     InitFunctionCallInfoData(fcache->fcinfo_data, &(fcache->func),
01315                              list_length(fcache->args),
01316                              input_collation, NULL, NULL);
01317 
01318     /* If function returns set, prepare expected tuple descriptor */
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         /* Must save tupdesc in fcache's context */
01331         oldcontext = MemoryContextSwitchTo(fcacheCxt);
01332 
01333         if (functypclass == TYPEFUNC_COMPOSITE)
01334         {
01335             /* Composite data type, e.g. a table's row type */
01336             Assert(tupdesc);
01337             /* Must copy it out of typcache for safety */
01338             fcache->funcResultDesc = CreateTupleDescCopy(tupdesc);
01339             fcache->funcReturnsTuple = true;
01340         }
01341         else if (functypclass == TYPEFUNC_SCALAR)
01342         {
01343             /* Base data type, i.e. scalar */
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             /* This will work if function doesn't need an expectedDesc */
01357             fcache->funcResultDesc = NULL;
01358             fcache->funcReturnsTuple = true;
01359         }
01360         else
01361         {
01362             /* Else, we will fail if function needs an expectedDesc */
01363             fcache->funcResultDesc = NULL;
01364         }
01365 
01366         MemoryContextSwitchTo(oldcontext);
01367     }
01368     else
01369         fcache->funcResultDesc = NULL;
01370 
01371     /* Initialize additional state */
01372     fcache->funcResultStore = NULL;
01373     fcache->funcResultSlot = NULL;
01374     fcache->setArgsValid = false;
01375     fcache->shutdown_reg = false;
01376 }
01377 
01378 /*
01379  * callback function in case a FuncExpr returning a set needs to be shut down
01380  * before it has been run to completion
01381  */
01382 static void
01383 ShutdownFuncExpr(Datum arg)
01384 {
01385     FuncExprState *fcache = (FuncExprState *) DatumGetPointer(arg);
01386 
01387     /* If we have a slot, make sure it's let go of any tuplestore pointer */
01388     if (fcache->funcResultSlot)
01389         ExecClearTuple(fcache->funcResultSlot);
01390 
01391     /* Release any open tuplestore */
01392     if (fcache->funcResultStore)
01393         tuplestore_end(fcache->funcResultStore);
01394     fcache->funcResultStore = NULL;
01395 
01396     /* Clear any active set-argument state */
01397     fcache->setArgsValid = false;
01398 
01399     /* execUtils will deregister the callback... */
01400     fcache->shutdown_reg = false;
01401 }
01402 
01403 /*
01404  * get_cached_rowtype: utility function to lookup a rowtype tupdesc
01405  *
01406  * type_id, typmod: identity of the rowtype
01407  * cache_field: where to cache the TupleDesc pointer in expression state node
01408  *      (field must be initialized to NULL)
01409  * econtext: expression context we are executing in
01410  *
01411  * NOTE: because the shutdown callback will be called during plan rescan,
01412  * must be prepared to re-do this during any node execution; cannot call
01413  * just once during expression initialization
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     /* Do lookup if no cached value or if requested type changed */
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             /* Release old tupdesc; but callback is already registered */
01431             ReleaseTupleDesc(*cache_field);
01432         }
01433         else
01434         {
01435             /* Need to register shutdown callback to release tupdesc */
01436             RegisterExprContextCallback(econtext,
01437                                         ShutdownTupleDescRef,
01438                                         PointerGetDatum(cache_field));
01439         }
01440         *cache_field = tupDesc;
01441     }
01442     return tupDesc;
01443 }
01444 
01445 /*
01446  * Callback function to release a tupdesc refcount at expression tree shutdown
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  * Evaluate arguments for a function.
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;       /* default assumption */
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              * We allow only one argument to have a set value; we'd need much
01487              * more complexity to keep track of multiple set arguments (cf.
01488              * ExecTargetList) and it doesn't seem worth it.
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  *      ExecPrepareTuplestoreResult
01506  *
01507  * Subroutine for ExecMakeFunctionResult: prepare to extract rows from a
01508  * tuplestore function result.  We must set up a funcResultSlot (unless
01509  * already done in a previous call cycle) and verify that the function
01510  * returned the expected tuple descriptor.
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         /* Create a slot so we can read data out of the tuplestore */
01523         TupleDesc   slotDesc;
01524         MemoryContext oldcontext;
01525 
01526         oldcontext = MemoryContextSwitchTo(fcache->func.fn_mcxt);
01527 
01528         /*
01529          * If we were not able to determine the result rowtype from context,
01530          * and the function didn't return a tupdesc, we have to fail.
01531          */
01532         if (fcache->funcResultDesc)
01533             slotDesc = fcache->funcResultDesc;
01534         else if (resultDesc)
01535         {
01536             /* don't assume resultDesc is long-lived */
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;    /* keep compiler quiet */
01546         }
01547 
01548         fcache->funcResultSlot = MakeSingleTupleTableSlot(slotDesc);
01549         MemoryContextSwitchTo(oldcontext);
01550     }
01551 
01552     /*
01553      * If function provided a tupdesc, cross-check it.  We only really need to
01554      * do this for functions returning RECORD, but might as well do it always.
01555      */
01556     if (resultDesc)
01557     {
01558         if (fcache->funcResultDesc)
01559             tupledesc_match(fcache->funcResultDesc, resultDesc);
01560 
01561         /*
01562          * If it is a dynamically-allocated TupleDesc, free it: it is
01563          * typically allocated in a per-query context, so we must avoid
01564          * leaking it across multiple usages.
01565          */
01566         if (resultDesc->tdrefcount == -1)
01567             FreeTupleDesc(resultDesc);
01568     }
01569 
01570     /* Register cleanup callback if we didn't already */
01571     if (!fcache->shutdown_reg)
01572     {
01573         RegisterExprContextCallback(econtext,
01574                                     ShutdownFuncExpr,
01575                                     PointerGetDatum(fcache));
01576         fcache->shutdown_reg = true;
01577     }
01578 }
01579 
01580 /*
01581  * Check that function result tuple type (src_tupdesc) matches or can
01582  * be considered to match what the query expects (dst_tupdesc). If
01583  * they don't match, ereport.
01584  *
01585  * We really only care about number of attributes and data type.
01586  * Also, we can ignore type mismatch on columns that are dropped in the
01587  * destination type, so long as the physical storage matches.  This is
01588  * helpful in some cases involving out-of-date cached plans.
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;           /* no worries */
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  *      ExecMakeFunctionResult
01632  *
01633  * Evaluate the arguments to a function and then the function itself.
01634  * init_fcache is presumed already run on the FuncExprState.
01635  *
01636  * This function handles the most general case, wherein the function or
01637  * one of its arguments might (or might not) return a set.  If we find
01638  * no sets involved, we will change the FuncExprState's function pointer
01639  * to use a simpler method on subsequent calls.
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;       /* for functions returning sets */
01652     ExprDoneCond argDone;
01653     bool        hasSetArg;
01654     int         i;
01655 
01656 restart:
01657 
01658     /* Guard against stack overflow due to overly complex expressions */
01659     check_stack_depth();
01660 
01661     /*
01662      * If a previous call of the function returned a set result in the form of
01663      * a tuplestore, continue reading rows from the tuplestore until it's
01664      * empty.
01665      */
01666     if (fcache->funcResultStore)
01667     {
01668         Assert(isDone);         /* it was provided before ... */
01669         if (tuplestore_gettupleslot(fcache->funcResultStore, true, false,
01670                                     fcache->funcResultSlot))
01671         {
01672             *isDone = ExprMultipleResult;
01673             if (fcache->funcReturnsTuple)
01674             {
01675                 /* We must return the whole tuple as a Datum. */
01676                 *isNull = false;
01677                 return ExecFetchSlotTupleDatum(fcache->funcResultSlot);
01678             }
01679             else
01680             {
01681                 /* Extract the first column and return it as a scalar. */
01682                 return slot_getattr(fcache->funcResultSlot, 1, isNull);
01683             }
01684         }
01685         /* Exhausted the tuplestore, so clean up */
01686         tuplestore_end(fcache->funcResultStore);
01687         fcache->funcResultStore = NULL;
01688         /* We are done unless there was a set-valued argument */
01689         if (!fcache->setHasSetArg)
01690         {
01691             *isDone = ExprEndResult;
01692             *isNull = true;
01693             return (Datum) 0;
01694         }
01695         /* If there was, continue evaluating the argument values */
01696         Assert(!fcache->setArgsValid);
01697     }
01698 
01699     /*
01700      * arguments is a list of expressions to evaluate before passing to the
01701      * function manager.  We skip the evaluation if it was already done in the
01702      * previous call (ie, we are continuing the evaluation of a set-valued
01703      * function).  Otherwise, collect the current argument values into fcinfo.
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             /* input is an empty set, so return an empty set. */
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         /* Re-use callinfo from previous evaluation */
01727         hasSetArg = fcache->setHasSetArg;
01728         /* Reset flag (we may set it again below) */
01729         fcache->setArgsValid = false;
01730     }
01731 
01732     /*
01733      * Now call the function, passing the evaluated parameter values.
01734      */
01735     if (fcache->func.fn_retset || hasSetArg)
01736     {
01737         /*
01738          * We need to return a set result.  Complain if caller not ready to
01739          * accept one.
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          * Prepare a resultinfo node for communication.  If the function
01748          * doesn't itself return set, we don't pass the resultinfo to the
01749          * function, but we need to fill it in anyway for internal use.
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         /* note we do not set SFRM_Materialize_Random or _Preferred */
01758         rsinfo.returnMode = SFRM_ValuePerCall;
01759         /* isDone is filled below */
01760         rsinfo.setResult = NULL;
01761         rsinfo.setDesc = NULL;
01762 
01763         /*
01764          * This loop handles the situation where we have both a set argument
01765          * and a set-valued function.  Once we have exhausted the function's
01766          * value(s) for a particular argument value, we have to get the next
01767          * argument value and start the function over again. We might have to
01768          * do it more than once, if the function produces an empty result set
01769          * for a particular input value.
01770          */
01771         for (;;)
01772         {
01773             /*
01774              * If function is strict, and there are any NULL arguments, skip
01775              * calling the function (at least for this set of args).
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             /* Which protocol does function want to use? */
01812             if (rsinfo.returnMode == SFRM_ValuePerCall)
01813             {
01814                 if (*isDone != ExprEndResult)
01815                 {
01816                     /*
01817                      * Got a result from current argument. If function itself
01818                      * returns set, save the current argument values to re-use
01819                      * on the next call.
01820                      */
01821                     if (fcache->func.fn_retset &&
01822                         *isDone == ExprMultipleResult)
01823                     {
01824                         fcache->setHasSetArg = hasSetArg;
01825                         fcache->setArgsValid = true;
01826                         /* Register cleanup callback if we didn't already */
01827                         if (!fcache->shutdown_reg)
01828                         {
01829                             RegisterExprContextCallback(econtext,
01830                                                         ShutdownFuncExpr,
01831                                                     PointerGetDatum(fcache));
01832                             fcache->shutdown_reg = true;
01833                         }
01834                     }
01835 
01836                     /*
01837                      * Make sure we say we are returning a set, even if the
01838                      * function itself doesn't return sets.
01839                      */
01840                     if (hasSetArg)
01841                         *isDone = ExprMultipleResult;
01842                     break;
01843                 }
01844             }
01845             else if (rsinfo.returnMode == SFRM_Materialize)
01846             {
01847                 /* check we're on the same page as the function author */
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                     /* prepare to return values from the tuplestore */
01855                     ExecPrepareTuplestoreResult(fcache, econtext,
01856                                                 rsinfo.setResult,
01857                                                 rsinfo.setDesc);
01858                     /* remember whether we had set arguments */
01859                     fcache->setHasSetArg = hasSetArg;
01860                     /* loop back to top to start returning from tuplestore */
01861                     goto restart;
01862                 }
01863                 /* if setResult was left null, treat it as empty set */
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             /* Else, done with this argument */
01875             if (!hasSetArg)
01876                 break;          /* input not a set, so done */
01877 
01878             /* Re-eval args to get the next element of the input set */
01879             argDone = ExecEvalFuncArgs(fcinfo, arguments, econtext);
01880 
01881             if (argDone != ExprMultipleResult)
01882             {
01883                 /* End of argument set, so we're done. */
01884                 *isNull = true;
01885                 *isDone = ExprEndResult;
01886                 result = (Datum) 0;
01887                 break;
01888             }
01889 
01890             /*
01891              * If we reach here, loop around to run the function on the new
01892              * argument.
01893              */
01894         }
01895     }
01896     else
01897     {
01898         /*
01899          * Non-set case: much easier.
01900          *
01901          * We change the ExprState function pointer to use the simpler
01902          * ExecMakeFunctionResultNoSets on subsequent calls.  This amounts to
01903          * assuming that no argument can return a set if it didn't do so the
01904          * first time.
01905          */
01906         fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResultNoSets;
01907 
01908         if (isDone)
01909             *isDone = ExprSingleResult;
01910 
01911         /*
01912          * If function is strict, and there are any NULL arguments, skip
01913          * calling the function and return NULL.
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  *      ExecMakeFunctionResultNoSets
01941  *
01942  * Simplified version of ExecMakeFunctionResult that can only handle
01943  * non-set cases.  Hand-tuned for speed.
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     /* Guard against stack overflow due to overly complex expressions */
01958     check_stack_depth();
01959 
01960     if (isDone)
01961         *isDone = ExprSingleResult;
01962 
01963     /* inlined, simplified version of ExecEvalFuncArgs */
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      * If function is strict, and there are any NULL arguments, skip calling
01979      * the function and return NULL.
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  *      ExecMakeTableFunctionResult
02007  *
02008  * Evaluate a table function, producing a materialized result in a Tuplestore
02009  * object.
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      * Prepare a resultinfo node for communication.  We always do this even if
02039      * not expecting a set result, so that we can pass expectedDesc.  In the
02040      * generic-expression case, the expression doesn't actually get to see the
02041      * resultinfo, but set it up anyway because we use some of the fields as
02042      * our own state variables.
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     /* isDone is filled below */
02052     rsinfo.setResult = NULL;
02053     rsinfo.setDesc = NULL;
02054 
02055     /*
02056      * Normally the passed expression tree will be a FuncExprState, since the
02057      * grammar only allows a function call at the top level of a table
02058      * function reference.  However, if the function doesn't return set then
02059      * the planner might have replaced the function call via constant-folding
02060      * or inlining.  So if we see any other kind of expression node, execute
02061      * it via the general ExecEvalExpr() code; the only difference is that we
02062      * don't get a chance to pass a special ReturnSetInfo to any functions
02063      * buried in the expression.
02064      */
02065     if (funcexpr && IsA(funcexpr, FuncExprState) &&
02066         IsA(funcexpr->expr, FuncExpr))
02067     {
02068         FuncExprState *fcache = (FuncExprState *) funcexpr;
02069         ExprDoneCond argDone;
02070 
02071         /*
02072          * This path is similar to ExecMakeFunctionResult.
02073          */
02074         direct_function_call = true;
02075 
02076         /*
02077          * Initialize function cache if first time through
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          * Evaluate the function's argument list.
02094          *
02095          * Note: ideally, we'd do this in the per-tuple context, but then the
02096          * argument values would disappear when we reset the context in the
02097          * inner loop.  So do it in caller context.  Perhaps we should make a
02098          * separate context just to hold the evaluated arguments?
02099          */
02100         argDone = ExecEvalFuncArgs(&fcinfo, fcache->args, econtext);
02101         /* We don't allow sets in the arguments of the table function */
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          * If function is strict, and there are any NULL arguments, skip
02109          * calling the function and act like it returned NULL (or an empty
02110          * set, in the returns-set case).
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         /* Treat funcexpr as a generic expression */
02126         direct_function_call = false;
02127         InitFunctionCallInfoData(fcinfo, NULL, 0, InvalidOid, NULL, NULL);
02128     }
02129 
02130     /*
02131      * Switch to short-lived context for calling the function or expression.
02132      */
02133     MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
02134 
02135     /*
02136      * Loop to handle the ValuePerCall protocol (which is also the same
02137      * behavior needed in the generic ExecEvalExpr path).
02138      */
02139     for (;;)
02140     {
02141         Datum       result;
02142 
02143         CHECK_FOR_INTERRUPTS();
02144 
02145         /*
02146          * reset per-tuple memory context before each call of the function or
02147          * expression. This cleans up any local memory the function may leak
02148          * when called.
02149          */
02150         ResetExprContext(econtext);
02151 
02152         /* Call the function or expression one time */
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         /* Which protocol does function want to use? */
02171         if (rsinfo.returnMode == SFRM_ValuePerCall)
02172         {
02173             /*
02174              * Check for end of result set.
02175              */
02176             if (rsinfo.isDone == ExprEndResult)
02177                 break;
02178 
02179             /*
02180              * Can't do anything very useful with NULL rowtype values. For a
02181              * function returning set, we consider this a protocol violation
02182              * (but another alternative would be to just ignore the result and
02183              * "continue" to get another row).  For a function not returning
02184              * set, we fall out of the loop; we'll cons up an all-nulls result
02185              * row below.
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              * If first time through, build tupdesc and tuplestore for result
02198              */
02199             if (first_time)
02200             {
02201                 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
02202                 if (returnsTuple)
02203                 {
02204                     /*
02205                      * Use the type info embedded in the rowtype Datum to look
02206                      * up the needed tupdesc.  Make a copy for the query.
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                      * Scalar type, so make a single-column descriptor
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              * Store current resultset item.
02235              */
02236             if (returnsTuple)
02237             {
02238                 HeapTupleHeader td;
02239 
02240                 td = DatumGetHeapTupleHeader(result);
02241 
02242                 /*
02243                  * Verify all returned rows have same subtype; necessary in
02244                  * case the type is RECORD.
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                  * tuplestore_puttuple needs a HeapTuple not a bare
02254                  * HeapTupleHeader, but it doesn't need all the fields.
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              * Are we done?
02266              */
02267             if (rsinfo.isDone != ExprMultipleResult)
02268                 break;
02269         }
02270         else if (rsinfo.returnMode == SFRM_Materialize)
02271         {
02272             /* check we're on the same page as the function author */
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             /* Done evaluating the set result */
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      * If we got nothing from the function (ie, an empty-set or NULL result),
02293      * we have to create the tuplestore to return, and if it's a
02294      * non-set-returning function then insert a single all-nulls row.
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      * If function provided a tupdesc, cross-check it.  We only really need to
02318      * do this for functions returning RECORD, but might as well do it always.
02319      */
02320     if (rsinfo.setDesc)
02321     {
02322         tupledesc_match(expectedDesc, rsinfo.setDesc);
02323 
02324         /*
02325          * If it is a dynamically-allocated TupleDesc, free it: it is
02326          * typically allocated in a per-query context, so we must avoid
02327          * leaking it across multiple usages.
02328          */
02329         if (rsinfo.setDesc->tdrefcount == -1)
02330             FreeTupleDesc(rsinfo.setDesc);
02331     }
02332 
02333     MemoryContextSwitchTo(callerContext);
02334 
02335     /* All done, pass back the tuplestore */
02336     return rsinfo.setResult;
02337 }
02338 
02339 
02340 /* ----------------------------------------------------------------
02341  *      ExecEvalFunc
02342  *      ExecEvalOper
02343  *
02344  *      Evaluate the functional result of a list of arguments by calling the
02345  *      function manager.
02346  * ----------------------------------------------------------------
02347  */
02348 
02349 /* ----------------------------------------------------------------
02350  *      ExecEvalFunc
02351  * ----------------------------------------------------------------
02352  */
02353 static Datum
02354 ExecEvalFunc(FuncExprState *fcache,
02355              ExprContext *econtext,
02356              bool *isNull,
02357              ExprDoneCond *isDone)
02358 {
02359     /* This is called only the first time through */
02360     FuncExpr   *func = (FuncExpr *) fcache->xprstate.expr;
02361 
02362     /* Initialize function lookup info */
02363     init_fcache(func->funcid, func->inputcollid, fcache,
02364                 econtext->ecxt_per_query_memory, true);
02365 
02366     /* Go directly to ExecMakeFunctionResult on subsequent uses */
02367     fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResult;
02368 
02369     return ExecMakeFunctionResult(fcache, econtext, isNull, isDone);
02370 }
02371 
02372 /* ----------------------------------------------------------------
02373  *      ExecEvalOper
02374  * ----------------------------------------------------------------
02375  */
02376 static Datum
02377 ExecEvalOper(FuncExprState *fcache,
02378              ExprContext *econtext,
02379              bool *isNull,
02380              ExprDoneCond *isDone)
02381 {
02382     /* This is called only the first time through */
02383     OpExpr     *op = (OpExpr *) fcache->xprstate.expr;
02384 
02385     /* Initialize function lookup info */
02386     init_fcache(op->opfuncid, op->inputcollid, fcache,
02387                 econtext->ecxt_per_query_memory, true);
02388 
02389     /* Go directly to ExecMakeFunctionResult on subsequent uses */
02390     fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResult;
02391 
02392     return ExecMakeFunctionResult(fcache, econtext, isNull, isDone);
02393 }
02394 
02395 /* ----------------------------------------------------------------
02396  *      ExecEvalDistinct
02397  *
02398  * IS DISTINCT FROM must evaluate arguments to determine whether
02399  * they are NULL; if either is NULL then the result is already
02400  * known. If neither is NULL, then proceed to evaluate the
02401  * function. Note that this is *always* derived from the equals
02402  * operator, but since we need special processing of the arguments
02403  * we can not simply reuse ExecEvalOper() or ExecEvalFunc().
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     /* Set default values for result flags: non-null, not a set result */
02417     *isNull = false;
02418     if (isDone)
02419         *isDone = ExprSingleResult;
02420 
02421     /*
02422      * Initialize function cache if first time through
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      * Evaluate arguments
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         /* Both NULL? Then is not distinct... */
02447         result = BoolGetDatum(FALSE);
02448     }
02449     else if (fcinfo->argnull[0] || fcinfo->argnull[1])
02450     {
02451         /* Only one is NULL? Then is distinct... */
02452         result = BoolGetDatum(TRUE);
02453     }
02454     else
02455     {
02456         fcinfo->isnull = false;
02457         result = FunctionCallInvoke(fcinfo);
02458         *isNull = fcinfo->isnull;
02459         /* Must invert result of "=" */
02460         result = BoolGetDatum(!DatumGetBool(result));
02461     }
02462 
02463     return result;
02464 }
02465 
02466 /*
02467  * ExecEvalScalarArrayOp
02468  *
02469  * Evaluate "scalar op ANY/ALL (array)".  The operator always yields boolean,
02470  * and we combine the results across all array elements using OR and AND
02471  * (for ANY and ALL respectively).  Of course we short-circuit as soon as
02472  * the result is known.
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     /* Set default values for result flags: non-null, not a set result */
02496     *isNull = false;
02497     if (isDone)
02498         *isDone = ExprSingleResult;
02499 
02500     /*
02501      * Initialize function cache if first time through
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      * Evaluate arguments
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      * If the array is NULL then we return NULL --- it's not very meaningful
02523      * to do anything else, even if the operator isn't strict.
02524      */
02525     if (fcinfo->argnull[1])
02526     {
02527         *isNull = true;
02528         return (Datum) 0;
02529     }
02530     /* Else okay to fetch and detoast the array */
02531     arr = DatumGetArrayTypeP(fcinfo->arg[1]);
02532 
02533     /*
02534      * If the array is empty, we return either FALSE or TRUE per the useOr
02535      * flag.  This is correct even if the scalar is NULL; since we would
02536      * evaluate the operator zero times, it matters not whether it would want
02537      * to return NULL.
02538      */
02539     nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
02540     if (nitems <= 0)
02541         return BoolGetDatum(!useOr);
02542 
02543     /*
02544      * If the scalar is NULL, and the function is strict, return NULL; no
02545      * point in iterating the loop.
02546      */
02547     if (fcinfo->argnull[0] && sstate->fxprstate.func.fn_strict)
02548     {
02549         *isNull = true;
02550         return (Datum) 0;
02551     }
02552 
02553     /*
02554      * We arrange to look up info about the element type only once per series
02555      * of calls, assuming the element type doesn't change underneath us.
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     /* Loop over the array elements */
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         /* Get array element, checking for NULL */
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         /* Call comparison function */
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         /* Combine results per OR or AND semantics */
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;          /* needn't look at any more elements */
02619             }
02620         }
02621         else
02622         {
02623             if (!DatumGetBool(thisresult))
02624             {
02625                 result = BoolGetDatum(false);
02626                 resultnull = false;
02627                 break;          /* needn't look at any more elements */
02628             }
02629         }
02630 
02631         /* advance bitmap pointer if any */
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  *      ExecEvalNot
02649  *      ExecEvalOr
02650  *      ExecEvalAnd
02651  *
02652  *      Evaluate boolean expressions, with appropriate short-circuiting.
02653  *
02654  *      The query planner reformulates clause expressions in the
02655  *      qualification to conjunctive normal form.  If we ever get
02656  *      an AND to evaluate, we can be sure that it's not a top-level
02657  *      clause in the qualification, but appears lower (as a function
02658  *      argument, for example), or in the target list.  Not that you
02659  *      need to know this, mind you...
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      * if the expression evaluates to null, then we just cascade the null back
02676      * to whoever called us.
02677      */
02678     if (*isNull)
02679         return expr_value;
02680 
02681     /*
02682      * evaluation of 'not' is simple.. expr is false, then return 'true' and
02683      * vice versa.
02684      */
02685     return BoolGetDatum(!DatumGetBool(expr_value));
02686 }
02687 
02688 /* ----------------------------------------------------------------
02689  *      ExecEvalOr
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      * If any of the clauses is TRUE, the OR result is TRUE regardless of the
02707      * states of the rest of the clauses, so we can stop evaluating and return
02708      * TRUE immediately.  If none are TRUE and one or more is NULL, we return
02709      * NULL; otherwise we return FALSE.  This makes sense when you interpret
02710      * NULL as "don't know": if we have a TRUE then the OR is TRUE even if we
02711      * aren't sure about some of the other inputs. If all the known inputs are
02712      * FALSE, but we have one or more "don't knows", then we have to report
02713      * that we "don't know" what the OR's result should be --- perhaps one of
02714      * the "don't knows" would have been TRUE if we'd known its value.  Only
02715      * when all the inputs are known to be FALSE can we state confidently that
02716      * the OR's result is FALSE.
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          * if we have a non-null true result, then return it.
02727          */
02728         if (*isNull)
02729             AnyNull = true;     /* remember we got a null */
02730         else if (DatumGetBool(clause_value))
02731             return clause_value;
02732     }
02733 
02734     /* AnyNull is true if at least one clause evaluated to NULL */
02735     *isNull = AnyNull;
02736     return BoolGetDatum(false);
02737 }
02738 
02739 /* ----------------------------------------------------------------
02740  *      ExecEvalAnd
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      * If any of the clauses is FALSE, the AND result is FALSE regardless of
02758      * the states of the rest of the clauses, so we can stop evaluating and
02759      * return FALSE immediately.  If none are FALSE and one or more is NULL,
02760      * we return NULL; otherwise we return TRUE.  This makes sense when you
02761      * interpret NULL as "don't know", using the same sort of reasoning as for
02762      * OR, above.
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          * if we have a non-null false result, then return it.
02774          */
02775         if (*isNull)
02776             AnyNull = true;     /* remember we got a null */
02777         else if (!DatumGetBool(clause_value))
02778             return clause_value;
02779     }
02780 
02781     /* AnyNull is true if at least one clause evaluated to NULL */
02782     *isNull = AnyNull;
02783     return BoolGetDatum(!AnyNull);
02784 }
02785 
02786 /* ----------------------------------------------------------------
02787  *      ExecEvalConvertRowtype
02788  *
02789  *      Evaluate a rowtype coercion operation.  This may require
02790  *      rearranging field positions.
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     /* this test covers the isDone exception too: */
02807     if (*isNull)
02808         return tupDatum;
02809 
02810     tuple = DatumGetHeapTupleHeader(tupDatum);
02811 
02812     /* Lookup tupdescs if first time through or after rescan */
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     /* if first time through, initialize conversion map */
02830     if (!cstate->initialized)
02831     {
02832         MemoryContext old_cxt;
02833 
02834         /* allocate map in long-lived memory context */
02835         old_cxt = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
02836 
02837         /* prepare map from old to new attribute numbers */
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      * No-op if no conversion needed (not clear this can happen here).
02848      */
02849     if (cstate->map == NULL)
02850         return tupDatum;
02851 
02852     /*
02853      * do_convert_tuple needs a HeapTuple not a bare HeapTupleHeader.
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  *      ExecEvalCase
02865  *
02866  *      Evaluate a CASE clause. Will have boolean expressions
02867  *      inside the WHEN clauses, and will have expressions
02868  *      for results.
02869  *      - thomas 1998-11-09
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      * If there's a test expression, we have to evaluate it and save the value
02886      * where the CaseTestExpr placeholders can find it. We must save and
02887      * restore prior setting of econtext's caseValue fields, in case this node
02888      * is itself within a larger CASE.
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      * we evaluate each of the WHEN clauses in turn, as soon as one is true we
02903      * return the corresponding result. If none are true then we return the
02904      * value of the default clause, or NULL if there is none.
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          * if we have a true test, then we return the result, since the case
02918          * statement is satisfied.  A NULL result from the test is not
02919          * considered true.
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  * ExecEvalCaseTestExpr
02949  *
02950  * Return the value stored by CASE.
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  *      ExecEvalArray - ARRAY[] expressions
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     /* Set default values for result flags: non-null, not a set result */
02980     *isNull = false;
02981     if (isDone)
02982         *isDone = ExprSingleResult;
02983 
02984     if (!arrayExpr->multidims)
02985     {
02986         /* Elements are presumably of scalar type */
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         /* Shouldn't happen here, but if length is 0, return empty array */
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         /* loop through and build array of datums */
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         /* setup for 1-D array of the given length */
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         /* Must be nested array expressions */
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         /* loop through and get data area from each element */
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             /* temporarily ignore null subarrays */
03059             if (eisnull)
03060             {
03061                 haveempty = true;
03062                 continue;
03063             }
03064 
03065             array = DatumGetArrayTypeP(arraydatum);
03066 
03067             /* run-time double-check on element type */
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             /* temporarily ignore zero-dimensional subarrays */
03079             if (this_ndims <= 0)
03080             {
03081                 haveempty = true;
03082                 continue;
03083             }
03084 
03085             if (firstone)
03086             {
03087                 /* Get sub-array details from first member */
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                 /* Check other sub-arrays are compatible */
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          * If all items were null or empty arrays, return an empty array;
03130          * otherwise, if some were and some weren't, raise error.  (Note: we
03131          * must special-case this somehow to avoid trying to generate a 1-D
03132          * array formed from empty arrays.  It's not ideal...)
03133          */
03134         if (haveempty)
03135         {
03136             if (ndims == 0)     /* didn't find any nonempty array */
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         /* setup for multi-D array */
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;     /* marker for no null bitmap */
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  *      ExecEvalRow - ROW() expressions
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     /* Set default values for result flags: non-null, not a set result */
03206     *isNull = false;
03207     if (isDone)
03208         *isDone = ExprSingleResult;
03209 
03210     /* Allocate workspace */
03211     natts = rstate->tupdesc->natts;
03212     values = (Datum *) palloc0(natts * sizeof(Datum));
03213     isnull = (bool *) palloc(natts * sizeof(bool));
03214 
03215     /* preset to nulls in case rowtype has some later-added columns */
03216     memset(isnull, true, natts * sizeof(bool));
03217 
03218     /* Evaluate field values */
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  *      ExecEvalRowCompare - ROW() comparison-op ROW()
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;             /* until we get a result */
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;   /* force NULL result */
03273         locfcinfo.isnull = false;
03274         cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo));
03275         if (locfcinfo.isnull)
03276             return (Datum) 0;   /* force NULL result */
03277         if (cmpresult != 0)
03278             break;              /* no need to compare remaining columns */
03279         i++;
03280     }
03281 
03282     switch (rctype)
03283     {
03284             /* EQ and NE cases aren't allowed here */
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;         /* keep compiler quiet */
03300             break;
03301     }
03302 
03303     *isNull = false;
03304     return BoolGetDatum(result);
03305 }
03306 
03307 /* ----------------------------------------------------------------
03308  *      ExecEvalCoalesce
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     /* Simply loop through until something NOT NULL is found */
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     /* Else return NULL */
03332     *isNull = true;
03333     return (Datum) 0;
03334 }
03335 
03336 /* ----------------------------------------------------------------
03337  *      ExecEvalMinMax
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;             /* until we get a result */
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;           /* ignore NULL inputs */
03370 
03371         if (*isNull)
03372         {
03373             /* first nonnull input, adopt value */
03374             result = value;
03375             *isNull = false;
03376         }
03377         else
03378         {
03379             /* apply comparison function */
03380             locfcinfo.arg[0] = result;
03381             locfcinfo.arg[1] = value;
03382             locfcinfo.isnull = false;
03383             cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo));
03384             if (locfcinfo.isnull)       /* probably should not happen */
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  *      ExecEvalXml
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;             /* until we get a result */
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                 /* arguments are known to be text, bool */
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)     /* probably can't happen */
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                 /* optional argument is known to be text */
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                 /* arguments are known to be xml, text, int */
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                 /* argument type is known to be xml */
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                 /* optional argument is known to be xml */
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  *      ExecEvalNullIf
03617  *
03618  * Note that this is *always* derived from the equals operator,
03619  * but since we need special processing of the arguments
03620  * we can not simply reuse ExecEvalOper() or ExecEvalFunc().
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      * Initialize function cache if first time through
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      * Evaluate arguments
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     /* if either argument is NULL they can't be equal */
03659     if (!fcinfo->argnull[0] && !fcinfo->argnull[1])
03660     {
03661         fcinfo->isnull = false;
03662         result = FunctionCallInvoke(fcinfo);
03663         /* if the arguments are equal return null */
03664         if (!fcinfo->isnull && DatumGetBool(result))
03665         {
03666             *isNull = true;
03667             return (Datum) 0;
03668         }
03669     }
03670 
03671     /* else return first argument */
03672     *isNull = fcinfo->argnull[0];
03673     return fcinfo->arg[0];
03674 }
03675 
03676 /* ----------------------------------------------------------------
03677  *      ExecEvalNullTest
03678  *
03679  *      Evaluate a NullTest node.
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;          /* nothing to check */
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         /* Lookup tupdesc if first time through or if type changes */
03711         tupDesc = get_cached_rowtype(tupType, tupTypmod,
03712                                      &nstate->argdesc, econtext);
03713 
03714         /*
03715          * heap_attisnull needs a HeapTuple not a bare HeapTupleHeader.
03716          */
03717         tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
03718         tmptup.t_data = tuple;
03719 
03720         for (att = 1; att <= tupDesc->natts; att++)
03721         {
03722             /* ignore dropped columns */
03723             if (tupDesc->attrs[att - 1]->attisdropped)
03724                 continue;
03725             if (heap_attisnull(&tmptup, att))
03726             {
03727                 /* null field disproves IS NOT NULL */
03728                 if (ntest->nulltesttype == IS_NOT_NULL)
03729                     return BoolGetDatum(false);
03730             }
03731             else
03732             {
03733                 /* non-null field disproves IS NULL */
03734                 if (ntest->nulltesttype == IS_NULL)
03735                     return BoolGetDatum(false);
03736             }
03737         }
03738 
03739         return BoolGetDatum(true);
03740     }
03741     else
03742     {
03743         /* Simple scalar-argument case, or a null rowtype datum */
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;       /* keep compiler quiet */
03766         }
03767     }
03768 }
03769 
03770 /* ----------------------------------------------------------------
03771  *      ExecEvalBooleanTest
03772  *
03773  *      Evaluate a BooleanTest node.
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;          /* nothing to check */
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;   /* keep compiler quiet */
03852     }
03853 }
03854 
03855 /*
03856  * ExecEvalCoerceToDomain
03857  *
03858  * Test the provided data against the domain constraint(s).  If the data
03859  * passes the constraint specifications, pass it through (return the
03860  * datum) otherwise throw an error.
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;          /* nothing to check */
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                      * Set up value to be returned by CoerceToDomainValue
03898                      * nodes. We must save and restore prior setting of
03899                      * econtext's domainValue fields, in case this node is
03900                      * itself within a check expression for another domain.
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     /* If all has gone well (constraints did not fail) return the datum */
03933     return result;
03934 }
03935 
03936 /*
03937  * ExecEvalCoerceToDomainValue
03938  *
03939  * Return the value stored by CoerceToDomain.
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  *      ExecEvalFieldSelect
03954  *
03955  *      Evaluate a FieldSelect node.
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     /* this test covers the isDone exception too: */
03978     if (*isNull)
03979         return tupDatum;
03980 
03981     tuple = DatumGetHeapTupleHeader(tupDatum);
03982 
03983     tupType = HeapTupleHeaderGetTypeId(tuple);
03984     tupTypmod = HeapTupleHeaderGetTypMod(tuple);
03985 
03986     /* Lookup tupdesc if first time through or if type changes */
03987     tupDesc = get_cached_rowtype(tupType, tupTypmod,
03988                                  &fstate->argdesc, econtext);
03989 
03990     /*
03991      * Find field's attr record.  Note we don't support system columns here: a
03992      * datum tuple doesn't have valid values for most of the interesting
03993      * system columns anyway.
03994      */
03995     if (fieldnum <= 0)          /* should never happen */
03996         elog(ERROR, "unsupported reference to system column %d in FieldSelect",
03997              fieldnum);
03998     if (fieldnum > tupDesc->natts)      /* should never happen */
03999         elog(ERROR, "attribute number %d exceeds number of columns %d",
04000              fieldnum, tupDesc->natts);
04001     attr = tupDesc->attrs[fieldnum - 1];
04002 
04003     /* Check for dropped column, and force a NULL result if so */
04004     if (attr->attisdropped)
04005     {
04006         *isNull = true;
04007         return (Datum) 0;
04008     }
04009 
04010     /* Check for type mismatch --- possible after ALTER COLUMN TYPE? */
04011     /* As in ExecEvalScalarVar, we should but can't check typmod */
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     /* heap_getattr needs a HeapTuple not a bare HeapTupleHeader */
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  *      ExecEvalFieldStore
04032  *
04033  *      Evaluate a FieldStore node.
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     /* Lookup tupdesc if first time through or after rescan */
04059     tupDesc = get_cached_rowtype(fstore->resulttype, -1,
04060                                  &fstate->argdesc, econtext);
04061 
04062     /* Allocate workspace */
04063     values = (Datum *) palloc(tupDesc->natts * sizeof(Datum));
04064     isnull = (bool *) palloc(tupDesc->natts * sizeof(bool));
04065 
04066     if (!*isNull)
04067     {
04068         /*
04069          * heap_deform_tuple needs a HeapTuple not a bare HeapTupleHeader. We
04070          * set all the fields in the struct just in case.
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         /* Convert null input tuple into an all-nulls row */
04086         memset(isnull, true, tupDesc->natts * sizeof(bool));
04087     }
04088 
04089     /* Result is never null */
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          * Use the CaseTestExpr mechanism to pass down the old value of the
04104          * field being replaced; this is needed in case the newval is itself a
04105          * FieldStore or ArrayRef that has to obtain and modify the old value.
04106          * It's safe to reuse the CASE mechanism because there cannot be a
04107          * CASE between here and where the value would be needed, and a field
04108          * assignment can't be within a CASE either.  (So saving and restoring
04109          * the caseValue is just paranoia, but let's do it anyway.)
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  *      ExecEvalRelabelType
04133  *
04134  *      Evaluate a RelabelType node.
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  *      ExecEvalCoerceViaIO
04147  *
04148  *      Evaluate a CoerceViaIO node.
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;        /* nothing to do */
04164 
04165     if (*isNull)
04166         string = NULL;          /* output functions are not called on nulls */
04167     else
04168         string = OutputFunctionCall(&iostate->outfunc, inputval);
04169 
04170     result = InputFunctionCall(&iostate->infunc,
04171                                string,
04172                                iostate->intypioparam,
04173                                -1);
04174 
04175     /* The input function cannot change the null/not-null status */
04176     return result;
04177 }
04178 
04179 /* ----------------------------------------------------------------
04180  *      ExecEvalArrayCoerceExpr
04181  *
04182  *      Evaluate an ArrayCoerceExpr node.
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;          /* nothing to do */
04199     if (*isNull)
04200         return result;          /* nothing to do */
04201 
04202     /*
04203      * If it's binary-compatible, modify the element type in the array header,
04204      * but otherwise leave the array as we received it.
04205      */
04206     if (!OidIsValid(acoerce->elemfuncid))
04207     {
04208         /* Detoast input array if necessary, and copy in any case */
04209         array = DatumGetArrayTypePCopy(result);
04210         ARR_ELEMTYPE(array) = astate->resultelemtype;
04211         PG_RETURN_ARRAYTYPE_P(array);
04212     }
04213 
04214     /* Detoast input array if necessary, but don't make a useless copy */
04215     array = DatumGetArrayTypeP(result);
04216 
04217     /* Initialize function cache if first time through */
04218     if (astate->elemfunc.fn_oid == InvalidOid)
04219     {
04220         AclResult   aclresult;
04221 
04222         /* Check permission to call function */
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         /* Set up the primary fmgr lookup information */
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      * Use array_map to apply the function to each array element.
04238      *
04239      * We pass on the desttypmod and isExplicit flags whether or not the
04240      * function wants them.
04241      *
04242      * Note: coercion functions are assumed to not use collation.
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  *      ExecEvalCurrentOfExpr
04259  *
04260  * The planner should convert CURRENT OF into a TidScan qualification, or some
04261  * other special handling in a ForeignScan node.  So we have to be able to do
04262  * ExecInitExpr on a CurrentOfExpr, but we shouldn't ever actually execute it.
04263  * If we get here, we suppose we must be dealing with CURRENT OF on a foreign
04264  * table whose FDW doesn't handle it, and complain accordingly.
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;                   /* keep compiler quiet */
04275 }
04276 
04277 
04278 /*
04279  * ExecEvalExprSwitchContext
04280  *
04281  * Same as ExecEvalExpr, but get into the right allocation context explicitly.
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  * ExecInitExpr: prepare an expression tree for execution
04301  *
04302  * This function builds and returns an ExprState tree paralleling the given
04303  * Expr node tree.  The ExprState tree can then be handed to ExecEvalExpr
04304  * for execution.  Because the Expr tree itself is read-only as far as
04305  * ExecInitExpr and ExecEvalExpr are concerned, several different executions
04306  * of the same plan tree can occur concurrently.
04307  *
04308  * This must be called in a memory context that will last as long as repeated
04309  * executions of the expression are needed.  Typically the context will be
04310  * the same as the per-query context of the associated ExprContext.
04311  *
04312  * Any Aggref, WindowFunc, or SubPlan nodes found in the tree are added to the
04313  * lists of such nodes held by the parent PlanState. Otherwise, we do very
04314  * little initialization here other than building the state-node tree.  Any
04315  * nontrivial work associated with initializing runtime info for a node should
04316  * happen during the first actual evaluation of that node.  (This policy lets
04317  * us avoid work if the node is never actually evaluated.)
04318  *
04319  * Note: there is no ExecEndExpr function; we assume that any resource
04320  * cleanup needed will be handled by just releasing the memory context
04321  * in which the state tree is built.  Functions that require additional
04322  * cleanup work can register a shutdown callback in the ExprContext.
04323  *
04324  *  'node' is the root of the expression tree to examine
04325  *  'parent' is the PlanState node that owns the expression.
04326  *
04327  * 'parent' may be NULL if we are preparing an expression that is not
04328  * associated with a plan tree.  (If so, it can't have aggs or subplans.)
04329  * This case should usually come through ExecPrepareExpr, not directly here.
04330  */
04331 ExprState *
04332 ExecInitExpr(Expr *node, PlanState *parent)
04333 {
04334     ExprState  *state;
04335 
04336     if (node == NULL)
04337         return NULL;
04338 
04339     /* Guard against stack overflow due to overly complex expressions */
04340     check_stack_depth();
04341 
04342     switch (nodeTag(node))
04343     {
04344         case T_Var:
04345             /* varattno == InvalidAttrNumber means it's a whole-row Var */
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                      * Complain if the aggregate's arguments contain any
04408                      * aggregates; nested agg functions are semantically
04409                      * nonsensical.  (This should have been caught earlier,
04410                      * but we defend against it here anyway.)
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                     /* planner messed up */
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                      * Complain if the windowfunc's arguments contain any
04446                      * windowfuncs; nested window functions are semantically
04447                      * nonsensical.  (This should have been caught earlier,
04448                      * but we defend against it here anyway.)
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                     /* planner messed up */
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                 /* do one-time catalog lookups for type info */
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;       /* not initialized */
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;       /* not initialized */
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;       /* not initialized */
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;       /* not initialized */
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;     /* not initialized */
04542                 sstate->element_type = InvalidOid;      /* ditto */
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                 /* Add SubPlanState nodes to parent->subPlan */
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                 /* lookup the result type's input function */
04644                 getTypeInputInfo(iocoerce->resulttype, &iofunc,
04645                                  &iostate->intypioparam);
04646                 fmgr_info(iofunc, &iostate->infunc);
04647                 /* lookup the input type's output function */
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                 /* Arrays over domains aren't supported yet */
04667                 Assert(getBaseType(astate->resultelemtype) ==
04668                        astate->resultelemtype);
04669                 astate->elemfunc.fn_oid = InvalidOid;   /* not initialized */
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;   /* not used */
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                 /* do one-time catalog lookup for type info */
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                 /* Build tupdesc to describe result tuples */
04746                 if (rowexpr->row_typeid == RECORDOID)
04747                 {
04748                     /* generic record, use runtime type assignment */
04749                     rstate->tupdesc = ExecTypeFromExprList(rowexpr->args,
04750                                                            rowexpr->colnames);
04751                     BlessTupleDesc(rstate->tupdesc);
04752                     /* we won't need to redo this at runtime */
04753                 }
04754                 else
04755                 {
04756                     /* it's been cast to a named type, use that */
04757                     rstate->tupdesc = lookup_rowtype_tupdesc_copy(rowexpr->row_typeid, -1);
04758                 }
04759                 /* Set up evaluation, skipping any deleted columns */
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                          * Guard against ALTER COLUMN TYPE on rowtype since
04772                          * the RowExpr was created.  XXX should we check
04773                          * typmod too?  Not sure we can be sure it'll be the
04774                          * same.
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                          * Ignore original expression and insert a NULL. We
04787                          * don't really care what type of NULL it is, so
04788                          * always make an int4 NULL.
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                      * If we enforced permissions checks on index support
04859                      * functions, we'd need to make a check here.  But the
04860                      * index support machinery doesn't do that, and neither
04861                      * does this code.
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                 /* Look up the btree comparison function for the datatype */
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                  * If we enforced permissions checks on index support
04919                  * functions, we'd need to make a check here.  But the index
04920                  * support machinery doesn't do that, and neither does this
04921                  * code.
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;       /* not used */
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                 /* Don't fall through to the "common" code below */
05018                 return (ExprState *) outlist;
05019             }
05020         default:
05021             elog(ERROR, "unrecognized node type: %d",
05022                  (int) nodeTag(node));
05023             state = NULL;       /* keep compiler quiet */
05024             break;
05025     }
05026 
05027     /* Common code for all state-node types */
05028     state->expr = node;
05029 
05030     return state;
05031 }
05032 
05033 /*
05034  * ExecPrepareExpr --- initialize for expression execution outside a normal
05035  * Plan tree context.
05036  *
05037  * This differs from ExecInitExpr in that we don't assume the caller is
05038  * already running in the EState's per-query context.  Also, we run the
05039  * passed expression tree through expression_planner() to prepare it for
05040  * execution.  (In ordinary Plan trees the regular planning process will have
05041  * made the appropriate transformations on expressions, but for standalone
05042  * expressions this won't have happened.)
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  *                   ExecQual / ExecTargetList / ExecProject
05064  * ----------------------------------------------------------------
05065  */
05066 
05067 /* ----------------------------------------------------------------
05068  *      ExecQual
05069  *
05070  *      Evaluates a conjunctive boolean expression (qual list) and
05071  *      returns true iff none of the subexpressions are false.
05072  *      (We also return true if the list is empty.)
05073  *
05074  *  If some of the subexpressions yield NULL but none yield FALSE,
05075  *  then the result of the conjunction is NULL (ie, unknown)
05076  *  according to three-valued boolean logic.  In this case,
05077  *  we return the value specified by the "resultForNull" parameter.
05078  *
05079  *  Callers evaluating WHERE clauses should pass resultForNull=FALSE,
05080  *  since SQL specifies that tuples with null WHERE results do not
05081  *  get selected.  On the other hand, callers evaluating constraint
05082  *  conditions should pass resultForNull=TRUE, since SQL also specifies
05083  *  that NULL constraint conditions are not failures.
05084  *
05085  *  NOTE: it would not be correct to use this routine to evaluate an
05086  *  AND subclause of a boolean expression; for that purpose, a NULL
05087  *  result must be returned as NULL so that it can be properly treated
05088  *  in the next higher operator (cf. ExecEvalAnd and ExecEvalOr).
05089  *  This routine is only used in contexts where a complete expression
05090  *  is being evaluated and we know that NULL can be treated the same
05091  *  as one boolean result or the other.
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      * debugging stuff
05104      */
05105     EV_printf("ExecQual: qual is ");
05106     EV_nodeDisplay(qual);
05107     EV_printf("\n");
05108 
05109     /*
05110      * Run in short-lived per-tuple context while computing expressions.
05111      */
05112     oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
05113 
05114     /*
05115      * Evaluate the qual conditions one at a time.  If we find a FALSE result,
05116      * we can stop evaluating and return FALSE --- the AND result must be
05117      * FALSE.  Also, if we find a NULL result when resultForNull is FALSE, we
05118      * can stop and return FALSE --- the AND result must be FALSE or NULL in
05119      * that case, and the caller doesn't care which.
05120      *
05121      * If we get to the end of the list, we can return TRUE.  This will happen
05122      * when the AND result is indeed TRUE, or when the AND result is NULL (one
05123      * or more NULL subresult, with all the rest TRUE) and the caller has
05124      * specified resultForNull = TRUE.
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; /* treat NULL as FALSE */
05141                 break;
05142             }
05143         }
05144         else
05145         {
05146             if (!DatumGetBool(expr_value))
05147             {
05148                 result = false; /* definitely FALSE */
05149                 break;
05150             }
05151         }
05152     }
05153 
05154     MemoryContextSwitchTo(oldContext);
05155 
05156     return result;
05157 }
05158 
05159 /*
05160  * Number of items in a tlist (including any resjunk items!)
05161  */
05162 int
05163 ExecTargetListLength(List *targetlist)
05164 {
05165     /* This used to be more complex, but fjoins are dead */
05166     return list_length(targetlist);
05167 }
05168 
05169 /*
05170  * Number of items in a tlist, not including any resjunk items
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  * ExecTargetList
05191  *      Evaluates a targetlist with respect to the given
05192  *      expression context.  Returns TRUE if we were able to create
05193  *      a result, FALSE if we have exhausted a set-valued expression.
05194  *
05195  * Results are stored into the passed values and isnull arrays.
05196  * The caller must provide an itemIsDone array that persists across calls.
05197  *
05198  * As with ExecEvalExpr, the caller should pass isDone = NULL if not
05199  * prepared to deal with sets of result tuples.  Otherwise, a return
05200  * of *isDone = ExprMultipleResult signifies a set element, and a return
05201  * of *isDone = ExprEndResult signifies end of the set of tuple.
05202  * We assume that *isDone has been initialized to ExprSingleResult by caller.
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      * Run in short-lived per-tuple context while computing expressions.
05218      */
05219     oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
05220 
05221     /*
05222      * evaluate all the expressions in the target list
05223      */
05224     haveDoneSets = false;       /* any exhausted set exprs in tlist? */
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             /* We have a set-valued expression in the tlist */
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                 /* we have undone sets in the tlist, set flag */
05247                 *isDone = ExprMultipleResult;
05248             }
05249             else
05250             {
05251                 /* we have done sets in the tlist, set flag for that */
05252                 haveDoneSets = true;
05253             }
05254         }
05255     }
05256 
05257     if (haveDoneSets)
05258     {
05259         /*
05260          * note: can't get here unless we verified isDone != NULL
05261          */
05262         if (*isDone == ExprSingleResult)
05263         {
05264             /*
05265              * all sets are done, so report that tlist expansion is complete.
05266              */
05267             *isDone = ExprEndResult;
05268             MemoryContextSwitchTo(oldContext);
05269             return false;
05270         }
05271         else
05272         {
05273             /*
05274              * We have some done and some undone sets.  Restart the done ones
05275              * so that we can deliver a tuple (if possible).
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                          * Oh dear, this item is returning an empty set. Guess
05294                          * we can't make a tuple after all.
05295                          */
05296                         *isDone = ExprEndResult;
05297                         break;
05298                     }
05299                 }
05300             }
05301 
05302             /*
05303              * If we cannot make a tuple because some sets are empty, we still
05304              * have to cycle the nonempty sets to completion, else resources
05305              * will not be released from subplans etc.
05306              *
05307              * XXX is that still necessary?
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     /* Report success */
05333     MemoryContextSwitchTo(oldContext);
05334 
05335     return true;
05336 }
05337 
05338 /*
05339  * ExecProject
05340  *
05341  *      projects a tuple based on projection info and stores
05342  *      it in the previously specified tuple table slot.
05343  *
05344  *      Note: the result is always a virtual tuple; therefore it
05345  *      may reference the contents of the exprContext's scan tuples
05346  *      and/or temporary results constructed in the exprContext.
05347  *      If the caller wishes the result to be valid longer than that
05348  *      data will be valid, he must call ExecMaterializeSlot on the
05349  *      result slot.
05350  */
05351 TupleTableSlot *
05352 ExecProject(ProjectionInfo *projInfo, ExprDoneCond *isDone)
05353 {
05354     TupleTableSlot *slot;
05355     ExprContext *econtext;
05356     int         numSimpleVars;
05357 
05358     /*
05359      * sanity checks
05360      */
05361     Assert(projInfo != NULL);
05362 
05363     /*
05364      * get the projection info we want
05365      */
05366     slot = projInfo->pi_slot;
05367     econtext = projInfo->pi_exprContext;
05368 
05369     /* Assume single result row until proven otherwise */
05370     if (isDone)
05371         *isDone = ExprSingleResult;
05372 
05373     /*
05374      * Clear any former contents of the result slot.  This makes it safe for
05375      * us to use the slot's Datum/isnull arrays as workspace. (Also, we can
05376      * return the slot as-is if we decide no rows can be projected.)
05377      */
05378     ExecClearTuple(slot);
05379 
05380     /*
05381      * Force extraction of all input values that we'll need.  The
05382      * Var-extraction loops below depend on this, and we are also prefetching
05383      * all attributes that will be referenced in the generic expressions.
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      * Assign simple Vars to result by direct extraction of fields from source
05397      * slots ... a mite ugly, but fast ...
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             /* especially simple case where vars go to output in order */
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             /* we have to pay attention to varOutputCols[] */
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      * If there are any generic expressions, evaluate them.  It's possible
05441      * that there are set-returning functions in such expressions; if so and
05442      * we have reached the end of the set, we return the result slot, which we
05443      * already marked empty.
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;        /* no more result rows, return empty slot */
05454     }
05455 
05456     /*
05457      * Successfully formed a result row.  Mark the result slot as containing a
05458      * valid virtual tuple.
05459      */
05460     return ExecStoreVirtualTuple(slot);
05461 }