aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeLimit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor/nodeLimit.c')
-rw-r--r--src/backend/executor/nodeLimit.c34
1 files changed, 23 insertions, 11 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