* plan normally and pass back the results.
*
*
- * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/nodeResult.c,v 1.37 2007/02/02 00:07:03 tgl Exp $
+ * src/backend/executor/nodeResult.c
*
*-------------------------------------------------------------------------
*/
ExecResult(ResultState *node)
{
TupleTableSlot *outerTupleSlot;
- TupleTableSlot *resultSlot;
PlanState *outerPlan;
ExprContext *econtext;
- ExprDoneCond isDone;
econtext = node->ps.ps_ExprContext;
*/
if (node->rs_checkqual)
{
- bool qualResult = ExecQual((List *) node->resconstantqual,
- econtext,
- false);
+ bool qualResult = ExecQual(node->resconstantqual, econtext);
node->rs_checkqual = false;
if (!qualResult)
}
}
- /*
- * 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);
if (TupIsNull(outerTupleSlot))
return NULL;
- node->ps.ps_OuterTupleSlot = outerTupleSlot;
-
/*
- * XXX gross hack. use outer tuple as scan tuple for projection
+ * prepare to compute projection expressions, which will expect to
+ * access the input tuples as varno OUTER.
*/
econtext->ecxt_outertuple = outerTupleSlot;
- econtext->ecxt_scantuple = outerTupleSlot;
}
else
{
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;
}
+/* ----------------------------------------------------------------
+ * ExecResultMarkPos
+ * ----------------------------------------------------------------
+ */
+void
+ExecResultMarkPos(ResultState *node)
+{
+ PlanState *outerPlan = outerPlanState(node);
+
+ if (outerPlan != NULL)
+ ExecMarkPos(outerPlan);
+ else
+ elog(DEBUG2, "Result nodes do not support mark/restore");
+}
+
+/* ----------------------------------------------------------------
+ * ExecResultRestrPos
+ * ----------------------------------------------------------------
+ */
+void
+ExecResultRestrPos(ResultState *node)
+{
+ PlanState *outerPlan = outerPlanState(node);
+
+ if (outerPlan != NULL)
+ ExecRestrPos(outerPlan);
+ else
+ elog(ERROR, "Result nodes do not support mark/restore");
+}
+
/* ----------------------------------------------------------------
* ExecInitResult
*
ResultState *resstate;
/* check for unsupported flags */
- Assert(!(eflags & EXEC_FLAG_MARK));
- Assert(!(eflags & EXEC_FLAG_BACKWARD) || outerPlan(node) != NULL);
+ Assert(!(eflags & (EXEC_FLAG_MARK | EXEC_FLAG_BACKWARD)) ||
+ outerPlan(node) != NULL);
/*
* create state structure
*/
ExecAssignExprContext(estate, &resstate->ps);
- resstate->ps.ps_TupFromTlist = false;
-
-#define RESULT_NSLOTS 1
-
/*
* tuple table initialization
*/
/*
* initialize child expressions
*/
- resstate->ps.targetlist = (List *)
- ExecInitExpr((Expr *) node->plan.targetlist,
- (PlanState *) resstate);
- resstate->ps.qual = (List *)
- ExecInitExpr((Expr *) node->plan.qual,
- (PlanState *) resstate);
- resstate->resconstantqual = ExecInitExpr((Expr *) node->resconstantqual,
- (PlanState *) resstate);
+ resstate->ps.qual =
+ ExecInitQual(node->plan.qual, (PlanState *) resstate);
+ resstate->resconstantqual =
+ ExecInitQual((List *) node->resconstantqual, (PlanState *) resstate);
/*
* initialize child nodes
return resstate;
}
-int
-ExecCountSlotsResult(Result *node)
-{
- return ExecCountSlotsNode(outerPlan(node)) + RESULT_NSLOTS;
-}
-
/* ----------------------------------------------------------------
* ExecEndResult
*
}
void
-ExecReScanResult(ResultState *node, ExprContext *exprCtxt)
+ExecReScanResult(ResultState *node)
{
node->rs_done = false;
- node->ps.ps_TupFromTlist = false;
node->rs_checkqual = (node->resconstantqual == NULL) ? false : true;
/*
- * if chgParam of subnode is not null then plan will be re-scanned by
+ * If chgParam of subnode is not null then plan will be re-scanned by
* first ExecProcNode.
*/
- if (((PlanState *) node)->lefttree &&
- ((PlanState *) node)->lefttree->chgParam == NULL)
- ExecReScan(((PlanState *) node)->lefttree, exprCtxt);
+ if (node->ps.lefttree &&
+ node->ps.lefttree->chgParam == NULL)
+ ExecReScan(node->ps.lefttree);
}