]> granicus.if.org Git - postgresql/commitdiff
Remove obsoleted code relating to targetlist SRF evaluation.
authorAndres Freund <andres@anarazel.de>
Thu, 19 Jan 2017 22:12:38 +0000 (14:12 -0800)
committerAndres Freund <andres@anarazel.de>
Thu, 19 Jan 2017 22:40:41 +0000 (14:40 -0800)
Since 69f4b9c plain expression evaluation (and thus normal projection)
can't return sets of tuples anymore. Thus remove code dealing with
that possibility.

This will require adjustments in external code using
ExecEvalExpr()/ExecProject() - that should neither be hard nor very
common.

Author: Andres Freund and Tom Lane
Discussion: https://postgr.es/m/20160822214023.aaxz5l4igypowyri@alap3.anarazel.de

44 files changed:
contrib/postgres_fdw/postgres_fdw.c
src/backend/catalog/index.c
src/backend/catalog/partition.c
src/backend/commands/copy.c
src/backend/commands/prepare.c
src/backend/commands/tablecmds.c
src/backend/commands/typecmds.c
src/backend/executor/execAmi.c
src/backend/executor/execQual.c
src/backend/executor/execScan.c
src/backend/executor/execUtils.c
src/backend/executor/nodeAgg.c
src/backend/executor/nodeBitmapHeapscan.c
src/backend/executor/nodeCtescan.c
src/backend/executor/nodeCustom.c
src/backend/executor/nodeForeignscan.c
src/backend/executor/nodeFunctionscan.c
src/backend/executor/nodeGather.c
src/backend/executor/nodeGroup.c
src/backend/executor/nodeHash.c
src/backend/executor/nodeHashjoin.c
src/backend/executor/nodeIndexonlyscan.c
src/backend/executor/nodeIndexscan.c
src/backend/executor/nodeLimit.c
src/backend/executor/nodeMergejoin.c
src/backend/executor/nodeModifyTable.c
src/backend/executor/nodeNestloop.c
src/backend/executor/nodeProjectSet.c
src/backend/executor/nodeResult.c
src/backend/executor/nodeSamplescan.c
src/backend/executor/nodeSeqscan.c
src/backend/executor/nodeSubplan.c
src/backend/executor/nodeSubqueryscan.c
src/backend/executor/nodeTidscan.c
src/backend/executor/nodeValuesscan.c
src/backend/executor/nodeWindowAgg.c
src/backend/executor/nodeWorktablescan.c
src/backend/optimizer/util/clauses.c
src/backend/optimizer/util/predtest.c
src/backend/utils/adt/domains.c
src/backend/utils/adt/xml.c
src/include/executor/executor.h
src/include/nodes/execnodes.h
src/pl/plpgsql/src/pl_exec.c

index 64f857ff535c5fc2e0f91360ba9978bbd0651844..ce1f443d55564bc09fb9aff08b3084c697830f7f 100644 (file)
@@ -3444,7 +3444,7 @@ process_query_params(ExprContext *econtext,
                bool            isNull;
 
                /* Evaluate the parameter expression */
-               expr_value = ExecEvalExpr(expr_state, econtext, &isNull, NULL);
+               expr_value = ExecEvalExpr(expr_state, econtext, &isNull);
 
                /*
                 * Get string representation of each parameter value by invoking
index cac0cbf7d4785d7f2d2ee4452922cbe8e3eaf57d..26cbc0e06aa24855e5521a07f56103a7f9f2876d 100644 (file)
@@ -1805,8 +1805,7 @@ FormIndexDatum(IndexInfo *indexInfo,
                                elog(ERROR, "wrong number of index expressions");
                        iDatum = ExecEvalExprSwitchContext((ExprState *) lfirst(indexpr_item),
                                                                                           GetPerTupleExprContext(estate),
-                                                                                          &isNull,
-                                                                                          NULL);
+                                                                                          &isNull);
                        indexpr_item = lnext(indexpr_item);
                }
                values[i] = iDatum;
index 45f7132f5439c43e20ff5a1db65e1f06c9745429..3f8a950f37dc57ff70db340a6ee7e808fb42a2d1 100644 (file)
@@ -1358,7 +1358,7 @@ get_qual_for_range(PartitionKey key, PartitionBoundSpec *spec)
                        test_exprstate = ExecInitExpr(test_expr, NULL);
                        test_result = ExecEvalExprSwitchContext(test_exprstate,
                                                                                          GetPerTupleExprContext(estate),
-                                                                                                       &isNull, NULL);
+                                                                                                       &isNull);
                        MemoryContextSwitchTo(oldcxt);
                        FreeExecutorState(estate);
 
@@ -1630,8 +1630,7 @@ FormPartitionKeyDatum(PartitionDispatch pd,
                                elog(ERROR, "wrong number of partition key expressions");
                        datum = ExecEvalExprSwitchContext((ExprState *) lfirst(partexpr_item),
                                                                                          GetPerTupleExprContext(estate),
-                                                                                         &isNull,
-                                                                                         NULL);
+                                                                                         &isNull);
                        partexpr_item = lnext(partexpr_item);
                }
                values[i] = datum;
index 75386212e0696fc6bb9596e5265c595fc1c64332..c05e14e26f76f3eebfde5d1ca16d496dc4e628cb 100644 (file)
@@ -3394,7 +3394,7 @@ NextCopyFrom(CopyState cstate, ExprContext *econtext,
                Assert(CurrentMemoryContext == econtext->ecxt_per_tuple_memory);
 
                values[defmap[i]] = ExecEvalExpr(defexprs[i], econtext,
-                                                                                &nulls[defmap[i]], NULL);
+                                                                                &nulls[defmap[i]]);
        }
 
        return true;
index 1ff41661a551c586b4198e3dc14bf3deb317f384..7d7e3daf1e7c008405e188b9c1de5a7a18366866 100644 (file)
@@ -413,8 +413,7 @@ EvaluateParams(PreparedStatement *pstmt, List *params,
                prm->pflags = PARAM_FLAG_CONST;
                prm->value = ExecEvalExprSwitchContext(n,
                                                                                           GetPerTupleExprContext(estate),
-                                                                                          &prm->isnull,
-                                                                                          NULL);
+                                                                                          &prm->isnull);
 
                i++;
        }
index 18cac9ad2d97aaed65a26c2902c27d46cf2bf36a..6ed2a3dc4d12f493e281b55bdc35a65124b77624 100644 (file)
@@ -4460,8 +4460,7 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
 
                                        values[ex->attnum - 1] = ExecEvalExpr(ex->exprstate,
                                                                                                                  econtext,
-                                                                                                        &isnull[ex->attnum - 1],
-                                                                                                                 NULL);
+                                                                                                        &isnull[ex->attnum - 1]);
                                }
 
                                /*
index 3ff6cbca56f43caecf0c93cc33950484c1779003..4c33d5548444d2bd536d9e9aceee3b6aa2ec0f0b 100644 (file)
@@ -2735,7 +2735,7 @@ validateDomainConstraint(Oid domainoid, char *ccbin)
 
                                conResult = ExecEvalExprSwitchContext(exprstate,
                                                                                                          econtext,
-                                                                                                         &isNull, NULL);
+                                                                                                         &isNull);
 
                                if (!isNull && !DatumGetBool(conResult))
                                {
index b52cfaa41f4746d36893971685f1671f6a7972dd..1ca4bcb117c8562256df35fcea6ca2dbf063bf25 100644 (file)
@@ -59,7 +59,6 @@
 #include "utils/syscache.h"
 
 
-static bool TargetListSupportsBackwardScan(List *targetlist);
 static bool IndexSupportsBackwardScan(Oid indexid);
 
 
@@ -120,7 +119,7 @@ ExecReScan(PlanState *node)
                        UpdateChangedParamSet(node->righttree, node->chgParam);
        }
 
-       /* Shut down any SRFs in the plan node's targetlist */
+       /* Call expression callbacks */
        if (node->ps_ExprContext)
                ReScanExprContext(node->ps_ExprContext);
 
@@ -460,8 +459,7 @@ ExecSupportsBackwardScan(Plan *node)
        {
                case T_Result:
                        if (outerPlan(node) != NULL)
-                               return ExecSupportsBackwardScan(outerPlan(node)) &&
-                                       TargetListSupportsBackwardScan(node->targetlist);
+                               return ExecSupportsBackwardScan(outerPlan(node));
                        else
                                return false;
 
@@ -478,13 +476,6 @@ ExecSupportsBackwardScan(Plan *node)
                                return true;
                        }
 
-               case T_SeqScan:
-               case T_TidScan:
-               case T_FunctionScan:
-               case T_ValuesScan:
-               case T_CteScan:
-                       return TargetListSupportsBackwardScan(node->targetlist);
-
                case T_SampleScan:
                        /* Simplify life for tablesample methods by disallowing this */
                        return false;
@@ -493,35 +484,34 @@ ExecSupportsBackwardScan(Plan *node)
                        return false;
 
                case T_IndexScan:
-                       return IndexSupportsBackwardScan(((IndexScan *) node)->indexid) &&
-                               TargetListSupportsBackwardScan(node->targetlist);
+                       return IndexSupportsBackwardScan(((IndexScan *) node)->indexid);
 
                case T_IndexOnlyScan:
-                       return IndexSupportsBackwardScan(((IndexOnlyScan *) node)->indexid) &&
-                               TargetListSupportsBackwardScan(node->targetlist);
+                       return IndexSupportsBackwardScan(((IndexOnlyScan *) node)->indexid);
 
                case T_SubqueryScan:
-                       return ExecSupportsBackwardScan(((SubqueryScan *) node)->subplan) &&
-                               TargetListSupportsBackwardScan(node->targetlist);
+                       return ExecSupportsBackwardScan(((SubqueryScan *) node)->subplan);
 
                case T_CustomScan:
                        {
                                uint32          flags = ((CustomScan *) node)->flags;
 
-                               if ((flags & CUSTOMPATH_SUPPORT_BACKWARD_SCAN) &&
-                                       TargetListSupportsBackwardScan(node->targetlist))
+                               if (flags & CUSTOMPATH_SUPPORT_BACKWARD_SCAN)
                                        return true;
                        }
                        return false;
 
+               case T_SeqScan:
+               case T_TidScan:
+               case T_FunctionScan:
+               case T_ValuesScan:
+               case T_CteScan:
                case T_Material:
                case T_Sort:
-                       /* these don't evaluate tlist */
                        return true;
 
                case T_LockRows:
                case T_Limit:
-                       /* these don't evaluate tlist */
                        return ExecSupportsBackwardScan(outerPlan(node));
 
                default:
@@ -529,18 +519,6 @@ ExecSupportsBackwardScan(Plan *node)
        }
 }
 
-/*
- * If the tlist contains set-returning functions, we can't support backward
- * scan, because the TupFromTlist code is direction-ignorant.
- */
-static bool
-TargetListSupportsBackwardScan(List *targetlist)
-{
-       if (expression_returns_set((Node *) targetlist))
-               return false;
-       return true;
-}
-
 /*
  * An IndexScan or IndexOnlyScan node supports backward scan only if the
  * index's AM does.
index eed7e95c7590a3ad2500f81f3b5883385398437c..19dd0b264bced6a75f07d69f49f8c19704d37694 100644 (file)
 /* static function decls */
 static Datum ExecEvalArrayRef(ArrayRefExprState *astate,
                                 ExprContext *econtext,
-                                bool *isNull, ExprDoneCond *isDone);
+                                bool *isNull);
 static bool isAssignmentIndirectionExpr(ExprState *exprstate);
 static Datum ExecEvalAggref(AggrefExprState *aggref,
                           ExprContext *econtext,
-                          bool *isNull, ExprDoneCond *isDone);
+                          bool *isNull);
 static Datum ExecEvalWindowFunc(WindowFuncExprState *wfunc,
                                   ExprContext *econtext,
-                                  bool *isNull, ExprDoneCond *isDone);
+                                  bool *isNull);
 static Datum ExecEvalScalarVar(ExprState *exprstate, ExprContext *econtext,
-                                 bool *isNull, ExprDoneCond *isDone);
+                                 bool *isNull);
 static Datum ExecEvalScalarVarFast(ExprState *exprstate, ExprContext *econtext,
-                                         bool *isNull, ExprDoneCond *isDone);
+                                         bool *isNull);
 static Datum ExecEvalWholeRowVar(WholeRowVarExprState *wrvstate,
                                        ExprContext *econtext,
-                                       bool *isNull, ExprDoneCond *isDone);
+                                       bool *isNull);
 static Datum ExecEvalWholeRowFast(WholeRowVarExprState *wrvstate,
                                         ExprContext *econtext,
-                                        bool *isNull, ExprDoneCond *isDone);
+                                        bool *isNull);
 static Datum ExecEvalWholeRowSlow(WholeRowVarExprState *wrvstate,
                                         ExprContext *econtext,
-                                        bool *isNull, ExprDoneCond *isDone);
+                                        bool *isNull);
 static Datum ExecEvalConst(ExprState *exprstate, ExprContext *econtext,
-                         bool *isNull, ExprDoneCond *isDone);
+                         bool *isNull);
 static Datum ExecEvalParamExec(ExprState *exprstate, ExprContext *econtext,
-                                 bool *isNull, ExprDoneCond *isDone);
+                                 bool *isNull);
 static Datum ExecEvalParamExtern(ExprState *exprstate, ExprContext *econtext,
-                                       bool *isNull, ExprDoneCond *isDone);
+                                       bool *isNull);
 static void init_fcache(Oid foid, Oid input_collation, FuncExprState *fcache,
                        MemoryContext fcacheCxt, bool allowSRF, bool needDescForSRF);
 static void ShutdownFuncExpr(Datum arg);
 static TupleDesc get_cached_rowtype(Oid type_id, int32 typmod,
                                   TupleDesc *cache_field, ExprContext *econtext);
 static void ShutdownTupleDescRef(Datum arg);
-static ExprDoneCond ExecEvalFuncArgs(FunctionCallInfo fcinfo,
+static void ExecEvalFuncArgs(FunctionCallInfo fcinfo,
                                 List *argList, ExprContext *econtext);
 static void ExecPrepareTuplestoreResult(FuncExprState *fcache,
                                                        ExprContext *econtext,
@@ -106,85 +106,85 @@ static void ExecPrepareTuplestoreResult(FuncExprState *fcache,
 static void tupledesc_match(TupleDesc dst_tupdesc, TupleDesc src_tupdesc);
 static Datum ExecMakeFunctionResultNoSets(FuncExprState *fcache,
                                                         ExprContext *econtext,
-                                                        bool *isNull, ExprDoneCond *isDone);
+                                                        bool *isNull);
 static Datum ExecEvalFunc(FuncExprState *fcache, ExprContext *econtext,
-                        bool *isNull, ExprDoneCond *isDone);
+                        bool *isNull);
 static Datum ExecEvalOper(FuncExprState *fcache, ExprContext *econtext,
-                        bool *isNull, ExprDoneCond *isDone);
+                        bool *isNull);
 static Datum ExecEvalDistinct(FuncExprState *fcache, ExprContext *econtext,
-                                bool *isNull, ExprDoneCond *isDone);
+                                bool *isNull);
 static Datum ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate,
                                          ExprContext *econtext,
-                                         bool *isNull, ExprDoneCond *isDone);
+                                         bool *isNull);
 static Datum ExecEvalNot(BoolExprState *notclause, ExprContext *econtext,
-                       bool *isNull, ExprDoneCond *isDone);
+                       bool *isNull);
 static Datum ExecEvalOr(BoolExprState *orExpr, ExprContext *econtext,
-                  bool *isNull, ExprDoneCond *isDone);
+                  bool *isNull);
 static Datum ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
-                       bool *isNull, ExprDoneCond *isDone);
+                       bool *isNull);
 static Datum ExecEvalConvertRowtype(ConvertRowtypeExprState *cstate,
                                           ExprContext *econtext,
-                                          bool *isNull, ExprDoneCond *isDone);
+                                          bool *isNull);
 static Datum ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
-                        bool *isNull, ExprDoneCond *isDone);
+                        bool *isNull);
 static Datum ExecEvalCaseTestExpr(ExprState *exprstate,
                                         ExprContext *econtext,
-                                        bool *isNull, ExprDoneCond *isDone);
+                                        bool *isNull);
 static Datum ExecEvalArray(ArrayExprState *astate,
                          ExprContext *econtext,
-                         bool *isNull, ExprDoneCond *isDone);
+                         bool *isNull);
 static Datum ExecEvalRow(RowExprState *rstate,
                        ExprContext *econtext,
-                       bool *isNull, ExprDoneCond *isDone);
+                       bool *isNull);
 static Datum ExecEvalRowCompare(RowCompareExprState *rstate,
                                   ExprContext *econtext,
-                                  bool *isNull, ExprDoneCond *isDone);
+                                  bool *isNull);
 static Datum ExecEvalCoalesce(CoalesceExprState *coalesceExpr,
                                 ExprContext *econtext,
-                                bool *isNull, ExprDoneCond *isDone);
+                                bool *isNull);
 static Datum ExecEvalMinMax(MinMaxExprState *minmaxExpr,
                           ExprContext *econtext,
-                          bool *isNull, ExprDoneCond *isDone);
+                          bool *isNull);
 static Datum ExecEvalSQLValueFunction(ExprState *svfExpr,
                                                 ExprContext *econtext,
-                                                bool *isNull, ExprDoneCond *isDone);
+                                                bool *isNull);
 static Datum ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
-                       bool *isNull, ExprDoneCond *isDone);
+                       bool *isNull);
 static Datum ExecEvalNullIf(FuncExprState *nullIfExpr,
                           ExprContext *econtext,
-                          bool *isNull, ExprDoneCond *isDone);
+                          bool *isNull);
 static Datum ExecEvalNullTest(NullTestState *nstate,
                                 ExprContext *econtext,
-                                bool *isNull, ExprDoneCond *isDone);
+                                bool *isNull);
 static Datum ExecEvalBooleanTest(GenericExprState *bstate,
                                        ExprContext *econtext,
-                                       bool *isNull, ExprDoneCond *isDone);
+                                       bool *isNull);
 static Datum ExecEvalCoerceToDomain(CoerceToDomainState *cstate,
                                           ExprContext *econtext,
-                                          bool *isNull, ExprDoneCond *isDone);
+                                          bool *isNull);
 static Datum ExecEvalCoerceToDomainValue(ExprState *exprstate,
                                                        ExprContext *econtext,
-                                                       bool *isNull, ExprDoneCond *isDone);
+                                                       bool *isNull);
 static Datum ExecEvalFieldSelect(FieldSelectState *fstate,
                                        ExprContext *econtext,
-                                       bool *isNull, ExprDoneCond *isDone);
+                                       bool *isNull);
 static Datum ExecEvalFieldStore(FieldStoreState *fstate,
                                   ExprContext *econtext,
-                                  bool *isNull, ExprDoneCond *isDone);
+                                  bool *isNull);
 static Datum ExecEvalRelabelType(GenericExprState *exprstate,
                                        ExprContext *econtext,
-                                       bool *isNull, ExprDoneCond *isDone);
+                                       bool *isNull);
 static Datum ExecEvalCoerceViaIO(CoerceViaIOState *iostate,
                                        ExprContext *econtext,
-                                       bool *isNull, ExprDoneCond *isDone);
+                                       bool *isNull);
 static Datum ExecEvalArrayCoerceExpr(ArrayCoerceExprState *astate,
                                                ExprContext *econtext,
-                                               bool *isNull, ExprDoneCond *isDone);
+                                               bool *isNull);
 static Datum ExecEvalCurrentOfExpr(ExprState *exprstate, ExprContext *econtext,
-                                         bool *isNull, ExprDoneCond *isDone);
+                                         bool *isNull);
 static Datum ExecEvalGroupingFuncExpr(GroupingFuncExprState *gstate,
                                                 ExprContext *econtext,
-                                                bool *isNull, ExprDoneCond *isDone);
+                                                bool *isNull);
 
 
 /* ----------------------------------------------------------------
@@ -195,8 +195,7 @@ static Datum ExecEvalGroupingFuncExpr(GroupingFuncExprState *gstate,
  * Each of the following routines having the signature
  *             Datum ExecEvalFoo(ExprState *expression,
  *                                               ExprContext *econtext,
- *                                               bool *isNull,
- *                                               ExprDoneCond *isDone);
+ *                                               bool *isNull);
  * is responsible for evaluating one type or subtype of ExprState node.
  * They are normally called via the ExecEvalExpr macro, which makes use of
  * the function pointer set up when the ExprState node was built by
@@ -220,22 +219,6 @@ static Datum ExecEvalGroupingFuncExpr(GroupingFuncExprState *gstate,
  *             return value: Datum value of result
  *             *isNull: set to TRUE if result is NULL (actual return value is
  *                              meaningless if so); set to FALSE if non-null result
- *             *isDone: set to indicator of set-result status
- *
- * A caller that can only accept a singleton (non-set) result should pass
- * NULL for isDone; if the expression computes a set result then an error
- * will be reported via ereport.  If the caller does pass an isDone pointer
- * then *isDone is set to one of these three states:
- *             ExprSingleResult                singleton result (not a set)
- *             ExprMultipleResult              return value is one element of a set
- *             ExprEndResult                   there are no more elements in the set
- * When ExprMultipleResult is returned, the caller should invoke
- * ExecEvalExpr() repeatedly until ExprEndResult is returned.  ExprEndResult
- * is returned after the last real set element.  For convenience isNull will
- * always be set TRUE when ExprEndResult is returned, but this should not be
- * taken as indicating a NULL element of the set.  Note that these return
- * conventions allow us to distinguish among a singleton NULL, a NULL element
- * of a set, and an empty set.
  *
  * The caller should already have switched into the temporary memory
  * context econtext->ecxt_per_tuple_memory.  The convenience entry point
@@ -260,8 +243,7 @@ static Datum ExecEvalGroupingFuncExpr(GroupingFuncExprState *gstate,
 static Datum
 ExecEvalArrayRef(ArrayRefExprState *astate,
                                 ExprContext *econtext,
-                                bool *isNull,
-                                ExprDoneCond *isDone)
+                                bool *isNull)
 {
        ArrayRef   *arrayRef = (ArrayRef *) astate->xprstate.expr;
        Datum           array_source;
@@ -278,8 +260,7 @@ ExecEvalArrayRef(ArrayRefExprState *astate,
 
        array_source = ExecEvalExpr(astate->refexpr,
                                                                econtext,
-                                                               isNull,
-                                                               isDone);
+                                                               isNull);
 
        /*
         * If refexpr yields NULL, and it's a fetch, then result is NULL. In the
@@ -287,8 +268,6 @@ ExecEvalArrayRef(ArrayRefExprState *astate,
         */
        if (*isNull)
        {
-               if (isDone && *isDone == ExprEndResult)
-                       return (Datum) NULL;    /* end of set result */
                if (!isAssignment)
                        return (Datum) NULL;
        }
@@ -314,8 +293,7 @@ ExecEvalArrayRef(ArrayRefExprState *astate,
 
                upper.indx[i++] = DatumGetInt32(ExecEvalExpr(eltstate,
                                                                                                         econtext,
-                                                                                                        &eisnull,
-                                                                                                        NULL));
+                                                                                                        &eisnull));
                /* If any index expr yields NULL, result is NULL or error */
                if (eisnull)
                {
@@ -350,8 +328,7 @@ ExecEvalArrayRef(ArrayRefExprState *astate,
 
                        lower.indx[j++] = DatumGetInt32(ExecEvalExpr(eltstate,
                                                                                                                 econtext,
-                                                                                                                &eisnull,
-                                                                                                                NULL));
+                                                                                                                &eisnull));
                        /* If any index expr yields NULL, result is NULL or error */
                        if (eisnull)
                        {
@@ -438,8 +415,7 @@ ExecEvalArrayRef(ArrayRefExprState *astate,
                 */
                sourceData = ExecEvalExpr(astate->refassgnexpr,
                                                                  econtext,
-                                                                 &eisnull,
-                                                                 NULL);
+                                                                 &eisnull);
 
                econtext->caseValue_datum = save_datum;
                econtext->caseValue_isNull = save_isNull;
@@ -542,11 +518,8 @@ isAssignmentIndirectionExpr(ExprState *exprstate)
  */
 static Datum
 ExecEvalAggref(AggrefExprState *aggref, ExprContext *econtext,
-                          bool *isNull, ExprDoneCond *isDone)
+                          bool *isNull)
 {
-       if (isDone)
-               *isDone = ExprSingleResult;
-
        if (econtext->ecxt_aggvalues == NULL)           /* safety check */
                elog(ERROR, "no aggregates in this expression context");
 
@@ -563,11 +536,8 @@ ExecEvalAggref(AggrefExprState *aggref, ExprContext *econtext,
  */
 static Datum
 ExecEvalWindowFunc(WindowFuncExprState *wfunc, ExprContext *econtext,
-                                  bool *isNull, ExprDoneCond *isDone)
+                                  bool *isNull)
 {
-       if (isDone)
-               *isDone = ExprSingleResult;
-
        if (econtext->ecxt_aggvalues == NULL)           /* safety check */
                elog(ERROR, "no window functions in this expression context");
 
@@ -588,15 +558,12 @@ ExecEvalWindowFunc(WindowFuncExprState *wfunc, ExprContext *econtext,
  */
 static Datum
 ExecEvalScalarVar(ExprState *exprstate, ExprContext *econtext,
-                                 bool *isNull, ExprDoneCond *isDone)
+                                 bool *isNull)
 {
        Var                *variable = (Var *) exprstate->expr;
        TupleTableSlot *slot;
        AttrNumber      attnum;
 
-       if (isDone)
-               *isDone = ExprSingleResult;
-
        /* Get the input slot and attribute number we want */
        switch (variable->varno)
        {
@@ -677,15 +644,12 @@ ExecEvalScalarVar(ExprState *exprstate, ExprContext *econtext,
  */
 static Datum
 ExecEvalScalarVarFast(ExprState *exprstate, ExprContext *econtext,
-                                         bool *isNull, ExprDoneCond *isDone)
+                                         bool *isNull)
 {
        Var                *variable = (Var *) exprstate->expr;
        TupleTableSlot *slot;
        AttrNumber      attnum;
 
-       if (isDone)
-               *isDone = ExprSingleResult;
-
        /* Get the input slot and attribute number we want */
        switch (variable->varno)
        {
@@ -725,7 +689,7 @@ ExecEvalScalarVarFast(ExprState *exprstate, ExprContext *econtext,
  */
 static Datum
 ExecEvalWholeRowVar(WholeRowVarExprState *wrvstate, ExprContext *econtext,
-                                       bool *isNull, ExprDoneCond *isDone)
+                                       bool *isNull)
 {
        Var                *variable = (Var *) wrvstate->xprstate.expr;
        TupleTableSlot *slot;
@@ -733,9 +697,6 @@ ExecEvalWholeRowVar(WholeRowVarExprState *wrvstate, ExprContext *econtext,
        MemoryContext oldcontext;
        bool            needslow = false;
 
-       if (isDone)
-               *isDone = ExprSingleResult;
-
        /* This was checked by ExecInitExpr */
        Assert(variable->varattno == InvalidAttrNumber);
 
@@ -941,7 +902,7 @@ ExecEvalWholeRowVar(WholeRowVarExprState *wrvstate, ExprContext *econtext,
 
        /* Fetch the value */
        return (*wrvstate->xprstate.evalfunc) ((ExprState *) wrvstate, econtext,
-                                                                                  isNull, isDone);
+                                                                                  isNull);
 }
 
 /* ----------------------------------------------------------------
@@ -952,14 +913,12 @@ ExecEvalWholeRowVar(WholeRowVarExprState *wrvstate, ExprContext *econtext,
  */
 static Datum
 ExecEvalWholeRowFast(WholeRowVarExprState *wrvstate, ExprContext *econtext,
-                                        bool *isNull, ExprDoneCond *isDone)
+                                        bool *isNull)
 {
        Var                *variable = (Var *) wrvstate->xprstate.expr;
        TupleTableSlot *slot;
        HeapTupleHeader dtuple;
 
-       if (isDone)
-               *isDone = ExprSingleResult;
        *isNull = false;
 
        /* Get the input slot we want */
@@ -1008,7 +967,7 @@ ExecEvalWholeRowFast(WholeRowVarExprState *wrvstate, ExprContext *econtext,
  */
 static Datum
 ExecEvalWholeRowSlow(WholeRowVarExprState *wrvstate, ExprContext *econtext,
-                                        bool *isNull, ExprDoneCond *isDone)
+                                        bool *isNull)
 {
        Var                *variable = (Var *) wrvstate->xprstate.expr;
        TupleTableSlot *slot;
@@ -1018,8 +977,6 @@ ExecEvalWholeRowSlow(WholeRowVarExprState *wrvstate, ExprContext *econtext,
        HeapTupleHeader dtuple;
        int                     i;
 
-       if (isDone)
-               *isDone = ExprSingleResult;
        *isNull = false;
 
        /* Get the input slot we want */
@@ -1097,13 +1054,10 @@ ExecEvalWholeRowSlow(WholeRowVarExprState *wrvstate, ExprContext *econtext,
  */
 static Datum
 ExecEvalConst(ExprState *exprstate, ExprContext *econtext,
-                         bool *isNull, ExprDoneCond *isDone)
+                         bool *isNull)
 {
        Const      *con = (Const *) exprstate->expr;
 
-       if (isDone)
-               *isDone = ExprSingleResult;
-
        *isNull = con->constisnull;
        return con->constvalue;
 }
@@ -1116,15 +1070,12 @@ ExecEvalConst(ExprState *exprstate, ExprContext *econtext,
  */
 static Datum
 ExecEvalParamExec(ExprState *exprstate, ExprContext *econtext,
-                                 bool *isNull, ExprDoneCond *isDone)
+                                 bool *isNull)
 {
        Param      *expression = (Param *) exprstate->expr;
        int                     thisParamId = expression->paramid;
        ParamExecData *prm;
 
-       if (isDone)
-               *isDone = ExprSingleResult;
-
        /*
         * PARAM_EXEC params (internal executor parameters) are stored in the
         * ecxt_param_exec_vals array, and can be accessed by array index.
@@ -1149,15 +1100,12 @@ ExecEvalParamExec(ExprState *exprstate, ExprContext *econtext,
  */
 static Datum
 ExecEvalParamExtern(ExprState *exprstate, ExprContext *econtext,
-                                       bool *isNull, ExprDoneCond *isDone)
+                                       bool *isNull)
 {
        Param      *expression = (Param *) exprstate->expr;
        int                     thisParamId = expression->paramid;
        ParamListInfo paramInfo = econtext->ecxt_param_list_info;
 
-       if (isDone)
-               *isDone = ExprSingleResult;
-
        /*
         * PARAM_EXTERN parameters must be sought in ecxt_param_list_info.
         */
@@ -1421,7 +1369,6 @@ init_fcache(Oid foid, Oid input_collation, FuncExprState *fcache,
        /* Initialize additional state */
        fcache->funcResultStore = NULL;
        fcache->funcResultSlot = NULL;
-       fcache->setArgsValid = false;
        fcache->shutdown_reg = false;
 }
 
@@ -1508,47 +1455,26 @@ ShutdownTupleDescRef(Datum arg)
 /*
  * Evaluate arguments for a function.
  */
-static ExprDoneCond
+static void
 ExecEvalFuncArgs(FunctionCallInfo fcinfo,
                                 List *argList,
                                 ExprContext *econtext)
 {
-       ExprDoneCond argIsDone;
        int                     i;
        ListCell   *arg;
 
-       argIsDone = ExprSingleResult;           /* default assumption */
-
        i = 0;
        foreach(arg, argList)
        {
                ExprState  *argstate = (ExprState *) lfirst(arg);
-               ExprDoneCond thisArgIsDone;
 
                fcinfo->arg[i] = ExecEvalExpr(argstate,
                                                                          econtext,
-                                                                         &fcinfo->argnull[i],
-                                                                         &thisArgIsDone);
-
-               if (thisArgIsDone != ExprSingleResult)
-               {
-                       /*
-                        * We allow only one argument to have a set value; we'd need much
-                        * more complexity to keep track of multiple set arguments (cf.
-                        * ExecTargetList) and it doesn't seem worth it.
-                        */
-                       if (argIsDone != ExprSingleResult)
-                               ereport(ERROR,
-                                               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                                                errmsg("functions and operators can take at most one set argument")));
-                       argIsDone = thisArgIsDone;
-               }
+                                                                         &fcinfo->argnull[i]);
                i++;
        }
 
        Assert(i == fcinfo->nargs);
-
-       return argIsDone;
 }
 
 /*
@@ -1694,9 +1620,8 @@ ExecMakeFunctionResultSet(FuncExprState *fcache,
        Datum           result;
        FunctionCallInfo fcinfo;
        PgStat_FunctionCallUsage fcusage;
-       ReturnSetInfo rsinfo;           /* for functions returning sets */
-       ExprDoneCond argDone;
-       bool            hasSetArg;
+       ReturnSetInfo rsinfo;
+       bool            callit;
        int                     i;
 
 restart:
@@ -1727,6 +1652,9 @@ restart:
                else
                        elog(ERROR, "unrecognized node type: %d",
                                 (int) nodeTag(fcache->xprstate.expr));
+
+               /* shouldn't get here otherwise */
+               Assert(fcache->func.fn_retset);
        }
 
        /*
@@ -1736,7 +1664,6 @@ restart:
         */
        if (fcache->funcResultStore)
        {
-               Assert(isDone);                 /* it was provided before ... */
                if (tuplestore_gettupleslot(fcache->funcResultStore, true, false,
                                                                        fcache->funcResultSlot))
                {
@@ -1756,15 +1683,9 @@ restart:
                /* Exhausted the tuplestore, so clean up */
                tuplestore_end(fcache->funcResultStore);
                fcache->funcResultStore = NULL;
-               /* We are done unless there was a set-valued argument */
-               if (!fcache->setHasSetArg)
-               {
-                       *isDone = ExprEndResult;
-                       *isNull = true;
-                       return (Datum) 0;
-               }
-               /* If there was, continue evaluating the argument values */
-               Assert(!fcache->setArgsValid);
+               *isDone = ExprEndResult;
+               *isNull = true;
+               return (Datum) 0;
        }
 
        /*
@@ -1776,18 +1697,9 @@ restart:
        fcinfo = &fcache->fcinfo_data;
        arguments = fcache->args;
        if (!fcache->setArgsValid)
-       {
-               argDone = ExecEvalFuncArgs(fcinfo, arguments, econtext);
-               if (argDone != ExprSingleResult)
-                       ereport(ERROR,
-                                       (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                                        errmsg("set-valued function called in context that cannot accept a set")));
-               hasSetArg = false;
-       }
+               ExecEvalFuncArgs(fcinfo, arguments, econtext);
        else
        {
-               /* Re-use callinfo from previous evaluation */
-               hasSetArg = fcache->setHasSetArg;
                /* Reset flag (we may set it again below) */
                fcache->setArgsValid = false;
        }
@@ -1795,213 +1707,105 @@ restart:
        /*
         * Now call the function, passing the evaluated parameter values.
         */
-       if (fcache->func.fn_retset || hasSetArg)
-       {
-               /*
-                * We need to return a set result.  Complain if caller not ready to
-                * accept one.
-                */
-               if (isDone == NULL)
-                       ereport(ERROR,
-                                       (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                                        errmsg("set-valued function called in context that cannot accept a set")));
 
-               /*
-                * Prepare a resultinfo node for communication.  If the function
-                * doesn't itself return set, we don't pass the resultinfo to the
-                * function, but we need to fill it in anyway for internal use.
-                */
-               if (fcache->func.fn_retset)
-                       fcinfo->resultinfo = (Node *) &rsinfo;
-               rsinfo.type = T_ReturnSetInfo;
-               rsinfo.econtext = econtext;
-               rsinfo.expectedDesc = fcache->funcResultDesc;
-               rsinfo.allowedModes = (int) (SFRM_ValuePerCall | SFRM_Materialize);
-               /* note we do not set SFRM_Materialize_Random or _Preferred */
-               rsinfo.returnMode = SFRM_ValuePerCall;
-               /* isDone is filled below */
-               rsinfo.setResult = NULL;
-               rsinfo.setDesc = NULL;
+       /* Prepare a resultinfo node for communication. */
+       fcinfo->resultinfo = (Node *) &rsinfo;
+       rsinfo.type = T_ReturnSetInfo;
+       rsinfo.econtext = econtext;
+       rsinfo.expectedDesc = fcache->funcResultDesc;
+       rsinfo.allowedModes = (int) (SFRM_ValuePerCall | SFRM_Materialize);
+       /* note we do not set SFRM_Materialize_Random or _Preferred */
+       rsinfo.returnMode = SFRM_ValuePerCall;
+       /* isDone is filled below */
+       rsinfo.setResult = NULL;
+       rsinfo.setDesc = NULL;
 
-               /*
-                * This loop handles the situation where we have both a set argument
-                * and a set-valued function.  Once we have exhausted the function's
-                * value(s) for a particular argument value, we have to get the next
-                * argument value and start the function over again. We might have to
-                * do it more than once, if the function produces an empty result set
-                * for a particular input value.
-                */
-               for (;;)
+       /*
+        * If function is strict, and there are any NULL arguments, skip calling
+        * the function.
+        */
+       callit = true;
+       if (fcache->func.fn_strict)
+       {
+               for (i = 0; i < fcinfo->nargs; i++)
                {
-                       /*
-                        * If function is strict, and there are any NULL arguments, skip
-                        * calling the function (at least for this set of args).
-                        */
-                       bool            callit = true;
-
-                       if (fcache->func.fn_strict)
-                       {
-                               for (i = 0; i < fcinfo->nargs; i++)
-                               {
-                                       if (fcinfo->argnull[i])
-                                       {
-                                               callit = false;
-                                               break;
-                                       }
-                               }
-                       }
-
-                       if (callit)
-                       {
-                               pgstat_init_function_usage(fcinfo, &fcusage);
-
-                               fcinfo->isnull = false;
-                               rsinfo.isDone = ExprSingleResult;
-                               result = FunctionCallInvoke(fcinfo);
-                               *isNull = fcinfo->isnull;
-                               *isDone = rsinfo.isDone;
-
-                               pgstat_end_function_usage(&fcusage,
-                                                                               rsinfo.isDone != ExprMultipleResult);
-                       }
-                       else if (fcache->func.fn_retset)
-                       {
-                               /* for a strict SRF, result for NULL is an empty set */
-                               result = (Datum) 0;
-                               *isNull = true;
-                               *isDone = ExprEndResult;
-                       }
-                       else
-                       {
-                               /* for a strict non-SRF, result for NULL is a NULL */
-                               result = (Datum) 0;
-                               *isNull = true;
-                               *isDone = ExprSingleResult;
-                       }
-
-                       /* Which protocol does function want to use? */
-                       if (rsinfo.returnMode == SFRM_ValuePerCall)
-                       {
-                               if (*isDone != ExprEndResult)
-                               {
-                                       /*
-                                        * Got a result from current argument. If function itself
-                                        * returns set, save the current argument values to re-use
-                                        * on the next call.
-                                        */
-                                       if (fcache->func.fn_retset &&
-                                               *isDone == ExprMultipleResult)
-                                       {
-                                               fcache->setHasSetArg = hasSetArg;
-                                               fcache->setArgsValid = true;
-                                               /* Register cleanup callback if we didn't already */
-                                               if (!fcache->shutdown_reg)
-                                               {
-                                                       RegisterExprContextCallback(econtext,
-                                                                                                               ShutdownFuncExpr,
-                                                                                                       PointerGetDatum(fcache));
-                                                       fcache->shutdown_reg = true;
-                                               }
-                                       }
-
-                                       /*
-                                        * Make sure we say we are returning a set, even if the
-                                        * function itself doesn't return sets.
-                                        */
-                                       if (hasSetArg)
-                                               *isDone = ExprMultipleResult;
-                                       break;
-                               }
-                       }
-                       else if (rsinfo.returnMode == SFRM_Materialize)
+                       if (fcinfo->argnull[i])
                        {
-                               /* check we're on the same page as the function author */
-                               if (rsinfo.isDone != ExprSingleResult)
-                                       ereport(ERROR,
-                                                       (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
-                                                        errmsg("table-function protocol for materialize mode was not followed")));
-                               if (rsinfo.setResult != NULL)
-                               {
-                                       /* prepare to return values from the tuplestore */
-                                       ExecPrepareTuplestoreResult(fcache, econtext,
-                                                                                               rsinfo.setResult,
-                                                                                               rsinfo.setDesc);
-                                       /* remember whether we had set arguments */
-                                       fcache->setHasSetArg = hasSetArg;
-                                       /* loop back to top to start returning from tuplestore */
-                                       goto restart;
-                               }
-                               /* if setResult was left null, treat it as empty set */
-                               *isDone = ExprEndResult;
-                               *isNull = true;
-                               result = (Datum) 0;
+                               callit = false;
+                               break;
                        }
-                       else
-                               ereport(ERROR,
-                                               (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
-                                                errmsg("unrecognized table-function returnMode: %d",
-                                                               (int) rsinfo.returnMode)));
-
-                       /* Else, done with this argument */
-                       if (!hasSetArg)
-                               break;                  /* input not a set, so done */
+               }
+       }
 
-                       /* Re-eval args to get the next element of the input set */
-                       argDone = ExecEvalFuncArgs(fcinfo, arguments, econtext);
+       if (callit)
+       {
+               pgstat_init_function_usage(fcinfo, &fcusage);
 
-                       if (argDone != ExprMultipleResult)
-                       {
-                               /* End of argument set, so we're done. */
-                               *isNull = true;
-                               *isDone = ExprEndResult;
-                               result = (Datum) 0;
-                               break;
-                       }
+               fcinfo->isnull = false;
+               rsinfo.isDone = ExprSingleResult;
+               result = FunctionCallInvoke(fcinfo);
+               *isNull = fcinfo->isnull;
+               *isDone = rsinfo.isDone;
 
-                       /*
-                        * If we reach here, loop around to run the function on the new
-                        * argument.
-                        */
-               }
+               pgstat_end_function_usage(&fcusage,
+                                                                 rsinfo.isDone != ExprMultipleResult);
        }
        else
        {
-               /*
-                * Non-set case: much easier.
-                *
-                * In common cases, this code path is unreachable because we'd have
-                * selected ExecMakeFunctionResultNoSets instead.  However, it's
-                * possible to get here if an argument sometimes produces set results
-                * and sometimes scalar results.  For example, a CASE expression might
-                * call a set-returning function in only some of its arms.
-                */
-               if (isDone)
-                       *isDone = ExprSingleResult;
+               /* for a strict SRF, result for NULL is an empty set */
+               result = (Datum) 0;
+               *isNull = true;
+               *isDone = ExprEndResult;
+       }
 
-               /*
-                * If function is strict, and there are any NULL arguments, skip
-                * calling the function and return NULL.
-                */
-               if (fcache->func.fn_strict)
+       /* Which protocol does function want to use? */
+       if (rsinfo.returnMode == SFRM_ValuePerCall)
+       {
+               if (*isDone != ExprEndResult)
                {
-                       for (i = 0; i < fcinfo->nargs; i++)
+                       /*
+                        * Save the current argument values to re-use on the next call.
+                        */
+                       if (*isDone == ExprMultipleResult)
                        {
-                               if (fcinfo->argnull[i])
+                               fcache->setArgsValid = true;
+                               /* Register cleanup callback if we didn't already */
+                               if (!fcache->shutdown_reg)
                                {
-                                       *isNull = true;
-                                       return (Datum) 0;
+                                       RegisterExprContextCallback(econtext,
+                                                                                               ShutdownFuncExpr,
+                                                                                               PointerGetDatum(fcache));
+                                       fcache->shutdown_reg = true;
                                }
                        }
                }
-
-               pgstat_init_function_usage(fcinfo, &fcusage);
-
-               fcinfo->isnull = false;
-               result = FunctionCallInvoke(fcinfo);
-               *isNull = fcinfo->isnull;
-
-               pgstat_end_function_usage(&fcusage, true);
        }
+       else if (rsinfo.returnMode == SFRM_Materialize)
+       {
+               /* check we're on the same page as the function author */
+               if (rsinfo.isDone != ExprSingleResult)
+                       ereport(ERROR,
+                                       (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
+                                        errmsg("table-function protocol for materialize mode was not followed")));
+               if (rsinfo.setResult != NULL)
+               {
+                       /* prepare to return values from the tuplestore */
+                       ExecPrepareTuplestoreResult(fcache, econtext,
+                                                                               rsinfo.setResult,
+                                                                               rsinfo.setDesc);
+                       /* loop back to top to start returning from tuplestore */
+                       goto restart;
+               }
+               /* if setResult was left null, treat it as empty set */
+               *isDone = ExprEndResult;
+               *isNull = true;
+               result = (Datum) 0;
+       }
+       else
+               ereport(ERROR,
+                               (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
+                                errmsg("unrecognized table-function returnMode: %d",
+                                               (int) rsinfo.returnMode)));
 
        return result;
 }
@@ -2015,8 +1819,7 @@ restart:
 static Datum
 ExecMakeFunctionResultNoSets(FuncExprState *fcache,
                                                         ExprContext *econtext,
-                                                        bool *isNull,
-                                                        ExprDoneCond *isDone)
+                                                        bool *isNull)
 {
        ListCell   *arg;
        Datum           result;
@@ -2027,9 +1830,6 @@ ExecMakeFunctionResultNoSets(FuncExprState *fcache,
        /* Guard against stack overflow due to overly complex expressions */
        check_stack_depth();
 
-       if (isDone)
-               *isDone = ExprSingleResult;
-
        /* inlined, simplified version of ExecEvalFuncArgs */
        fcinfo = &fcache->fcinfo_data;
        i = 0;
@@ -2039,8 +1839,7 @@ ExecMakeFunctionResultNoSets(FuncExprState *fcache,
 
                fcinfo->arg[i] = ExecEvalExpr(argstate,
                                                                          econtext,
-                                                                         &fcinfo->argnull[i],
-                                                                         NULL);
+                                                                         &fcinfo->argnull[i]);
                i++;
        }
 
@@ -2137,7 +1936,6 @@ ExecMakeTableFunctionResult(ExprState *funcexpr,
                IsA(funcexpr->expr, FuncExpr))
        {
                FuncExprState *fcache = (FuncExprState *) funcexpr;
-               ExprDoneCond argDone;
 
                /*
                 * This path is similar to ExecMakeFunctionResultSet.
@@ -2172,15 +1970,9 @@ ExecMakeTableFunctionResult(ExprState *funcexpr,
                 */
                MemoryContextReset(argContext);
                oldcontext = MemoryContextSwitchTo(argContext);
-               argDone = ExecEvalFuncArgs(&fcinfo, fcache->args, econtext);
+               ExecEvalFuncArgs(&fcinfo, fcache->args, econtext);
                MemoryContextSwitchTo(oldcontext);
 
-               /* We don't allow sets in the arguments of the table function */
-               if (argDone != ExprSingleResult)
-                       ereport(ERROR,
-                                       (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                                        errmsg("set-valued function called in context that cannot accept a set")));
-
                /*
                 * If function is strict, and there are any NULL arguments, skip
                 * calling the function and act like it returned NULL (or an empty
@@ -2240,8 +2032,8 @@ ExecMakeTableFunctionResult(ExprState *funcexpr,
                }
                else
                {
-                       result = ExecEvalExpr(funcexpr, econtext,
-                                                                 &fcinfo.isnull, &rsinfo.isDone);
+                       result = ExecEvalExpr(funcexpr, econtext, &fcinfo.isnull);
+                       rsinfo.isDone = ExprSingleResult;
                }
 
                /* Which protocol does function want to use? */
@@ -2435,8 +2227,7 @@ no_function_result:
 static Datum
 ExecEvalFunc(FuncExprState *fcache,
                         ExprContext *econtext,
-                        bool *isNull,
-                        ExprDoneCond *isDone)
+                        bool *isNull)
 {
        /* This is called only the first time through */
        FuncExpr   *func = (FuncExpr *) fcache->xprstate.expr;
@@ -2447,7 +2238,7 @@ ExecEvalFunc(FuncExprState *fcache,
 
        /* Change the evalfunc pointer to save a few cycles in additional calls */
        fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResultNoSets;
-       return ExecMakeFunctionResultNoSets(fcache, econtext, isNull, isDone);
+       return ExecMakeFunctionResultNoSets(fcache, econtext, isNull);
 }
 
 /* ----------------------------------------------------------------
@@ -2457,8 +2248,7 @@ ExecEvalFunc(FuncExprState *fcache,
 static Datum
 ExecEvalOper(FuncExprState *fcache,
                         ExprContext *econtext,
-                        bool *isNull,
-                        ExprDoneCond *isDone)
+                        bool *isNull)
 {
        /* This is called only the first time through */
        OpExpr     *op = (OpExpr *) fcache->xprstate.expr;
@@ -2469,7 +2259,7 @@ ExecEvalOper(FuncExprState *fcache,
 
        /* Change the evalfunc pointer to save a few cycles in additional calls */
        fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResultNoSets;
-       return ExecMakeFunctionResultNoSets(fcache, econtext, isNull, isDone);
+       return ExecMakeFunctionResultNoSets(fcache, econtext, isNull);
 }
 
 /* ----------------------------------------------------------------
@@ -2486,17 +2276,13 @@ ExecEvalOper(FuncExprState *fcache,
 static Datum
 ExecEvalDistinct(FuncExprState *fcache,
                                 ExprContext *econtext,
-                                bool *isNull,
-                                ExprDoneCond *isDone)
+                                bool *isNull)
 {
        Datum           result;
        FunctionCallInfo fcinfo;
-       ExprDoneCond argDone;
 
-       /* Set default values for result flags: non-null, not a set result */
+       /* Set non-null as default */
        *isNull = false;
-       if (isDone)
-               *isDone = ExprSingleResult;
 
        /*
         * Initialize function cache if first time through
@@ -2513,11 +2299,7 @@ ExecEvalDistinct(FuncExprState *fcache,
         * Evaluate arguments
         */
        fcinfo = &fcache->fcinfo_data;
-       argDone = ExecEvalFuncArgs(fcinfo, fcache->args, econtext);
-       if (argDone != ExprSingleResult)
-               ereport(ERROR,
-                               (errcode(ERRCODE_DATATYPE_MISMATCH),
-                                errmsg("IS DISTINCT FROM does not support set arguments")));
+       ExecEvalFuncArgs(fcinfo, fcache->args, econtext);
        Assert(fcinfo->nargs == 2);
 
        if (fcinfo->argnull[0] && fcinfo->argnull[1])
@@ -2553,7 +2335,7 @@ ExecEvalDistinct(FuncExprState *fcache,
 static Datum
 ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate,
                                          ExprContext *econtext,
-                                         bool *isNull, ExprDoneCond *isDone)
+                                         bool *isNull)
 {
        ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) sstate->fxprstate.xprstate.expr;
        bool            useOr = opexpr->useOr;
@@ -2562,7 +2344,6 @@ ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate,
        Datum           result;
        bool            resultnull;
        FunctionCallInfo fcinfo;
-       ExprDoneCond argDone;
        int                     i;
        int16           typlen;
        bool            typbyval;
@@ -2571,10 +2352,8 @@ ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate,
        bits8      *bitmap;
        int                     bitmask;
 
-       /* Set default values for result flags: non-null, not a set result */
+       /* Set non-null as default */
        *isNull = false;
-       if (isDone)
-               *isDone = ExprSingleResult;
 
        /*
         * Initialize function cache if first time through
@@ -2589,11 +2368,7 @@ ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate,
         * Evaluate arguments
         */
        fcinfo = &sstate->fxprstate.fcinfo_data;
-       argDone = ExecEvalFuncArgs(fcinfo, sstate->fxprstate.args, econtext);
-       if (argDone != ExprSingleResult)
-               ereport(ERROR,
-                               (errcode(ERRCODE_DATATYPE_MISMATCH),
-                          errmsg("op ANY/ALL (array) does not support set arguments")));
+       ExecEvalFuncArgs(fcinfo, sstate->fxprstate.args, econtext);
        Assert(fcinfo->nargs == 2);
 
        /*
@@ -2739,15 +2514,12 @@ ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate,
  */
 static Datum
 ExecEvalNot(BoolExprState *notclause, ExprContext *econtext,
-                       bool *isNull, ExprDoneCond *isDone)
+                       bool *isNull)
 {
        ExprState  *clause = linitial(notclause->args);
        Datum           expr_value;
 
-       if (isDone)
-               *isDone = ExprSingleResult;
-
-       expr_value = ExecEvalExpr(clause, econtext, isNull, NULL);
+       expr_value = ExecEvalExpr(clause, econtext, isNull);
 
        /*
         * if the expression evaluates to null, then we just cascade the null back
@@ -2769,15 +2541,12 @@ ExecEvalNot(BoolExprState *notclause, ExprContext *econtext,
  */
 static Datum
 ExecEvalOr(BoolExprState *orExpr, ExprContext *econtext,
-                  bool *isNull, ExprDoneCond *isDone)
+                  bool *isNull)
 {
        List       *clauses = orExpr->args;
        ListCell   *clause;
        bool            AnyNull;
 
-       if (isDone)
-               *isDone = ExprSingleResult;
-
        AnyNull = false;
 
        /*
@@ -2798,7 +2567,7 @@ ExecEvalOr(BoolExprState *orExpr, ExprContext *econtext,
                ExprState  *clausestate = (ExprState *) lfirst(clause);
                Datum           clause_value;
 
-               clause_value = ExecEvalExpr(clausestate, econtext, isNull, NULL);
+               clause_value = ExecEvalExpr(clausestate, econtext, isNull);
 
                /*
                 * if we have a non-null true result, then return it.
@@ -2820,15 +2589,12 @@ ExecEvalOr(BoolExprState *orExpr, ExprContext *econtext,
  */
 static Datum
 ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
-                       bool *isNull, ExprDoneCond *isDone)
+                       bool *isNull)
 {
        List       *clauses = andExpr->args;
        ListCell   *clause;
        bool            AnyNull;
 
-       if (isDone)
-               *isDone = ExprSingleResult;
-
        AnyNull = false;
 
        /*
@@ -2845,7 +2611,7 @@ ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
                ExprState  *clausestate = (ExprState *) lfirst(clause);
                Datum           clause_value;
 
-               clause_value = ExecEvalExpr(clausestate, econtext, isNull, NULL);
+               clause_value = ExecEvalExpr(clausestate, econtext, isNull);
 
                /*
                 * if we have a non-null false result, then return it.
@@ -2871,7 +2637,7 @@ ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
 static Datum
 ExecEvalConvertRowtype(ConvertRowtypeExprState *cstate,
                                           ExprContext *econtext,
-                                          bool *isNull, ExprDoneCond *isDone)
+                                          bool *isNull)
 {
        ConvertRowtypeExpr *convert = (ConvertRowtypeExpr *) cstate->xprstate.expr;
        HeapTuple       result;
@@ -2879,7 +2645,7 @@ ExecEvalConvertRowtype(ConvertRowtypeExprState *cstate,
        HeapTupleHeader tuple;
        HeapTupleData tmptup;
 
-       tupDatum = ExecEvalExpr(cstate->arg, econtext, isNull, isDone);
+       tupDatum = ExecEvalExpr(cstate->arg, econtext, isNull);
 
        /* this test covers the isDone exception too: */
        if (*isNull)
@@ -2955,16 +2721,13 @@ ExecEvalConvertRowtype(ConvertRowtypeExprState *cstate,
  */
 static Datum
 ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
-                        bool *isNull, ExprDoneCond *isDone)
+                        bool *isNull)
 {
        List       *clauses = caseExpr->args;
        ListCell   *clause;
        Datum           save_datum;
        bool            save_isNull;
 
-       if (isDone)
-               *isDone = ExprSingleResult;
-
        /*
         * If there's a test expression, we have to evaluate it and save the value
         * where the CaseTestExpr placeholders can find it.  We must save and
@@ -2989,8 +2752,7 @@ ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
 
                arg_value = ExecEvalExpr(caseExpr->arg,
                                                                 econtext,
-                                                                &arg_isNull,
-                                                                NULL);
+                                                                &arg_isNull);
                /* Since caseValue_datum may be read multiple times, force to R/O */
                econtext->caseValue_datum =
                        MakeExpandedObjectReadOnly(arg_value,
@@ -3012,8 +2774,7 @@ ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
 
                clause_value = ExecEvalExpr(wclause->expr,
                                                                        econtext,
-                                                                       &clause_isNull,
-                                                                       NULL);
+                                                                       &clause_isNull);
 
                /*
                 * if we have a true test, then we return the result, since the case
@@ -3026,8 +2787,7 @@ ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
                        econtext->caseValue_isNull = save_isNull;
                        return ExecEvalExpr(wclause->result,
                                                                econtext,
-                                                               isNull,
-                                                               isDone);
+                                                               isNull);
                }
        }
 
@@ -3038,8 +2798,7 @@ ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
        {
                return ExecEvalExpr(caseExpr->defresult,
                                                        econtext,
-                                                       isNull,
-                                                       isDone);
+                                                       isNull);
        }
 
        *isNull = true;
@@ -3054,10 +2813,8 @@ ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
 static Datum
 ExecEvalCaseTestExpr(ExprState *exprstate,
                                         ExprContext *econtext,
-                                        bool *isNull, ExprDoneCond *isDone)
+                                        bool *isNull)
 {
-       if (isDone)
-               *isDone = ExprSingleResult;
        *isNull = econtext->caseValue_isNull;
        return econtext->caseValue_datum;
 }
@@ -3074,17 +2831,13 @@ ExecEvalCaseTestExpr(ExprState *exprstate,
 static Datum
 ExecEvalGroupingFuncExpr(GroupingFuncExprState *gstate,
                                                 ExprContext *econtext,
-                                                bool *isNull,
-                                                ExprDoneCond *isDone)
+                                                bool *isNull)
 {
        int                     result = 0;
        int                     attnum = 0;
        Bitmapset  *grouped_cols = gstate->aggstate->grouped_cols;
        ListCell   *lc;
 
-       if (isDone)
-               *isDone = ExprSingleResult;
-
        *isNull = false;
 
        foreach(lc, (gstate->clauses))
@@ -3106,7 +2859,7 @@ ExecEvalGroupingFuncExpr(GroupingFuncExprState *gstate,
  */
 static Datum
 ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
-                         bool *isNull, ExprDoneCond *isDone)
+                         bool *isNull)
 {
        ArrayExpr  *arrayExpr = (ArrayExpr *) astate->xprstate.expr;
        ArrayType  *result;
@@ -3116,10 +2869,8 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
        int                     dims[MAXDIM];
        int                     lbs[MAXDIM];
 
-       /* Set default values for result flags: non-null, not a set result */
+       /* Set non-null as default */
        *isNull = false;
-       if (isDone)
-               *isDone = ExprSingleResult;
 
        if (!arrayExpr->multidims)
        {
@@ -3144,7 +2895,7 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
                {
                        ExprState  *e = (ExprState *) lfirst(element);
 
-                       dvalues[i] = ExecEvalExpr(e, econtext, &dnulls[i], NULL);
+                       dvalues[i] = ExecEvalExpr(e, econtext, &dnulls[i]);
                        i++;
                }
 
@@ -3194,7 +2945,7 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
                        ArrayType  *array;
                        int                     this_ndims;
 
-                       arraydatum = ExecEvalExpr(e, econtext, &eisnull, NULL);
+                       arraydatum = ExecEvalExpr(e, econtext, &eisnull);
                        /* temporarily ignore null subarrays */
                        if (eisnull)
                        {
@@ -3333,7 +3084,7 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
 static Datum
 ExecEvalRow(RowExprState *rstate,
                        ExprContext *econtext,
-                       bool *isNull, ExprDoneCond *isDone)
+                       bool *isNull)
 {
        HeapTuple       tuple;
        Datum      *values;
@@ -3342,10 +3093,8 @@ ExecEvalRow(RowExprState *rstate,
        ListCell   *arg;
        int                     i;
 
-       /* Set default values for result flags: non-null, not a set result */
+       /* Set non-null as default */
        *isNull = false;
-       if (isDone)
-               *isDone = ExprSingleResult;
 
        /* Allocate workspace */
        natts = rstate->tupdesc->natts;
@@ -3361,7 +3110,7 @@ ExecEvalRow(RowExprState *rstate,
        {
                ExprState  *e = (ExprState *) lfirst(arg);
 
-               values[i] = ExecEvalExpr(e, econtext, &isnull[i], NULL);
+               values[i] = ExecEvalExpr(e, econtext, &isnull[i]);
                i++;
        }
 
@@ -3380,7 +3129,7 @@ ExecEvalRow(RowExprState *rstate,
 static Datum
 ExecEvalRowCompare(RowCompareExprState *rstate,
                                   ExprContext *econtext,
-                                  bool *isNull, ExprDoneCond *isDone)
+                                  bool *isNull)
 {
        bool            result;
        RowCompareType rctype = ((RowCompareExpr *) rstate->xprstate.expr)->rctype;
@@ -3389,8 +3138,6 @@ ExecEvalRowCompare(RowCompareExprState *rstate,
        ListCell   *r;
        int                     i;
 
-       if (isDone)
-               *isDone = ExprSingleResult;
        *isNull = true;                         /* until we get a result */
 
        i = 0;
@@ -3404,9 +3151,9 @@ ExecEvalRowCompare(RowCompareExprState *rstate,
                                                                 rstate->collations[i],
                                                                 NULL, NULL);
                locfcinfo.arg[0] = ExecEvalExpr(le, econtext,
-                                                                               &locfcinfo.argnull[0], NULL);
+                                                                               &locfcinfo.argnull[0]);
                locfcinfo.arg[1] = ExecEvalExpr(re, econtext,
-                                                                               &locfcinfo.argnull[1], NULL);
+                                                                               &locfcinfo.argnull[1]);
                if (rstate->funcs[i].fn_strict &&
                        (locfcinfo.argnull[0] || locfcinfo.argnull[1]))
                        return (Datum) 0;       /* force NULL result */
@@ -3450,20 +3197,17 @@ ExecEvalRowCompare(RowCompareExprState *rstate,
  */
 static Datum
 ExecEvalCoalesce(CoalesceExprState *coalesceExpr, ExprContext *econtext,
-                                bool *isNull, ExprDoneCond *isDone)
+                                bool *isNull)
 {
        ListCell   *arg;
 
-       if (isDone)
-               *isDone = ExprSingleResult;
-
        /* Simply loop through until something NOT NULL is found */
        foreach(arg, coalesceExpr->args)
        {
                ExprState  *e = (ExprState *) lfirst(arg);
                Datum           value;
 
-               value = ExecEvalExpr(e, econtext, isNull, NULL);
+               value = ExecEvalExpr(e, econtext, isNull);
                if (!*isNull)
                        return value;
        }
@@ -3479,7 +3223,7 @@ ExecEvalCoalesce(CoalesceExprState *coalesceExpr, ExprContext *econtext,
  */
 static Datum
 ExecEvalMinMax(MinMaxExprState *minmaxExpr, ExprContext *econtext,
-                          bool *isNull, ExprDoneCond *isDone)
+                          bool *isNull)
 {
        Datum           result = (Datum) 0;
        MinMaxExpr *minmax = (MinMaxExpr *) minmaxExpr->xprstate.expr;
@@ -3488,8 +3232,6 @@ ExecEvalMinMax(MinMaxExprState *minmaxExpr, ExprContext *econtext,
        FunctionCallInfoData locfcinfo;
        ListCell   *arg;
 
-       if (isDone)
-               *isDone = ExprSingleResult;
        *isNull = true;                         /* until we get a result */
 
        InitFunctionCallInfoData(locfcinfo, &minmaxExpr->cfunc, 2,
@@ -3504,7 +3246,7 @@ ExecEvalMinMax(MinMaxExprState *minmaxExpr, ExprContext *econtext,
                bool            valueIsNull;
                int32           cmpresult;
 
-               value = ExecEvalExpr(e, econtext, &valueIsNull, NULL);
+               value = ExecEvalExpr(e, econtext, &valueIsNull);
                if (valueIsNull)
                        continue;                       /* ignore NULL inputs */
 
@@ -3540,14 +3282,12 @@ ExecEvalMinMax(MinMaxExprState *minmaxExpr, ExprContext *econtext,
 static Datum
 ExecEvalSQLValueFunction(ExprState *svfExpr,
                                                 ExprContext *econtext,
-                                                bool *isNull, ExprDoneCond *isDone)
+                                                bool *isNull)
 {
        Datum           result = (Datum) 0;
        SQLValueFunction *svf = (SQLValueFunction *) svfExpr->expr;
        FunctionCallInfoData fcinfo;
 
-       if (isDone)
-               *isDone = ExprSingleResult;
        *isNull = false;
 
        /*
@@ -3608,7 +3348,7 @@ ExecEvalSQLValueFunction(ExprState *svfExpr,
  */
 static Datum
 ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
-                       bool *isNull, ExprDoneCond *isDone)
+                       bool *isNull)
 {
        XmlExpr    *xexpr = (XmlExpr *) xmlExpr->xprstate.expr;
        Datum           value;
@@ -3616,8 +3356,6 @@ ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
        ListCell   *arg;
        ListCell   *narg;
 
-       if (isDone)
-               *isDone = ExprSingleResult;
        *isNull = true;                         /* until we get a result */
 
        switch (xexpr->op)
@@ -3630,7 +3368,7 @@ ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
                                {
                                        ExprState  *e = (ExprState *) lfirst(arg);
 
-                                       value = ExecEvalExpr(e, econtext, &isnull, NULL);
+                                       value = ExecEvalExpr(e, econtext, &isnull);
                                        if (!isnull)
                                                values = lappend(values, DatumGetPointer(value));
                                }
@@ -3655,7 +3393,7 @@ ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
                                        ExprState  *e = (ExprState *) lfirst(arg);
                                        char       *argname = strVal(lfirst(narg));
 
-                                       value = ExecEvalExpr(e, econtext, &isnull, NULL);
+                                       value = ExecEvalExpr(e, econtext, &isnull);
                                        if (!isnull)
                                        {
                                                appendStringInfo(&buf, "<%s>%s</%s>",
@@ -3698,13 +3436,13 @@ ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
                                Assert(list_length(xmlExpr->args) == 2);
 
                                e = (ExprState *) linitial(xmlExpr->args);
-                               value = ExecEvalExpr(e, econtext, &isnull, NULL);
+                               value = ExecEvalExpr(e, econtext, &isnull);
                                if (isnull)
                                        return (Datum) 0;
                                data = DatumGetTextP(value);
 
                                e = (ExprState *) lsecond(xmlExpr->args);
-                               value = ExecEvalExpr(e, econtext, &isnull, NULL);
+                               value = ExecEvalExpr(e, econtext, &isnull);
                                if (isnull)             /* probably can't happen */
                                        return (Datum) 0;
                                preserve_whitespace = DatumGetBool(value);
@@ -3728,7 +3466,7 @@ ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
                                if (xmlExpr->args)
                                {
                                        e = (ExprState *) linitial(xmlExpr->args);
-                                       value = ExecEvalExpr(e, econtext, &isnull, NULL);
+                                       value = ExecEvalExpr(e, econtext, &isnull);
                                        if (isnull)
                                                arg = NULL;
                                        else
@@ -3755,20 +3493,20 @@ ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
                                Assert(list_length(xmlExpr->args) == 3);
 
                                e = (ExprState *) linitial(xmlExpr->args);
-                               value = ExecEvalExpr(e, econtext, &isnull, NULL);
+                               value = ExecEvalExpr(e, econtext, &isnull);
                                if (isnull)
                                        return (Datum) 0;
                                data = DatumGetXmlP(value);
 
                                e = (ExprState *) lsecond(xmlExpr->args);
-                               value = ExecEvalExpr(e, econtext, &isnull, NULL);
+                               value = ExecEvalExpr(e, econtext, &isnull);
                                if (isnull)
                                        version = NULL;
                                else
                                        version = DatumGetTextP(value);
 
                                e = (ExprState *) lthird(xmlExpr->args);
-                               value = ExecEvalExpr(e, econtext, &isnull, NULL);
+                               value = ExecEvalExpr(e, econtext, &isnull);
                                standalone = DatumGetInt32(value);
 
                                *isNull = false;
@@ -3787,7 +3525,7 @@ ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
                                Assert(list_length(xmlExpr->args) == 1);
 
                                e = (ExprState *) linitial(xmlExpr->args);
-                               value = ExecEvalExpr(e, econtext, &isnull, NULL);
+                               value = ExecEvalExpr(e, econtext, &isnull);
                                if (isnull)
                                        return (Datum) 0;
 
@@ -3805,7 +3543,7 @@ ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
                                Assert(list_length(xmlExpr->args) == 1);
 
                                e = (ExprState *) linitial(xmlExpr->args);
-                               value = ExecEvalExpr(e, econtext, &isnull, NULL);
+                               value = ExecEvalExpr(e, econtext, &isnull);
                                if (isnull)
                                        return (Datum) 0;
                                else
@@ -3832,14 +3570,10 @@ ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
 static Datum
 ExecEvalNullIf(FuncExprState *nullIfExpr,
                           ExprContext *econtext,
-                          bool *isNull, ExprDoneCond *isDone)
+                          bool *isNull)
 {
        Datum           result;
        FunctionCallInfo fcinfo;
-       ExprDoneCond argDone;
-
-       if (isDone)
-               *isDone = ExprSingleResult;
 
        /*
         * Initialize function cache if first time through
@@ -3856,11 +3590,7 @@ ExecEvalNullIf(FuncExprState *nullIfExpr,
         * Evaluate arguments
         */
        fcinfo = &nullIfExpr->fcinfo_data;
-       argDone = ExecEvalFuncArgs(fcinfo, nullIfExpr->args, econtext);
-       if (argDone != ExprSingleResult)
-               ereport(ERROR,
-                               (errcode(ERRCODE_DATATYPE_MISMATCH),
-                                errmsg("NULLIF does not support set arguments")));
+       ExecEvalFuncArgs(fcinfo, nullIfExpr->args, econtext);
        Assert(fcinfo->nargs == 2);
 
        /* if either argument is NULL they can't be equal */
@@ -3890,16 +3620,12 @@ ExecEvalNullIf(FuncExprState *nullIfExpr,
 static Datum
 ExecEvalNullTest(NullTestState *nstate,
                                 ExprContext *econtext,
-                                bool *isNull,
-                                ExprDoneCond *isDone)
+                                bool *isNull)
 {
        NullTest   *ntest = (NullTest *) nstate->xprstate.expr;
        Datum           result;
 
-       result = ExecEvalExpr(nstate->arg, econtext, isNull, isDone);
-
-       if (isDone && *isDone == ExprEndResult)
-               return result;                  /* nothing to check */
+       result = ExecEvalExpr(nstate->arg, econtext, isNull);
 
        if (ntest->argisrow && !(*isNull))
        {
@@ -3999,16 +3725,12 @@ ExecEvalNullTest(NullTestState *nstate,
 static Datum
 ExecEvalBooleanTest(GenericExprState *bstate,
                                        ExprContext *econtext,
-                                       bool *isNull,
-                                       ExprDoneCond *isDone)
+                                       bool *isNull)
 {
        BooleanTest *btest = (BooleanTest *) bstate->xprstate.expr;
        Datum           result;
 
-       result = ExecEvalExpr(bstate->arg, econtext, isNull, isDone);
-
-       if (isDone && *isDone == ExprEndResult)
-               return result;                  /* nothing to check */
+       result = ExecEvalExpr(bstate->arg, econtext, isNull);
 
        switch (btest->booltesttype)
        {
@@ -4084,16 +3806,13 @@ ExecEvalBooleanTest(GenericExprState *bstate,
  */
 static Datum
 ExecEvalCoerceToDomain(CoerceToDomainState *cstate, ExprContext *econtext,
-                                          bool *isNull, ExprDoneCond *isDone)
+                                          bool *isNull)
 {
        CoerceToDomain *ctest = (CoerceToDomain *) cstate->xprstate.expr;
        Datum           result;
        ListCell   *l;
 
-       result = ExecEvalExpr(cstate->arg, econtext, isNull, isDone);
-
-       if (isDone && *isDone == ExprEndResult)
-               return result;                  /* nothing to check */
+       result = ExecEvalExpr(cstate->arg, econtext, isNull);
 
        /* Make sure we have up-to-date constraints */
        UpdateDomainConstraintRef(cstate->constraint_ref);
@@ -4138,8 +3857,8 @@ ExecEvalCoerceToDomain(CoerceToDomainState *cstate, ExprContext *econtext,
                                                                         cstate->constraint_ref->tcache->typlen);
                                        econtext->domainValue_isNull = *isNull;
 
-                                       conResult = ExecEvalExpr(con->check_expr,
-                                                                                        econtext, &conIsNull, NULL);
+                                       conResult = ExecEvalExpr(con->check_expr, econtext,
+                                                                                        &conIsNull);
 
                                        if (!conIsNull &&
                                                !DatumGetBool(conResult))
@@ -4174,10 +3893,8 @@ ExecEvalCoerceToDomain(CoerceToDomainState *cstate, ExprContext *econtext,
 static Datum
 ExecEvalCoerceToDomainValue(ExprState *exprstate,
                                                        ExprContext *econtext,
-                                                       bool *isNull, ExprDoneCond *isDone)
+                                                       bool *isNull)
 {
-       if (isDone)
-               *isDone = ExprSingleResult;
        *isNull = econtext->domainValue_isNull;
        return econtext->domainValue_datum;
 }
@@ -4191,8 +3908,7 @@ ExecEvalCoerceToDomainValue(ExprState *exprstate,
 static Datum
 ExecEvalFieldSelect(FieldSelectState *fstate,
                                        ExprContext *econtext,
-                                       bool *isNull,
-                                       ExprDoneCond *isDone)
+                                       bool *isNull)
 {
        FieldSelect *fselect = (FieldSelect *) fstate->xprstate.expr;
        AttrNumber      fieldnum = fselect->fieldnum;
@@ -4205,9 +3921,8 @@ ExecEvalFieldSelect(FieldSelectState *fstate,
        Form_pg_attribute attr;
        HeapTupleData tmptup;
 
-       tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull, isDone);
+       tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull);
 
-       /* this test covers the isDone exception too: */
        if (*isNull)
                return tupDatum;
 
@@ -4270,8 +3985,7 @@ ExecEvalFieldSelect(FieldSelectState *fstate,
 static Datum
 ExecEvalFieldStore(FieldStoreState *fstate,
                                   ExprContext *econtext,
-                                  bool *isNull,
-                                  ExprDoneCond *isDone)
+                                  bool *isNull)
 {
        FieldStore *fstore = (FieldStore *) fstate->xprstate.expr;
        HeapTuple       tuple;
@@ -4284,10 +3998,7 @@ ExecEvalFieldStore(FieldStoreState *fstate,
        ListCell   *l1,
                           *l2;
 
-       tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull, isDone);
-
-       if (isDone && *isDone == ExprEndResult)
-               return tupDatum;
+       tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull);
 
        /* Lookup tupdesc if first time through or after rescan */
        tupDesc = get_cached_rowtype(fstore->resulttype, -1,
@@ -4347,8 +4058,7 @@ ExecEvalFieldStore(FieldStoreState *fstate,
 
                values[fieldnum - 1] = ExecEvalExpr(newval,
                                                                                        econtext,
-                                                                                       &isnull[fieldnum - 1],
-                                                                                       NULL);
+                                                                                       &isnull[fieldnum - 1]);
        }
 
        econtext->caseValue_datum = save_datum;
@@ -4371,9 +4081,9 @@ ExecEvalFieldStore(FieldStoreState *fstate,
 static Datum
 ExecEvalRelabelType(GenericExprState *exprstate,
                                        ExprContext *econtext,
-                                       bool *isNull, ExprDoneCond *isDone)
+                                       bool *isNull)
 {
-       return ExecEvalExpr(exprstate->arg, econtext, isNull, isDone);
+       return ExecEvalExpr(exprstate->arg, econtext, isNull);
 }
 
 /* ----------------------------------------------------------------
@@ -4385,16 +4095,13 @@ ExecEvalRelabelType(GenericExprState *exprstate,
 static Datum
 ExecEvalCoerceViaIO(CoerceViaIOState *iostate,
                                        ExprContext *econtext,
-                                       bool *isNull, ExprDoneCond *isDone)
+                                       bool *isNull)
 {
        Datum           result;
        Datum           inputval;
        char       *string;
 
-       inputval = ExecEvalExpr(iostate->arg, econtext, isNull, isDone);
-
-       if (isDone && *isDone == ExprEndResult)
-               return inputval;                /* nothing to do */
+       inputval = ExecEvalExpr(iostate->arg, econtext, isNull);
 
        if (*isNull)
                string = NULL;                  /* output functions are not called on nulls */
@@ -4419,16 +4126,14 @@ ExecEvalCoerceViaIO(CoerceViaIOState *iostate,
 static Datum
 ExecEvalArrayCoerceExpr(ArrayCoerceExprState *astate,
                                                ExprContext *econtext,
-                                               bool *isNull, ExprDoneCond *isDone)
+                                               bool *isNull)
 {
        ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) astate->xprstate.expr;
        Datum           result;
        FunctionCallInfoData locfcinfo;
 
-       result = ExecEvalExpr(astate->arg, econtext, isNull, isDone);
+       result = ExecEvalExpr(astate->arg, econtext, isNull);
 
-       if (isDone && *isDone == ExprEndResult)
-               return result;                  /* nothing to do */
        if (*isNull)
                return result;                  /* nothing to do */
 
@@ -4496,7 +4201,7 @@ ExecEvalArrayCoerceExpr(ArrayCoerceExprState *astate,
  */
 static Datum
 ExecEvalCurrentOfExpr(ExprState *exprstate, ExprContext *econtext,
-                                         bool *isNull, ExprDoneCond *isDone)
+                                         bool *isNull)
 {
        ereport(ERROR,
                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -4513,14 +4218,13 @@ ExecEvalCurrentOfExpr(ExprState *exprstate, ExprContext *econtext,
 Datum
 ExecEvalExprSwitchContext(ExprState *expression,
                                                  ExprContext *econtext,
-                                                 bool *isNull,
-                                                 ExprDoneCond *isDone)
+                                                 bool *isNull)
 {
        Datum           retDatum;
        MemoryContext oldContext;
 
        oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
-       retDatum = ExecEvalExpr(expression, econtext, isNull, isDone);
+       retDatum = ExecEvalExpr(expression, econtext, isNull);
        MemoryContextSwitchTo(oldContext);
        return retDatum;
 }
@@ -5387,7 +5091,7 @@ ExecQual(List *qual, ExprContext *econtext, bool resultForNull)
                Datum           expr_value;
                bool            isNull;
 
-               expr_value = ExecEvalExpr(clause, econtext, &isNull, NULL);
+               expr_value = ExecEvalExpr(clause, econtext, &isNull);
 
                if (isNull)
                {
@@ -5445,17 +5149,11 @@ ExecCleanTargetListLength(List *targetlist)
 /*
  * ExecTargetList
  *             Evaluates a targetlist with respect to the given
- *             expression context.  Returns TRUE if we were able to create
- *             a result, FALSE if we have exhausted a set-valued expression.
+ *             expression context.
  *
- * Results are stored into the passed values and isnull arrays.
- * The caller must provide an itemIsDone array that persists across calls.
+ * tupdesc must describe the rowtype of the expected result.
  *
- * As with ExecEvalExpr, the caller should pass isDone = NULL if not
- * prepared to deal with sets of result tuples.  Otherwise, a return
- * of *isDone = ExprMultipleResult signifies a set element, and a return
- * of *isDone = ExprEndResult signifies end of the set of tuple.
- * We assume that *isDone has been initialized to ExprSingleResult by caller.
+ * Results are stored into the passed values and isnull arrays.
  *
  * Since fields of the result tuple might be multiply referenced in higher
  * plan nodes, we have to force any read/write expanded values to read-only
@@ -5464,19 +5162,16 @@ ExecCleanTargetListLength(List *targetlist)
  * actually-multiply-referenced Vars and insert an expression node that
  * would do that only where really required.
  */
-static bool
+static void
 ExecTargetList(List *targetlist,
                           TupleDesc tupdesc,
                           ExprContext *econtext,
                           Datum *values,
-                          bool *isnull,
-                          ExprDoneCond *itemIsDone,
-                          ExprDoneCond *isDone)
+                          bool *isnull)
 {
        Form_pg_attribute *att = tupdesc->attrs;
        MemoryContext oldContext;
        ListCell   *tl;
-       bool            haveDoneSets;
 
        /*
         * Run in short-lived per-tuple context while computing expressions.
@@ -5486,8 +5181,6 @@ ExecTargetList(List *targetlist,
        /*
         * evaluate all the expressions in the target list
         */
-       haveDoneSets = false;           /* any exhausted set exprs in tlist? */
-
        foreach(tl, targetlist)
        {
                GenericExprState *gstate = (GenericExprState *) lfirst(tl);
@@ -5496,117 +5189,14 @@ ExecTargetList(List *targetlist,
 
                values[resind] = ExecEvalExpr(gstate->arg,
                                                                          econtext,
-                                                                         &isnull[resind],
-                                                                         &itemIsDone[resind]);
+                                                                         &isnull[resind]);
 
                values[resind] = MakeExpandedObjectReadOnly(values[resind],
                                                                                                        isnull[resind],
                                                                                                        att[resind]->attlen);
-
-               if (itemIsDone[resind] != ExprSingleResult)
-               {
-                       /* We have a set-valued expression in the tlist */
-                       if (isDone == NULL)
-                               ereport(ERROR,
-                                               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                                                errmsg("set-valued function called in context that cannot accept a set")));
-                       if (itemIsDone[resind] == ExprMultipleResult)
-                       {
-                               /* we have undone sets in the tlist, set flag */
-                               *isDone = ExprMultipleResult;
-                       }
-                       else
-                       {
-                               /* we have done sets in the tlist, set flag for that */
-                               haveDoneSets = true;
-                       }
-               }
        }
 
-       if (haveDoneSets)
-       {
-               /*
-                * note: can't get here unless we verified isDone != NULL
-                */
-               if (*isDone == ExprSingleResult)
-               {
-                       /*
-                        * all sets are done, so report that tlist expansion is complete.
-                        */
-                       *isDone = ExprEndResult;
-                       MemoryContextSwitchTo(oldContext);
-                       return false;
-               }
-               else
-               {
-                       /*
-                        * We have some done and some undone sets.  Restart the done ones
-                        * so that we can deliver a tuple (if possible).
-                        */
-                       foreach(tl, targetlist)
-                       {
-                               GenericExprState *gstate = (GenericExprState *) lfirst(tl);
-                               TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
-                               AttrNumber      resind = tle->resno - 1;
-
-                               if (itemIsDone[resind] == ExprEndResult)
-                               {
-                                       values[resind] = ExecEvalExpr(gstate->arg,
-                                                                                                 econtext,
-                                                                                                 &isnull[resind],
-                                                                                                 &itemIsDone[resind]);
-
-                                       values[resind] = MakeExpandedObjectReadOnly(values[resind],
-                                                                                                                         isnull[resind],
-                                                                                                               att[resind]->attlen);
-
-                                       if (itemIsDone[resind] == ExprEndResult)
-                                       {
-                                               /*
-                                                * Oh dear, this item is returning an empty set. Guess
-                                                * we can't make a tuple after all.
-                                                */
-                                               *isDone = ExprEndResult;
-                                               break;
-                                       }
-                               }
-                       }
-
-                       /*
-                        * If we cannot make a tuple because some sets are empty, we still
-                        * have to cycle the nonempty sets to completion, else resources
-                        * will not be released from subplans etc.
-                        *
-                        * XXX is that still necessary?
-                        */
-                       if (*isDone == ExprEndResult)
-                       {
-                               foreach(tl, targetlist)
-                               {
-                                       GenericExprState *gstate = (GenericExprState *) lfirst(tl);
-                                       TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
-                                       AttrNumber      resind = tle->resno - 1;
-
-                                       while (itemIsDone[resind] == ExprMultipleResult)
-                                       {
-                                               values[resind] = ExecEvalExpr(gstate->arg,
-                                                                                                         econtext,
-                                                                                                         &isnull[resind],
-                                                                                                         &itemIsDone[resind]);
-                                               /* no need for MakeExpandedObjectReadOnly */
-                                       }
-                               }
-
-                               MemoryContextSwitchTo(oldContext);
-                               return false;
-                       }
-               }
-       }
-
-       /* Report success */
        MemoryContextSwitchTo(oldContext);
-
-       return true;
 }
 
 /*
@@ -5623,7 +5213,7 @@ ExecTargetList(List *targetlist,
  *             result slot.
  */
 TupleTableSlot *
-ExecProject(ProjectionInfo *projInfo, ExprDoneCond *isDone)
+ExecProject(ProjectionInfo *projInfo)
 {
        TupleTableSlot *slot;
        ExprContext *econtext;
@@ -5640,14 +5230,9 @@ ExecProject(ProjectionInfo *projInfo, ExprDoneCond *isDone)
        slot = projInfo->pi_slot;
        econtext = projInfo->pi_exprContext;
 
-       /* Assume single result row until proven otherwise */
-       if (isDone)
-               *isDone = ExprSingleResult;
-
        /*
         * Clear any former contents of the result slot.  This makes it safe for
-        * us to use the slot's Datum/isnull arrays as workspace. (Also, we can
-        * return the slot as-is if we decide no rows can be projected.)
+        * us to use the slot's Datum/isnull arrays as workspace.
         */
        ExecClearTuple(slot);
 
@@ -5711,26 +5296,19 @@ ExecProject(ProjectionInfo *projInfo, ExprDoneCond *isDone)
        }
 
        /*
-        * If there are any generic expressions, evaluate them.  It's possible
-        * that there are set-returning functions in such expressions; if so and
-        * we have reached the end of the set, we return the result slot, which we
-        * already marked empty.
+        * If there are any generic expressions, evaluate them.
         */
        if (projInfo->pi_targetlist)
        {
-               if (!ExecTargetList(projInfo->pi_targetlist,
-                                                       slot->tts_tupleDescriptor,
-                                                       econtext,
-                                                       slot->tts_values,
-                                                       slot->tts_isnull,
-                                                       projInfo->pi_itemIsDone,
-                                                       isDone))
-                       return slot;            /* no more result rows, return empty slot */
+               ExecTargetList(projInfo->pi_targetlist,
+                                          slot->tts_tupleDescriptor,
+                                          econtext,
+                                          slot->tts_values,
+                                          slot->tts_isnull);
        }
 
        /*
-        * Successfully formed a result row.  Mark the result slot as containing a
-        * valid virtual tuple.
+        * Mark the result slot as containing a valid virtual tuple.
         */
        return ExecStoreVirtualTuple(slot);
 }
index f97db9c2112ad7b6f2f06035a9deb393a39ea293..65196795d7004831e6959e3cef610b8928796471 100644 (file)
@@ -125,8 +125,6 @@ ExecScan(ScanState *node,
        ExprContext *econtext;
        List       *qual;
        ProjectionInfo *projInfo;
-       ExprDoneCond isDone;
-       TupleTableSlot *resultSlot;
 
        /*
         * Fetch data from node
@@ -145,25 +143,9 @@ ExecScan(ScanState *node,
                return ExecScanFetch(node, accessMtd, recheckMtd);
        }
 
-       /*
-        * Check to see if we're still projecting out tuples from a previous scan
-        * tuple (because there is a function-returning-set in the projection
-        * expressions).  If so, try to project another one.
-        */
-       if (node->ps.ps_TupFromTlist)
-       {
-               Assert(projInfo);               /* can't get here if not projecting */
-               resultSlot = ExecProject(projInfo, &isDone);
-               if (isDone == ExprMultipleResult)
-                       return resultSlot;
-               /* Done with that source tuple... */
-               node->ps.ps_TupFromTlist = false;
-       }
-
        /*
         * Reset per-tuple memory context to free any expression evaluation
-        * storage allocated in the previous tuple cycle.  Note this can't happen
-        * until we're done projecting out tuples from a scan tuple.
+        * storage allocated in the previous tuple cycle.
         */
        ResetExprContext(econtext);
 
@@ -214,15 +196,9 @@ ExecScan(ScanState *node,
                        {
                                /*
                                 * Form a projection tuple, store it in the result tuple slot
-                                * and return it --- unless we find we can project no tuples
-                                * from this scan tuple, in which case continue scan.
+                                * and return it.
                                 */
-                               resultSlot = ExecProject(projInfo, &isDone);
-                               if (isDone != ExprEndResult)
-                               {
-                                       node->ps.ps_TupFromTlist = (isDone == ExprMultipleResult);
-                                       return resultSlot;
-                               }
+                               return ExecProject(projInfo);
                        }
                        else
                        {
@@ -352,9 +328,6 @@ ExecScanReScan(ScanState *node)
 {
        EState     *estate = node->ps.state;
 
-       /* Stop projecting any tuples from SRFs in the targetlist */
-       node->ps.ps_TupFromTlist = false;
-
        /* Rescan EvalPlanQual tuple if we're inside an EvalPlanQual recheck */
        if (estate->es_epqScanDone != NULL)
        {
index 70646fd15a7f97f4292ddef486e02af3975630a2..e49feff6c0fac17794a094e3b73adc473a1cae20 100644 (file)
@@ -586,12 +586,6 @@ ExecBuildProjectionInfo(List *targetList,
        projInfo->pi_numSimpleVars = numSimpleVars;
        projInfo->pi_directMap = directMap;
 
-       if (exprlist == NIL)
-               projInfo->pi_itemIsDone = NULL; /* not needed */
-       else
-               projInfo->pi_itemIsDone = (ExprDoneCond *)
-                       palloc(len * sizeof(ExprDoneCond));
-
        return projInfo;
 }
 
index dc64b3262a9d7c9c689d3d0c97d6e8368f8cec51..e4992134bd0a1dfec4032a1c3e69a8b6f315b4e6 100644 (file)
@@ -854,7 +854,7 @@ advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup)
 
        /* compute input for all aggregates */
        if (aggstate->evalproj)
-               aggstate->evalslot = ExecProject(aggstate->evalproj, NULL);
+               aggstate->evalslot = ExecProject(aggstate->evalproj);
 
        for (transno = 0; transno < numTrans; transno++)
        {
@@ -871,7 +871,7 @@ advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup)
                        bool            isnull;
 
                        res = ExecEvalExprSwitchContext(filter, aggstate->tmpcontext,
-                                                                                       &isnull, NULL);
+                                                                                       &isnull);
                        if (isnull || !DatumGetBool(res))
                                continue;
                }
@@ -970,7 +970,7 @@ combine_aggregates(AggState *aggstate, AggStatePerGroup pergroup)
        Assert(aggstate->phase->numsets == 0);
 
        /* compute input for all aggregates */
-       slot = ExecProject(aggstate->evalproj, NULL);
+       slot = ExecProject(aggstate->evalproj);
 
        for (transno = 0; transno < numTrans; transno++)
        {
@@ -1368,8 +1368,7 @@ finalize_aggregate(AggState *aggstate,
 
                fcinfo.arg[i] = ExecEvalExpr(expr,
                                                                         aggstate->ss.ps.ps_ExprContext,
-                                                                        &fcinfo.argnull[i],
-                                                                        NULL);
+                                                                        &fcinfo.argnull[i]);
                anynull |= fcinfo.argnull[i];
                i++;
        }
@@ -1630,7 +1629,7 @@ finalize_aggregates(AggState *aggstate,
 /*
  * Project the result of a group (whose aggs have already been calculated by
  * finalize_aggregates). Returns the result slot, or NULL if no row is
- * projected (suppressed by qual or by an empty SRF).
+ * projected (suppressed by qual).
  */
 static TupleTableSlot *
 project_aggregates(AggState *aggstate)
@@ -1643,20 +1642,10 @@ project_aggregates(AggState *aggstate)
        if (ExecQual(aggstate->ss.ps.qual, econtext, false))
        {
                /*
-                * Form and return or store a projection tuple using the aggregate
-                * results and the representative input tuple.
+                * Form and return projection tuple using the aggregate results and
+                * the representative input tuple.
                 */
-               ExprDoneCond isDone;
-               TupleTableSlot *result;
-
-               result = ExecProject(aggstate->ss.ps.ps_ProjInfo, &isDone);
-
-               if (isDone != ExprEndResult)
-               {
-                       aggstate->ss.ps.ps_TupFromTlist =
-                               (isDone == ExprMultipleResult);
-                       return result;
-               }
+               return ExecProject(aggstate->ss.ps.ps_ProjInfo);
        }
        else
                InstrCountFiltered1(aggstate, 1);
@@ -1911,27 +1900,6 @@ ExecAgg(AggState *node)
 {
        TupleTableSlot *result;
 
-       /*
-        * Check to see if we're still projecting out tuples from a previous agg
-        * tuple (because there is a function-returning-set in the projection
-        * expressions).  If so, try to project another one.
-        */
-       if (node->ss.ps.ps_TupFromTlist)
-       {
-               ExprDoneCond isDone;
-
-               result = ExecProject(node->ss.ps.ps_ProjInfo, &isDone);
-               if (isDone == ExprMultipleResult)
-                       return result;
-               /* Done with that source tuple... */
-               node->ss.ps.ps_TupFromTlist = false;
-       }
-
-       /*
-        * (We must do the ps_TupFromTlist check first, because in some cases
-        * agg_done gets set before we emit the final aggregate tuple, and we have
-        * to finish running SRFs for it.)
-        */
        if (!node->agg_done)
        {
                /* Dispatch based on strategy */
@@ -2571,8 +2539,6 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
        ExecAssignResultTypeFromTL(&aggstate->ss.ps);
        ExecAssignProjectionInfo(&aggstate->ss.ps, NULL);
 
-       aggstate->ss.ps.ps_TupFromTlist = false;
-
        /*
         * get the count of aggregates in targetlist and quals
         */
@@ -3575,8 +3541,6 @@ ExecReScanAgg(AggState *node)
 
        node->agg_done = false;
 
-       node->ss.ps.ps_TupFromTlist = false;
-
        if (aggnode->aggstrategy == AGG_HASHED)
        {
                /*
index d5fd57ae4bafdcc65f9357d914954ce4b7c5fb4a..f18827de0bd4fba0db3800c321fbdff2add29517 100644 (file)
@@ -575,8 +575,6 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags)
         */
        ExecAssignExprContext(estate, &scanstate->ss.ps);
 
-       scanstate->ss.ps.ps_TupFromTlist = false;
-
        /*
         * initialize child expressions
         */
index 2f9c007409b99a763b2ae6e6c70de72ceea143a7..610797b36b63a1144e0814f92d6d19e9fec9f960 100644 (file)
@@ -269,8 +269,6 @@ ExecInitCteScan(CteScan *node, EState *estate, int eflags)
        ExecAssignResultTypeFromTL(&scanstate->ss.ps);
        ExecAssignScanProjectionInfo(&scanstate->ss);
 
-       scanstate->ss.ps.ps_TupFromTlist = false;
-
        return scanstate;
 }
 
index b01e65f3626eb9007320f00062f46a0b2bfa0743..a27430242a5621763ce1a75c41fddb57aab41a57 100644 (file)
@@ -48,8 +48,6 @@ ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags)
        /* create expression context for node */
        ExecAssignExprContext(estate, &css->ss.ps);
 
-       css->ss.ps.ps_TupFromTlist = false;
-
        /* initialize child expressions */
        css->ss.ps.targetlist = (List *)
                ExecInitExpr((Expr *) cscan->scan.plan.targetlist,
index 8f21c17f240348cc15e19153fa75a8e5d5a41c2f..86a77e356c02a250048f6d748fbf20c60ee1c33b 100644 (file)
@@ -152,8 +152,6 @@ ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags)
         */
        ExecAssignExprContext(estate, &scanstate->ss.ps);
 
-       scanstate->ss.ps.ps_TupFromTlist = false;
-
        /*
         * initialize child expressions
         */
index 1b593dcd71f768a924ed8f854019682941f0a40b..972022784d531ded41ab58d4338d5e49b7e82a16 100644 (file)
@@ -331,8 +331,6 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags)
         */
        ExecAssignExprContext(estate, &scanstate->ss.ps);
 
-       scanstate->ss.ps.ps_TupFromTlist = false;
-
        /*
         * tuple table initialization
         */
index f95c3d1b19ced4585e1208f06c5d3049df085165..45aa1132d92271e9a65c9beeacfe7e2196af2d13 100644 (file)
@@ -100,8 +100,6 @@ ExecInitGather(Gather *node, EState *estate, int eflags)
        outerNode = outerPlan(node);
        outerPlanState(gatherstate) = ExecInitNode(outerNode, estate, eflags);
 
-       gatherstate->ps.ps_TupFromTlist = false;
-
        /*
         * Initialize result tuple type and projection info.
         */
@@ -132,8 +130,6 @@ ExecGather(GatherState *node)
        TupleTableSlot *fslot = node->funnel_slot;
        int                     i;
        TupleTableSlot *slot;
-       TupleTableSlot *resultSlot;
-       ExprDoneCond isDone;
        ExprContext *econtext;
 
        /*
@@ -199,26 +195,11 @@ ExecGather(GatherState *node)
                node->initialized = true;
        }
 
-       /*
-        * Check to see if we're still projecting out tuples from a previous scan
-        * tuple (because there is a function-returning-set in the projection
-        * expressions).  If so, try to project another one.
-        */
-       if (node->ps.ps_TupFromTlist)
-       {
-               resultSlot = ExecProject(node->ps.ps_ProjInfo, &isDone);
-               if (isDone == ExprMultipleResult)
-                       return resultSlot;
-               /* Done with that source tuple... */
-               node->ps.ps_TupFromTlist = false;
-       }
-
        /*
         * Reset per-tuple memory context to free any expression evaluation
-        * storage allocated in the previous tuple cycle.  Note we can't do this
-        * until we're done projecting.  This will also clear any previous tuple
-        * returned by a TupleQueueReader; to make sure we don't leave a dangling
-        * pointer around, clear the working slot first.
+        * storage allocated in the previous tuple cycle.  This will also clear
+        * any previous tuple returned by a TupleQueueReader; to make sure we
+        * don't leave a dangling pointer around, clear the working slot first.
         */
        ExecClearTuple(node->funnel_slot);
        econtext = node->ps.ps_ExprContext;
@@ -241,13 +222,8 @@ ExecGather(GatherState *node)
                 * back around for another tuple
                 */
                econtext->ecxt_outertuple = slot;
-               resultSlot = ExecProject(node->ps.ps_ProjInfo, &isDone);
 
-               if (isDone != ExprEndResult)
-               {
-                       node->ps.ps_TupFromTlist = (isDone == ExprMultipleResult);
-                       return resultSlot;
-               }
+               return ExecProject(node->ps.ps_ProjInfo);
        }
 
        return slot;
index 6a05023e50fca5e9cd5c53939eed3e7d2c3b71bb..66c095bc72305ed0ff8df76bb63b5d223c5117ae 100644 (file)
@@ -49,23 +49,6 @@ ExecGroup(GroupState *node)
        numCols = ((Group *) node->ss.ps.plan)->numCols;
        grpColIdx = ((Group *) node->ss.ps.plan)->grpColIdx;
 
-       /*
-        * Check to see if we're still projecting out tuples from a previous group
-        * tuple (because there is a function-returning-set in the projection
-        * expressions).  If so, try to project another one.
-        */
-       if (node->ss.ps.ps_TupFromTlist)
-       {
-               TupleTableSlot *result;
-               ExprDoneCond isDone;
-
-               result = ExecProject(node->ss.ps.ps_ProjInfo, &isDone);
-               if (isDone == ExprMultipleResult)
-                       return result;
-               /* Done with that source tuple... */
-               node->ss.ps.ps_TupFromTlist = false;
-       }
-
        /*
         * The ScanTupleSlot holds the (copied) first tuple of each group.
         */
@@ -107,16 +90,7 @@ ExecGroup(GroupState *node)
                        /*
                         * Form and return a projection tuple using the first input tuple.
                         */
-                       TupleTableSlot *result;
-                       ExprDoneCond isDone;
-
-                       result = ExecProject(node->ss.ps.ps_ProjInfo, &isDone);
-
-                       if (isDone != ExprEndResult)
-                       {
-                               node->ss.ps.ps_TupFromTlist = (isDone == ExprMultipleResult);
-                               return result;
-                       }
+                       return ExecProject(node->ss.ps.ps_ProjInfo);
                }
                else
                        InstrCountFiltered1(node, 1);
@@ -170,16 +144,7 @@ ExecGroup(GroupState *node)
                        /*
                         * Form and return a projection tuple using the first input tuple.
                         */
-                       TupleTableSlot *result;
-                       ExprDoneCond isDone;
-
-                       result = ExecProject(node->ss.ps.ps_ProjInfo, &isDone);
-
-                       if (isDone != ExprEndResult)
-                       {
-                               node->ss.ps.ps_TupFromTlist = (isDone == ExprMultipleResult);
-                               return result;
-                       }
+                       return ExecProject(node->ss.ps.ps_ProjInfo);
                }
                else
                        InstrCountFiltered1(node, 1);
@@ -246,8 +211,6 @@ ExecInitGroup(Group *node, EState *estate, int eflags)
        ExecAssignResultTypeFromTL(&grpstate->ss.ps);
        ExecAssignProjectionInfo(&grpstate->ss.ps, NULL);
 
-       grpstate->ss.ps.ps_TupFromTlist = false;
-
        /*
         * Precompute fmgr lookup data for inner loop
         */
@@ -283,7 +246,6 @@ ExecReScanGroup(GroupState *node)
        PlanState  *outerPlan = outerPlanState(node);
 
        node->grp_done = FALSE;
-       node->ss.ps.ps_TupFromTlist = false;
        /* must clear first tuple */
        ExecClearTuple(node->ss.ss_ScanTupleSlot);
 
index 11db08f5fa66c73aab9e53b348c9887748597e3e..af5934d2bcfcf804d2840425df927d7946b4760f 100644 (file)
@@ -959,7 +959,7 @@ ExecHashGetHashValue(HashJoinTable hashtable,
                /*
                 * Get the join attribute value of the tuple
                 */
-               keyval = ExecEvalExpr(keyexpr, econtext, &isNull, NULL);
+               keyval = ExecEvalExpr(keyexpr, econtext, &isNull);
 
                /*
                 * If the attribute is NULL, and the join operator is strict, then
index b41e4e2f98a04515be52b3a5938f7c7edcca19cd..6e576ad0b38c2b21fa82e6521d072475d2b04c7f 100644 (file)
@@ -66,7 +66,6 @@ ExecHashJoin(HashJoinState *node)
        List       *joinqual;
        List       *otherqual;
        ExprContext *econtext;
-       ExprDoneCond isDone;
        HashJoinTable hashtable;
        TupleTableSlot *outerTupleSlot;
        uint32          hashvalue;
@@ -82,26 +81,9 @@ ExecHashJoin(HashJoinState *node)
        hashtable = node->hj_HashTable;
        econtext = node->js.ps.ps_ExprContext;
 
-       /*
-        * Check to see if we're still projecting out tuples from a previous join
-        * tuple (because there is a function-returning-set in the projection
-        * expressions).  If so, try to project another one.
-        */
-       if (node->js.ps.ps_TupFromTlist)
-       {
-               TupleTableSlot *result;
-
-               result = ExecProject(node->js.ps.ps_ProjInfo, &isDone);
-               if (isDone == ExprMultipleResult)
-                       return result;
-               /* Done with that source tuple... */
-               node->js.ps.ps_TupFromTlist = false;
-       }
-
        /*
         * Reset per-tuple memory context to free any expression evaluation
-        * storage allocated in the previous tuple cycle.  Note this can't happen
-        * until we're done projecting out tuples from a join tuple.
+        * storage allocated in the previous tuple cycle.
         */
        ResetExprContext(econtext);
 
@@ -314,18 +296,7 @@ ExecHashJoin(HashJoinState *node)
 
                                        if (otherqual == NIL ||
                                                ExecQual(otherqual, econtext, false))
-                                       {
-                                               TupleTableSlot *result;
-
-                                               result = ExecProject(node->js.ps.ps_ProjInfo, &isDone);
-
-                                               if (isDone != ExprEndResult)
-                                               {
-                                                       node->js.ps.ps_TupFromTlist =
-                                                               (isDone == ExprMultipleResult);
-                                                       return result;
-                                               }
-                                       }
+                                               return ExecProject(node->js.ps.ps_ProjInfo);
                                        else
                                                InstrCountFiltered2(node, 1);
                                }
@@ -353,18 +324,7 @@ ExecHashJoin(HashJoinState *node)
 
                                        if (otherqual == NIL ||
                                                ExecQual(otherqual, econtext, false))
-                                       {
-                                               TupleTableSlot *result;
-
-                                               result = ExecProject(node->js.ps.ps_ProjInfo, &isDone);
-
-                                               if (isDone != ExprEndResult)
-                                               {
-                                                       node->js.ps.ps_TupFromTlist =
-                                                               (isDone == ExprMultipleResult);
-                                                       return result;
-                                               }
-                                       }
+                                               return ExecProject(node->js.ps.ps_ProjInfo);
                                        else
                                                InstrCountFiltered2(node, 1);
                                }
@@ -392,18 +352,7 @@ ExecHashJoin(HashJoinState *node)
 
                                if (otherqual == NIL ||
                                        ExecQual(otherqual, econtext, false))
-                               {
-                                       TupleTableSlot *result;
-
-                                       result = ExecProject(node->js.ps.ps_ProjInfo, &isDone);
-
-                                       if (isDone != ExprEndResult)
-                                       {
-                                               node->js.ps.ps_TupFromTlist =
-                                                       (isDone == ExprMultipleResult);
-                                               return result;
-                                       }
-                               }
+                                       return ExecProject(node->js.ps.ps_ProjInfo);
                                else
                                        InstrCountFiltered2(node, 1);
                                break;
@@ -586,7 +535,6 @@ ExecInitHashJoin(HashJoin *node, EState *estate, int eflags)
        /* child Hash node needs to evaluate inner hash keys, too */
        ((HashState *) innerPlanState(hjstate))->hashkeys = rclauses;
 
-       hjstate->js.ps.ps_TupFromTlist = false;
        hjstate->hj_JoinState = HJ_BUILD_HASHTABLE;
        hjstate->hj_MatchedOuter = false;
        hjstate->hj_OuterNotEmpty = false;
@@ -1000,7 +948,6 @@ ExecReScanHashJoin(HashJoinState *node)
        node->hj_CurSkewBucketNo = INVALID_SKEW_BUCKET_NO;
        node->hj_CurTuple = NULL;
 
-       node->js.ps.ps_TupFromTlist = false;
        node->hj_MatchedOuter = false;
        node->hj_FirstOuterTupleSlot = NULL;
 
index ddef3a42bff3e22c1212400e30cec9f8ebda67d2..d5b19b7c11589c4352134baa4783a50e35fca456 100644 (file)
@@ -412,8 +412,6 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags)
         */
        ExecAssignExprContext(estate, &indexstate->ss.ps);
 
-       indexstate->ss.ps.ps_TupFromTlist = false;
-
        /*
         * initialize child expressions
         *
index 97a6fac34d9b9a8c333a324579e8a2a97c1bfbe3..5734550d2c78c7030d8a20a2bfc672794b36a86f 100644 (file)
@@ -336,8 +336,7 @@ EvalOrderByExpressions(IndexScanState *node, ExprContext *econtext)
 
                node->iss_OrderByValues[i] = ExecEvalExpr(orderby,
                                                                                                  econtext,
-                                                                                                 &node->iss_OrderByNulls[i],
-                                                                                                 NULL);
+                                                                                                 &node->iss_OrderByNulls[i]);
                i++;
        }
 
@@ -590,8 +589,7 @@ ExecIndexEvalRuntimeKeys(ExprContext *econtext,
                 */
                scanvalue = ExecEvalExpr(key_expr,
                                                                 econtext,
-                                                                &isNull,
-                                                                NULL);
+                                                                &isNull);
                if (isNull)
                {
                        scan_key->sk_argument = scanvalue;
@@ -648,8 +646,7 @@ ExecIndexEvalArrayKeys(ExprContext *econtext,
                 */
                arraydatum = ExecEvalExpr(array_expr,
                                                                  econtext,
-                                                                 &isNull,
-                                                                 NULL);
+                                                                 &isNull);
                if (isNull)
                {
                        result = false;
@@ -837,8 +834,6 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int eflags)
         */
        ExecAssignExprContext(estate, &indexstate->ss.ps);
 
-       indexstate->ss.ps.ps_TupFromTlist = false;
-
        /*
         * initialize child expressions
         *
index 885931e594798eb80fa5d2ddda2ab954e0cb0c16..aaec13221896c7d7357bc196deaa92378f47c56c 100644 (file)
@@ -239,8 +239,7 @@ recompute_limits(LimitState *node)
        {
                val = ExecEvalExprSwitchContext(node->limitOffset,
                                                                                econtext,
-                                                                               &isNull,
-                                                                               NULL);
+                                                                               &isNull);
                /* Interpret NULL offset as no offset */
                if (isNull)
                        node->offset = 0;
@@ -263,8 +262,7 @@ recompute_limits(LimitState *node)
        {
                val = ExecEvalExprSwitchContext(node->limitCount,
                                                                                econtext,
-                                                                               &isNull,
-                                                                               NULL);
+                                                                               &isNull);
                /* Interpret NULL count as no count (LIMIT ALL) */
                if (isNull)
                {
@@ -346,18 +344,11 @@ pass_down_bound(LimitState *node, PlanState *child_node)
        else if (IsA(child_node, ResultState))
        {
                /*
-                * An extra consideration here is that if the Result is projecting a
-                * targetlist that contains any SRFs, we can't assume that every input
-                * tuple generates an output tuple, so a Sort underneath might need to
-                * return more than N tuples to satisfy LIMIT N. So we cannot use
-                * bounded sort.
-                *
                 * If Result supported qual checking, we'd have to punt on seeing a
-                * qual, too.  Note that having a resconstantqual is not a
-                * showstopper: if that fails we're not getting any rows at all.
+                * qual.  Note that having a resconstantqual is not a showstopper: if
+                * that fails we're not getting any rows at all.
                 */
-               if (outerPlanState(child_node) &&
-                       !expression_returns_set((Node *) child_node->plan->targetlist))
+               if (outerPlanState(child_node))
                        pass_down_bound(node, outerPlanState(child_node));
        }
 }
index 2fd1856603740fce361926a9600eddca50f5406f..105e2dcedbe9e793d85d3080017a39b666ab2ef9 100644 (file)
@@ -313,7 +313,7 @@ MJEvalOuterValues(MergeJoinState *mergestate)
                MergeJoinClause clause = &mergestate->mj_Clauses[i];
 
                clause->ldatum = ExecEvalExpr(clause->lexpr, econtext,
-                                                                         &clause->lisnull, NULL);
+                                                                         &clause->lisnull);
                if (clause->lisnull)
                {
                        /* match is impossible; can we end the join early? */
@@ -360,7 +360,7 @@ MJEvalInnerValues(MergeJoinState *mergestate, TupleTableSlot *innerslot)
                MergeJoinClause clause = &mergestate->mj_Clauses[i];
 
                clause->rdatum = ExecEvalExpr(clause->rexpr, econtext,
-                                                                         &clause->risnull, NULL);
+                                                                         &clause->risnull);
                if (clause->risnull)
                {
                        /* match is impossible; can we end the join early? */
@@ -465,19 +465,9 @@ MJFillOuter(MergeJoinState *node)
                 * qualification succeeded.  now form the desired projection tuple and
                 * return the slot containing it.
                 */
-               TupleTableSlot *result;
-               ExprDoneCond isDone;
-
                MJ_printf("ExecMergeJoin: returning outer fill tuple\n");
 
-               result = ExecProject(node->js.ps.ps_ProjInfo, &isDone);
-
-               if (isDone != ExprEndResult)
-               {
-                       node->js.ps.ps_TupFromTlist =
-                               (isDone == ExprMultipleResult);
-                       return result;
-               }
+               return ExecProject(node->js.ps.ps_ProjInfo);
        }
        else
                InstrCountFiltered2(node, 1);
@@ -506,19 +496,9 @@ MJFillInner(MergeJoinState *node)
                 * qualification succeeded.  now form the desired projection tuple and
                 * return the slot containing it.
                 */
-               TupleTableSlot *result;
-               ExprDoneCond isDone;
-
                MJ_printf("ExecMergeJoin: returning inner fill tuple\n");
 
-               result = ExecProject(node->js.ps.ps_ProjInfo, &isDone);
-
-               if (isDone != ExprEndResult)
-               {
-                       node->js.ps.ps_TupFromTlist =
-                               (isDone == ExprMultipleResult);
-                       return result;
-               }
+               return ExecProject(node->js.ps.ps_ProjInfo);
        }
        else
                InstrCountFiltered2(node, 1);
@@ -641,27 +621,9 @@ ExecMergeJoin(MergeJoinState *node)
        doFillOuter = node->mj_FillOuter;
        doFillInner = node->mj_FillInner;
 
-       /*
-        * Check to see if we're still projecting out tuples from a previous join
-        * tuple (because there is a function-returning-set in the projection
-        * expressions).  If so, try to project another one.
-        */
-       if (node->js.ps.ps_TupFromTlist)
-       {
-               TupleTableSlot *result;
-               ExprDoneCond isDone;
-
-               result = ExecProject(node->js.ps.ps_ProjInfo, &isDone);
-               if (isDone == ExprMultipleResult)
-                       return result;
-               /* Done with that source tuple... */
-               node->js.ps.ps_TupFromTlist = false;
-       }
-
        /*
         * Reset per-tuple memory context to free any expression evaluation
-        * storage allocated in the previous tuple cycle.  Note this can't happen
-        * until we're done projecting out tuples from a join tuple.
+        * storage allocated in the previous tuple cycle.
         */
        ResetExprContext(econtext);
 
@@ -856,20 +818,9 @@ ExecMergeJoin(MergeJoinState *node)
                                                 * qualification succeeded.  now form the desired
                                                 * projection tuple and return the slot containing it.
                                                 */
-                                               TupleTableSlot *result;
-                                               ExprDoneCond isDone;
-
                                                MJ_printf("ExecMergeJoin: returning tuple\n");
 
-                                               result = ExecProject(node->js.ps.ps_ProjInfo,
-                                                                                        &isDone);
-
-                                               if (isDone != ExprEndResult)
-                                               {
-                                                       node->js.ps.ps_TupFromTlist =
-                                                               (isDone == ExprMultipleResult);
-                                                       return result;
-                                               }
+                                               return ExecProject(node->js.ps.ps_ProjInfo);
                                        }
                                        else
                                                InstrCountFiltered2(node, 1);
@@ -1629,7 +1580,6 @@ ExecInitMergeJoin(MergeJoin *node, EState *estate, int eflags)
         * initialize join state
         */
        mergestate->mj_JoinState = EXEC_MJ_INITIALIZE_OUTER;
-       mergestate->js.ps.ps_TupFromTlist = false;
        mergestate->mj_MatchedOuter = false;
        mergestate->mj_MatchedInner = false;
        mergestate->mj_OuterTupleSlot = NULL;
@@ -1684,7 +1634,6 @@ ExecReScanMergeJoin(MergeJoinState *node)
        ExecClearTuple(node->mj_MarkedTupleSlot);
 
        node->mj_JoinState = EXEC_MJ_INITIALIZE_OUTER;
-       node->js.ps.ps_TupFromTlist = false;
        node->mj_MatchedOuter = false;
        node->mj_MatchedInner = false;
        node->mj_OuterTupleSlot = NULL;
index 982f15d490e1d8225243a4b4630711ff3dbc23db..2ac740731869d3ce5795719266081370cbda1deb 100644 (file)
@@ -175,7 +175,7 @@ ExecProcessReturning(ResultRelInfo *resultRelInfo,
        econtext->ecxt_outertuple = planSlot;
 
        /* Compute the RETURNING expressions */
-       return ExecProject(projectReturning, NULL);
+       return ExecProject(projectReturning);
 }
 
 /*
@@ -1300,7 +1300,7 @@ ExecOnConflictUpdate(ModifyTableState *mtstate,
        }
 
        /* Project the new tuple version */
-       ExecProject(resultRelInfo->ri_onConflictSetProj, NULL);
+       ExecProject(resultRelInfo->ri_onConflictSetProj);
 
        /*
         * Note that it is possible that the target tuple has been modified in
index e05842768a3b3bff0c92f417bb1e8a3b97f65a11..cac7ba1b9bfd8c3914f861efc07ff874f0c0a8b1 100644 (file)
@@ -81,27 +81,9 @@ ExecNestLoop(NestLoopState *node)
        innerPlan = innerPlanState(node);
        econtext = node->js.ps.ps_ExprContext;
 
-       /*
-        * Check to see if we're still projecting out tuples from a previous join
-        * tuple (because there is a function-returning-set in the projection
-        * expressions).  If so, try to project another one.
-        */
-       if (node->js.ps.ps_TupFromTlist)
-       {
-               TupleTableSlot *result;
-               ExprDoneCond isDone;
-
-               result = ExecProject(node->js.ps.ps_ProjInfo, &isDone);
-               if (isDone == ExprMultipleResult)
-                       return result;
-               /* Done with that source tuple... */
-               node->js.ps.ps_TupFromTlist = false;
-       }
-
        /*
         * Reset per-tuple memory context to free any expression evaluation
-        * storage allocated in the previous tuple cycle.  Note this can't happen
-        * until we're done projecting out tuples from a join tuple.
+        * storage allocated in the previous tuple cycle.
         */
        ResetExprContext(econtext);
 
@@ -201,19 +183,9 @@ ExecNestLoop(NestLoopState *node)
                                         * the slot containing the result tuple using
                                         * ExecProject().
                                         */
-                                       TupleTableSlot *result;
-                                       ExprDoneCond isDone;
-
                                        ENL1_printf("qualification succeeded, projecting tuple");
 
-                                       result = ExecProject(node->js.ps.ps_ProjInfo, &isDone);
-
-                                       if (isDone != ExprEndResult)
-                                       {
-                                               node->js.ps.ps_TupFromTlist =
-                                                       (isDone == ExprMultipleResult);
-                                               return result;
-                                       }
+                                       return ExecProject(node->js.ps.ps_ProjInfo);
                                }
                                else
                                        InstrCountFiltered2(node, 1);
@@ -259,19 +231,9 @@ ExecNestLoop(NestLoopState *node)
                                 * qualification was satisfied so we project and return the
                                 * slot containing the result tuple using ExecProject().
                                 */
-                               TupleTableSlot *result;
-                               ExprDoneCond isDone;
-
                                ENL1_printf("qualification succeeded, projecting tuple");
 
-                               result = ExecProject(node->js.ps.ps_ProjInfo, &isDone);
-
-                               if (isDone != ExprEndResult)
-                               {
-                                       node->js.ps.ps_TupFromTlist =
-                                               (isDone == ExprMultipleResult);
-                                       return result;
-                               }
+                               return ExecProject(node->js.ps.ps_ProjInfo);
                        }
                        else
                                InstrCountFiltered2(node, 1);
@@ -377,7 +339,6 @@ ExecInitNestLoop(NestLoop *node, EState *estate, int eflags)
        /*
         * finally, wipe the current outer tuple clean.
         */
-       nlstate->js.ps.ps_TupFromTlist = false;
        nlstate->nl_NeedNewOuter = true;
        nlstate->nl_MatchedOuter = false;
 
@@ -441,7 +402,6 @@ ExecReScanNestLoop(NestLoopState *node)
         * outer Vars are used as run-time keys...
         */
 
-       node->js.ps.ps_TupFromTlist = false;
        node->nl_NeedNewOuter = true;
        node->nl_MatchedOuter = false;
 }
index 391e97ea6fe668bb191feb8ed71ad2eb078a4bba..eae0f1dad93026975a98aa71a1355a36b0058cec 100644 (file)
@@ -169,7 +169,7 @@ ExecProjectSRF(ProjectSetState *node, bool continuing)
                else
                {
                        /* Non-SRF tlist expression, just evaluate normally. */
-                       *result = ExecEvalExpr(gstate->arg, econtext, isnull, NULL);
+                       *result = ExecEvalExpr(gstate->arg, econtext, isnull);
                        *isdone = ExprSingleResult;
                }
 
index 59dacd33ef2c4a9f9de50e5e002448fef04e0e43..b5b50b21e9af8db0e413c7d5aba20ffef60f3ff3 100644 (file)
@@ -67,10 +67,8 @@ TupleTableSlot *
 ExecResult(ResultState *node)
 {
        TupleTableSlot *outerTupleSlot;
-       TupleTableSlot *resultSlot;
        PlanState  *outerPlan;
        ExprContext *econtext;
-       ExprDoneCond isDone;
 
        econtext = node->ps.ps_ExprContext;
 
@@ -91,24 +89,9 @@ ExecResult(ResultState *node)
                }
        }
 
-       /*
-        * Check to see if we're still projecting out tuples from a previous scan
-        * tuple (because there is a function-returning-set in the projection
-        * expressions).  If so, try to project another one.
-        */
-       if (node->ps.ps_TupFromTlist)
-       {
-               resultSlot = ExecProject(node->ps.ps_ProjInfo, &isDone);
-               if (isDone == ExprMultipleResult)
-                       return resultSlot;
-               /* Done with that source tuple... */
-               node->ps.ps_TupFromTlist = false;
-       }
-
        /*
         * Reset per-tuple memory context to free any expression evaluation
-        * storage allocated in the previous tuple cycle.  Note this can't happen
-        * until we're done projecting out tuples from a scan tuple.
+        * storage allocated in the previous tuple cycle.
         */
        ResetExprContext(econtext);
 
@@ -147,18 +130,8 @@ ExecResult(ResultState *node)
                        node->rs_done = true;
                }
 
-               /*
-                * form the result tuple using ExecProject(), and return it --- unless
-                * the projection produces an empty set, in which case we must loop
-                * back to see if there are more outerPlan tuples.
-                */
-               resultSlot = ExecProject(node->ps.ps_ProjInfo, &isDone);
-
-               if (isDone != ExprEndResult)
-               {
-                       node->ps.ps_TupFromTlist = (isDone == ExprMultipleResult);
-                       return resultSlot;
-               }
+               /* form the result tuple using ExecProject(), and return it */
+               return ExecProject(node->ps.ps_ProjInfo);
        }
 
        return NULL;
@@ -228,8 +201,6 @@ ExecInitResult(Result *node, EState *estate, int eflags)
         */
        ExecAssignExprContext(estate, &resstate->ps);
 
-       resstate->ps.ps_TupFromTlist = false;
-
        /*
         * tuple table initialization
         */
@@ -295,7 +266,6 @@ void
 ExecReScanResult(ResultState *node)
 {
        node->rs_done = false;
-       node->ps.ps_TupFromTlist = false;
        node->rs_checkqual = (node->resconstantqual == NULL) ? false : true;
 
        /*
index 8db5469d5a453ac6a65faec114117c0d9b60409a..d38265e8104825e382d3fb66dade78edc312858d 100644 (file)
@@ -189,8 +189,6 @@ ExecInitSampleScan(SampleScan *node, EState *estate, int eflags)
         */
        InitScanRelation(scanstate, estate, eflags);
 
-       scanstate->ss.ps.ps_TupFromTlist = false;
-
        /*
         * Initialize result tuple type and projection info.
         */
@@ -300,8 +298,7 @@ tablesample_init(SampleScanState *scanstate)
 
                params[i] = ExecEvalExprSwitchContext(argstate,
                                                                                          econtext,
-                                                                                         &isnull,
-                                                                                         NULL);
+                                                                                         &isnull);
                if (isnull)
                        ereport(ERROR,
                                        (errcode(ERRCODE_INVALID_TABLESAMPLE_ARGUMENT),
@@ -313,8 +310,7 @@ tablesample_init(SampleScanState *scanstate)
        {
                datum = ExecEvalExprSwitchContext(scanstate->repeatable,
                                                                                  econtext,
-                                                                                 &isnull,
-                                                                                 NULL);
+                                                                                 &isnull);
                if (isnull)
                        ereport(ERROR,
                                        (errcode(ERRCODE_INVALID_TABLESAMPLE_REPEAT),
index 439a94694b6dac2f4e7b5a723c1f12f6196b5c78..e61895de0a80d3704b6ee89510b52a0d50d51d91 100644 (file)
@@ -206,8 +206,6 @@ ExecInitSeqScan(SeqScan *node, EState *estate, int eflags)
         */
        InitScanRelation(scanstate, estate, eflags);
 
-       scanstate->ss.ps.ps_TupFromTlist = false;
-
        /*
         * Initialize result tuple type and projection info.
         */
index 68edcd4567b89e87c8f9074b19eb4d18c0a737a7..f8a2cd446a2590ab1d53d6decf0b70e5d2be2409 100644 (file)
 
 static Datum ExecSubPlan(SubPlanState *node,
                        ExprContext *econtext,
-                       bool *isNull,
-                       ExprDoneCond *isDone);
+                       bool *isNull);
 static Datum ExecAlternativeSubPlan(AlternativeSubPlanState *node,
                                           ExprContext *econtext,
-                                          bool *isNull,
-                                          ExprDoneCond *isDone);
+                                          bool *isNull);
 static Datum ExecHashSubPlan(SubPlanState *node,
                                ExprContext *econtext,
                                bool *isNull);
@@ -69,15 +67,12 @@ static bool slotNoNulls(TupleTableSlot *slot);
 static Datum
 ExecSubPlan(SubPlanState *node,
                        ExprContext *econtext,
-                       bool *isNull,
-                       ExprDoneCond *isDone)
+                       bool *isNull)
 {
        SubPlan    *subplan = (SubPlan *) node->xprstate.expr;
 
-       /* Set default values for result flags: non-null, not a set result */
+       /* Set non-null as default */
        *isNull = false;
-       if (isDone)
-               *isDone = ExprSingleResult;
 
        /* Sanity checks */
        if (subplan->subLinkType == CTE_SUBLINK)
@@ -128,7 +123,7 @@ ExecHashSubPlan(SubPlanState *node,
         * have to set the econtext to use (hack alert!).
         */
        node->projLeft->pi_exprContext = econtext;
-       slot = ExecProject(node->projLeft, NULL);
+       slot = ExecProject(node->projLeft);
 
        /*
         * Note: because we are typically called in a per-tuple context, we have
@@ -285,8 +280,7 @@ ExecScanSubPlan(SubPlanState *node,
 
                prm->value = ExecEvalExprSwitchContext((ExprState *) lfirst(pvar),
                                                                                           econtext,
-                                                                                          &(prm->isnull),
-                                                                                          NULL);
+                                                                                          &(prm->isnull));
                planstate->chgParam = bms_add_member(planstate->chgParam, paramid);
        }
 
@@ -403,7 +397,7 @@ ExecScanSubPlan(SubPlanState *node,
                }
 
                rowresult = ExecEvalExprSwitchContext(node->testexpr, econtext,
-                                                                                         &rownull, NULL);
+                                                                                         &rownull);
 
                if (subLinkType == ANY_SUBLINK)
                {
@@ -572,7 +566,7 @@ buildSubPlanHash(SubPlanState *node, ExprContext *econtext)
                                                                                  &(prmdata->isnull));
                        col++;
                }
-               slot = ExecProject(node->projRight, NULL);
+               slot = ExecProject(node->projRight);
 
                /*
                 * If result contains any nulls, store separately or not at all.
@@ -985,8 +979,7 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
 
                prm->value = ExecEvalExprSwitchContext((ExprState *) lfirst(pvar),
                                                                                           econtext,
-                                                                                          &(prm->isnull),
-                                                                                          NULL);
+                                                                                          &(prm->isnull));
                planstate->chgParam = bms_add_member(planstate->chgParam, paramid);
        }
 
@@ -1222,8 +1215,7 @@ ExecInitAlternativeSubPlan(AlternativeSubPlan *asplan, PlanState *parent)
 static Datum
 ExecAlternativeSubPlan(AlternativeSubPlanState *node,
                                           ExprContext *econtext,
-                                          bool *isNull,
-                                          ExprDoneCond *isDone)
+                                          bool *isNull)
 {
        /* Just pass control to the active subplan */
        SubPlanState *activesp = (SubPlanState *) list_nth(node->subplans,
@@ -1231,8 +1223,5 @@ ExecAlternativeSubPlan(AlternativeSubPlanState *node,
 
        Assert(IsA(activesp, SubPlanState));
 
-       return ExecSubPlan(activesp,
-                                          econtext,
-                                          isNull,
-                                          isDone);
+       return ExecSubPlan(activesp, econtext, isNull);
 }
index a4387da80a21403168f84c2c4beaf4ec2103481c..230a96f9d2ed266cc5891b4ac13be7755ab09f1f 100644 (file)
@@ -138,8 +138,6 @@ ExecInitSubqueryScan(SubqueryScan *node, EState *estate, int eflags)
         */
        subquerystate->subplan = ExecInitNode(node->subplan, estate, eflags);
 
-       subquerystate->ss.ps.ps_TupFromTlist = false;
-
        /*
         * Initialize scan tuple type (needed by ExecAssignScanProjectionInfo)
         */
index e3d3fc3842bf1bed8b19940488da8cd67c64d250..13ed886577a6327665901478146c3034aea80168 100644 (file)
@@ -104,8 +104,7 @@ TidListCreate(TidScanState *tidstate)
                        itemptr = (ItemPointer)
                                DatumGetPointer(ExecEvalExprSwitchContext(exstate,
                                                                                                                  econtext,
-                                                                                                                 &isNull,
-                                                                                                                 NULL));
+                                                                                                                 &isNull));
                        if (!isNull &&
                                ItemPointerIsValid(itemptr) &&
                                ItemPointerGetBlockNumber(itemptr) < nblocks)
@@ -133,8 +132,7 @@ TidListCreate(TidScanState *tidstate)
                        exstate = (ExprState *) lsecond(saexstate->fxprstate.args);
                        arraydatum = ExecEvalExprSwitchContext(exstate,
                                                                                                   econtext,
-                                                                                                  &isNull,
-                                                                                                  NULL);
+                                                                                                  &isNull);
                        if (isNull)
                                continue;
                        itemarray = DatumGetArrayTypeP(arraydatum);
@@ -469,8 +467,6 @@ ExecInitTidScan(TidScan *node, EState *estate, int eflags)
         */
        ExecAssignExprContext(estate, &tidstate->ss.ps);
 
-       tidstate->ss.ps.ps_TupFromTlist = false;
-
        /*
         * initialize child expressions
         */
index 5b42ca93cff9b17b6afe8d2d0e3cd40ef7355b5d..9883a8b1301fd3c34a34affc6bab0e91697d0dbd 100644 (file)
@@ -140,8 +140,7 @@ ValuesNext(ValuesScanState *node)
 
                        values[resind] = ExecEvalExpr(estate,
                                                                                  econtext,
-                                                                                 &isnull[resind],
-                                                                                 NULL);
+                                                                                 &isnull[resind]);
 
                        /*
                         * We must force any R/W expanded datums to read-only state, in
@@ -272,8 +271,6 @@ ExecInitValuesScan(ValuesScan *node, EState *estate, int eflags)
                scanstate->exprlists[i++] = (List *) lfirst(vtl);
        }
 
-       scanstate->ss.ps.ps_TupFromTlist = false;
-
        /*
         * Initialize result tuple type and projection info.
         */
index 17884d2c44cba3f8e3ba34ddb12694acc9137c77..6ac6b83cddcb31ecd289d66a33e8937495c8050d 100644 (file)
@@ -256,7 +256,7 @@ advance_windowaggregate(WindowAggState *winstate,
        if (filter)
        {
                bool            isnull;
-               Datum           res = ExecEvalExpr(filter, econtext, &isnull, NULL);
+               Datum           res = ExecEvalExpr(filter, econtext, &isnull);
 
                if (isnull || !DatumGetBool(res))
                {
@@ -272,7 +272,7 @@ advance_windowaggregate(WindowAggState *winstate,
                ExprState  *argstate = (ExprState *) lfirst(arg);
 
                fcinfo->arg[i] = ExecEvalExpr(argstate, econtext,
-                                                                         &fcinfo->argnull[i], NULL);
+                                                                         &fcinfo->argnull[i]);
                i++;
        }
 
@@ -433,7 +433,7 @@ advance_windowaggregate_base(WindowAggState *winstate,
        if (filter)
        {
                bool            isnull;
-               Datum           res = ExecEvalExpr(filter, econtext, &isnull, NULL);
+               Datum           res = ExecEvalExpr(filter, econtext, &isnull);
 
                if (isnull || !DatumGetBool(res))
                {
@@ -449,7 +449,7 @@ advance_windowaggregate_base(WindowAggState *winstate,
                ExprState  *argstate = (ExprState *) lfirst(arg);
 
                fcinfo->arg[i] = ExecEvalExpr(argstate, econtext,
-                                                                         &fcinfo->argnull[i], NULL);
+                                                                         &fcinfo->argnull[i]);
                i++;
        }
 
@@ -1584,15 +1584,12 @@ update_frametailpos(WindowObject winobj, TupleTableSlot *slot)
  *     ExecWindowAgg receives tuples from its outer subplan and
  *     stores them into a tuplestore, then processes window functions.
  *     This node doesn't reduce nor qualify any row so the number of
- *     returned rows is exactly the same as its outer subplan's result
- *     (ignoring the case of SRFs in the targetlist, that is).
+ *     returned rows is exactly the same as its outer subplan's result.
  * -----------------
  */
 TupleTableSlot *
 ExecWindowAgg(WindowAggState *winstate)
 {
-       TupleTableSlot *result;
-       ExprDoneCond isDone;
        ExprContext *econtext;
        int                     i;
        int                     numfuncs;
@@ -1600,23 +1597,6 @@ ExecWindowAgg(WindowAggState *winstate)
        if (winstate->all_done)
                return NULL;
 
-       /*
-        * Check to see if we're still projecting out tuples from a previous
-        * output tuple (because there is a function-returning-set in the
-        * projection expressions).  If so, try to project another one.
-        */
-       if (winstate->ss.ps.ps_TupFromTlist)
-       {
-               TupleTableSlot *result;
-               ExprDoneCond isDone;
-
-               result = ExecProject(winstate->ss.ps.ps_ProjInfo, &isDone);
-               if (isDone == ExprMultipleResult)
-                       return result;
-               /* Done with that source tuple... */
-               winstate->ss.ps.ps_TupFromTlist = false;
-       }
-
        /*
         * Compute frame offset values, if any, during first call.
         */
@@ -1634,8 +1614,7 @@ ExecWindowAgg(WindowAggState *winstate)
                        Assert(winstate->startOffset != NULL);
                        value = ExecEvalExprSwitchContext(winstate->startOffset,
                                                                                          econtext,
-                                                                                         &isnull,
-                                                                                         NULL);
+                                                                                         &isnull);
                        if (isnull)
                                ereport(ERROR,
                                                (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
@@ -1660,8 +1639,7 @@ ExecWindowAgg(WindowAggState *winstate)
                        Assert(winstate->endOffset != NULL);
                        value = ExecEvalExprSwitchContext(winstate->endOffset,
                                                                                          econtext,
-                                                                                         &isnull,
-                                                                                         NULL);
+                                                                                         &isnull);
                        if (isnull)
                                ereport(ERROR,
                                                (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
@@ -1684,7 +1662,6 @@ ExecWindowAgg(WindowAggState *winstate)
                winstate->all_first = false;
        }
 
-restart:
        if (winstate->buffer == NULL)
        {
                /* Initialize for first partition and set current row = 0 */
@@ -1776,17 +1753,8 @@ restart:
         * evaluated with respect to that row.
         */
        econtext->ecxt_outertuple = winstate->ss.ss_ScanTupleSlot;
-       result = ExecProject(winstate->ss.ps.ps_ProjInfo, &isDone);
 
-       if (isDone == ExprEndResult)
-       {
-               /* SRF in tlist returned no rows, so advance to next input tuple */
-               goto restart;
-       }
-
-       winstate->ss.ps.ps_TupFromTlist =
-               (isDone == ExprMultipleResult);
-       return result;
+       return ExecProject(winstate->ss.ps.ps_ProjInfo);
 }
 
 /* -----------------
@@ -1896,8 +1864,6 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
        ExecAssignResultTypeFromTL(&winstate->ss.ps);
        ExecAssignProjectionInfo(&winstate->ss.ps, NULL);
 
-       winstate->ss.ps.ps_TupFromTlist = false;
-
        /* Set up data for comparing tuples */
        if (node->partNumCols > 0)
                winstate->partEqfunctions = execTuplesMatchPrepare(node->partNumCols,
@@ -2090,8 +2056,6 @@ ExecReScanWindowAgg(WindowAggState *node)
        ExprContext *econtext = node->ss.ps.ps_ExprContext;
 
        node->all_done = false;
-
-       node->ss.ps.ps_TupFromTlist = false;
        node->all_first = true;
 
        /* release tuplestore et al */
@@ -2712,7 +2676,7 @@ WinGetFuncArgInPartition(WindowObject winobj, int argno,
                }
                econtext->ecxt_outertuple = slot;
                return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
-                                                       econtext, isnull, NULL);
+                                                       econtext, isnull);
        }
 }
 
@@ -2811,7 +2775,7 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
                }
                econtext->ecxt_outertuple = slot;
                return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
-                                                       econtext, isnull, NULL);
+                                                       econtext, isnull);
        }
 }
 
@@ -2841,5 +2805,5 @@ WinGetFuncArgCurrent(WindowObject winobj, int argno, bool *isnull)
 
        econtext->ecxt_outertuple = winstate->ss.ss_ScanTupleSlot;
        return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
-                                               econtext, isnull, NULL);
+                                               econtext, isnull);
 }
index 73a1a8238aae9c193d7ff2396ac6d7d1f38fb461..bdba9e0bfcde501a2cd113f43c57c600decf72e8 100644 (file)
@@ -174,8 +174,6 @@ ExecInitWorkTableScan(WorkTableScan *node, EState *estate, int eflags)
         */
        ExecAssignResultTypeFromTL(&scanstate->ss.ps);
 
-       scanstate->ss.ps.ps_TupFromTlist = false;
-
        return scanstate;
 }
 
index 85ffa3afc7c732060107425cd30bb56c7136bdb2..d589dc2544b0fe1bfc5bd483a6a2c7eb5b3f1d2b 100644 (file)
@@ -4685,7 +4685,7 @@ evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod,
         */
        const_val = ExecEvalExprSwitchContext(exprstate,
                                                                                  GetPerTupleExprContext(estate),
-                                                                                 &const_is_null, NULL);
+                                                                                 &const_is_null);
 
        /* Get info needed about result datatype */
        get_typlenbyval(result_type, &resultTypLen, &resultTypByVal);
index fd009e135e41423cf8dfddee7ac7dc18eb72fccc..c4a04cfa9535546f8346238d564adbc5b05bdf36 100644 (file)
@@ -1596,7 +1596,7 @@ operator_predicate_proof(Expr *predicate, Node *clause, bool refute_it)
        /* And execute it. */
        test_result = ExecEvalExprSwitchContext(test_exprstate,
                                                                                        GetPerTupleExprContext(estate),
-                                                                                       &isNull, NULL);
+                                                                                       &isNull);
 
        /* Get back to outer memory context */
        MemoryContextSwitchTo(oldcontext);
index 14fa119f07ce011c3537b6bad7d4e5d931be96e5..c2ad440013668aa77189d248891e1abbf193dfcc 100644 (file)
@@ -179,7 +179,7 @@ domain_check_input(Datum value, bool isnull, DomainIOData *my_extra)
 
                                        conResult = ExecEvalExprSwitchContext(con->check_expr,
                                                                                                                  econtext,
-                                                                                                                 &conIsNull, NULL);
+                                                                                                                 &conIsNull);
 
                                        if (!conIsNull &&
                                                !DatumGetBool(conResult))
index dcc5d6287ab4ed63b64f569e57ac2cb63a67e8a7..e8bce3b806d127b19c9b0be06da7d9764cdda900 100644 (file)
@@ -603,7 +603,7 @@ xmlelement(XmlExprState *xmlExpr, ExprContext *econtext)
                bool            isnull;
                char       *str;
 
-               value = ExecEvalExpr(e, econtext, &isnull, NULL);
+               value = ExecEvalExpr(e, econtext, &isnull);
                if (isnull)
                        str = NULL;
                else
@@ -620,7 +620,7 @@ xmlelement(XmlExprState *xmlExpr, ExprContext *econtext)
                bool            isnull;
                char       *str;
 
-               value = ExecEvalExpr(e, econtext, &isnull, NULL);
+               value = ExecEvalExpr(e, econtext, &isnull);
                /* here we can just forget NULL elements immediately */
                if (!isnull)
                {
index eb180fdb631bb72ebf064e88358b3575dd0a6917..74aa63536bdfb80d0338d0b9cf0c7b767a02d3f7 100644 (file)
@@ -70,8 +70,8 @@
  * now it's just a macro invoking the function pointed to by an ExprState
  * node.  Beware of double evaluation of the ExprState argument!
  */
-#define ExecEvalExpr(expr, econtext, isNull, isDone) \
-       ((*(expr)->evalfunc) (expr, econtext, isNull, isDone))
+#define ExecEvalExpr(expr, econtext, isNull) \
+       ((*(expr)->evalfunc) (expr, econtext, isNull))
 
 
 /* Hook for plugins to get control in ExecutorStart() */
@@ -257,14 +257,13 @@ extern Datum ExecMakeFunctionResultSet(FuncExprState *fcache,
                                                  bool *isNull,
                                                  ExprDoneCond *isDone);
 extern Datum ExecEvalExprSwitchContext(ExprState *expression, ExprContext *econtext,
-                                                 bool *isNull, ExprDoneCond *isDone);
+                                                 bool *isNull);
 extern ExprState *ExecInitExpr(Expr *node, PlanState *parent);
 extern ExprState *ExecPrepareExpr(Expr *node, EState *estate);
 extern bool ExecQual(List *qual, ExprContext *econtext, bool resultForNull);
 extern int     ExecTargetListLength(List *targetlist);
 extern int     ExecCleanTargetListLength(List *targetlist);
-extern TupleTableSlot *ExecProject(ProjectionInfo *projInfo,
-                       ExprDoneCond *isDone);
+extern TupleTableSlot *ExecProject(ProjectionInfo *projInfo);
 
 /*
  * prototypes from functions in execScan.c
index 1da1e1f80434ddb42d7ff539cb746a0a9b9a7cb0..f9bcdd63de0718a5419649fe7ea4f10e34d913cb 100644 (file)
@@ -156,7 +156,8 @@ typedef struct ExprContext
 } ExprContext;
 
 /*
- * Set-result status returned by ExecEvalExpr()
+ * Set-result status used when evaluating functions potentially returning a
+ * set.
  */
 typedef enum
 {
@@ -228,7 +229,6 @@ typedef struct ReturnSetInfo
  *             targetlist              target list for projection (non-Var expressions only)
  *             exprContext             expression context in which to evaluate targetlist
  *             slot                    slot to place projection result in
- *             itemIsDone              workspace array for ExecProject
  *             directMap               true if varOutputCols[] is an identity map
  *             numSimpleVars   number of simple Vars found in original tlist
  *             varSlotOffsets  array indicating which slot each simple Var is from
@@ -245,7 +245,6 @@ typedef struct ProjectionInfo
        List       *pi_targetlist;
        ExprContext *pi_exprContext;
        TupleTableSlot *pi_slot;
-       ExprDoneCond *pi_itemIsDone;
        bool            pi_directMap;
        int                     pi_numSimpleVars;
        int                *pi_varSlotOffsets;
@@ -586,8 +585,7 @@ typedef struct ExprState ExprState;
 
 typedef Datum (*ExprStateEvalFunc) (ExprState *expression,
                                                                                                ExprContext *econtext,
-                                                                                               bool *isNull,
-                                                                                               ExprDoneCond *isDone);
+                                                                                               bool *isNull);
 
 struct ExprState
 {
@@ -731,13 +729,6 @@ typedef struct FuncExprState
         */
        bool            setArgsValid;
 
-       /*
-        * Flag to remember whether we found a set-valued argument to the
-        * function. This causes the function result to be a set as well. Valid
-        * only when setArgsValid is true or funcResultStore isn't NULL.
-        */
-       bool            setHasSetArg;   /* some argument returns a set */
-
        /*
         * Flag to remember whether we have registered a shutdown callback for
         * this FuncExprState.  We do so only if funcResultStore or setArgsValid
@@ -1081,8 +1072,6 @@ typedef struct PlanState
        TupleTableSlot *ps_ResultTupleSlot; /* slot for my result tuples */
        ExprContext *ps_ExprContext;    /* node's expression-evaluation context */
        ProjectionInfo *ps_ProjInfo;    /* info for doing tuple projection */
-       bool            ps_TupFromTlist;/* state flag for processing set-valued
-                                                                * functions in targetlist */
 } PlanState;
 
 /* ----------------
index bc7b00199efb0832db288260a154179573cb23fe..b48146a362b1cbbd2b4422eae85bbb1728aae254 100644 (file)
@@ -5606,8 +5606,7 @@ exec_eval_simple_expr(PLpgSQL_execstate *estate,
         */
        *result = ExecEvalExpr(expr->expr_simple_state,
                                                   econtext,
-                                                  isNull,
-                                                  NULL);
+                                                  isNull);
 
        /* Assorted cleanup */
        expr->expr_simple_in_use = false;
@@ -6272,7 +6271,7 @@ exec_cast_value(PLpgSQL_execstate *estate,
                        cast_entry->cast_in_use = true;
 
                        value = ExecEvalExpr(cast_entry->cast_exprstate, econtext,
-                                                                isnull, NULL);
+                                                                isnull);
 
                        cast_entry->cast_in_use = false;