aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor')
-rw-r--r--src/backend/executor/nodeLimit.c34
-rw-r--r--src/backend/executor/nodeSubplan.c9
2 files changed, 31 insertions, 12 deletions
diff --git a/src/backend/executor/nodeLimit.c b/src/backend/executor/nodeLimit.c
index 9d40952647d..76296cfd877 100644
--- a/src/backend/executor/nodeLimit.c
+++ b/src/backend/executor/nodeLimit.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/nodeLimit.c,v 1.30 2007/05/04 01:13:43 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/nodeLimit.c,v 1.31 2007/05/17 19:35:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -55,17 +55,22 @@ ExecLimit(LimitState *node)
case LIMIT_INITIAL:
/*
- * If backwards scan, just return NULL without changing state.
+ * First call for this node, so compute limit/offset. (We can't do
+ * this any earlier, because parameters from upper nodes will not
+ * be set during ExecInitLimit.) This also sets position = 0
+ * and changes the state to LIMIT_RESCAN.
*/
- if (!ScanDirectionIsForward(direction))
- return NULL;
+ recompute_limits(node);
+
+ /* FALL THRU */
+
+ case LIMIT_RESCAN:
/*
- * First call for this scan, so compute limit/offset. (We can't do
- * this any earlier, because parameters from upper nodes may not
- * be set until now.) This also sets position = 0.
+ * If backwards scan, just return NULL without changing state.
*/
- recompute_limits(node);
+ if (!ScanDirectionIsForward(direction))
+ return NULL;
/*
* Check for empty window; if so, treat like empty subplan.
@@ -217,7 +222,7 @@ ExecLimit(LimitState *node)
}
/*
- * Evaluate the limit/offset expressions --- done at start of each scan.
+ * Evaluate the limit/offset expressions --- done at startup or rescan.
*
* This is also a handy place to reset the current-position state info.
*/
@@ -281,6 +286,9 @@ recompute_limits(LimitState *node)
node->position = 0;
node->subSlot = NULL;
+ /* Set state-machine state */
+ node->lstate = LIMIT_RESCAN;
+
/*
* If we have a COUNT, and our input is a Sort node, notify it that it can
* use bounded sort.
@@ -403,8 +411,12 @@ ExecEndLimit(LimitState *node)
void
ExecReScanLimit(LimitState *node, ExprContext *exprCtxt)
{
- /* resetting lstate will force offset/limit recalculation */
- node->lstate = LIMIT_INITIAL;
+ /*
+ * Recompute limit/offset in case parameters changed, and reset the
+ * state machine. We must do this before rescanning our child node,
+ * in case it's a Sort that we are passing the parameters down to.
+ */
+ recompute_limits(node);
/*
* if chgParam of subnode is not null then plan will be re-scanned by
diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c
index a66f51c26a6..ac91ed1be64 100644
--- a/src/backend/executor/nodeSubplan.c
+++ b/src/backend/executor/nodeSubplan.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/nodeSubplan.c,v 1.88 2007/04/26 23:24:44 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/nodeSubplan.c,v 1.89 2007/05/17 19:35:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -242,6 +242,9 @@ ExecScanSubPlan(SubPlanState *node,
planstate->chgParam = bms_add_member(planstate->chgParam, paramid);
}
+ /*
+ * Now that we've set up its parameters, we can reset the subplan.
+ */
ExecReScan(planstate, NULL);
/*
@@ -901,6 +904,10 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
subLinkType == ALL_SUBLINK)
elog(ERROR, "ANY/ALL subselect unsupported as initplan");
+ /*
+ * By definition, an initplan has no parameters from our query level,
+ * but it could have some from an outer level. Rescan it if needed.
+ */
if (planstate->chgParam != NULL)
ExecReScan(planstate, NULL);