summaryrefslogtreecommitdiff
path: root/src/backend/optimizer
diff options
context:
space:
mode:
authorTom Lane2000-10-26 21:38:24 +0000
committerTom Lane2000-10-26 21:38:24 +0000
commit2f35b4efdbec6c161ca9bd491d6345134910c425 (patch)
tree2424351bcc12a8ddf2b716b28f53d2c37c79e507 /src/backend/optimizer
parentc9476bafdb1b97d0d21d92788f93298962145479 (diff)
Re-implement LIMIT/OFFSET as a plan node type, instead of a hack in
ExecutorRun. This allows LIMIT to work in a view. Also, LIMIT in a cursor declaration will behave in a reasonable fashion, whereas before it was overridden by the FETCH count.
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r--src/backend/optimizer/plan/createplan.c23
-rw-r--r--src/backend/optimizer/plan/planner.c28
-rw-r--r--src/backend/optimizer/plan/setrefs.c3
-rw-r--r--src/backend/optimizer/plan/subselect.c3
4 files changed, 45 insertions, 12 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index eb005121cd5..a865da61b92 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.98 2000/10/05 19:11:29 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.99 2000/10/26 21:36:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1651,6 +1651,27 @@ make_setop(SetOpCmd cmd, List *tlist, Plan *lefttree,
return node;
}
+Limit *
+make_limit(List *tlist, Plan *lefttree,
+ Node *limitOffset, Node *limitCount)
+{
+ Limit *node = makeNode(Limit);
+ Plan *plan = &node->plan;
+
+ copy_plan_costsize(plan, lefttree);
+
+ plan->state = (EState *) NULL;
+ plan->targetlist = tlist;
+ plan->qual = NIL;
+ plan->lefttree = lefttree;
+ plan->righttree = NULL;
+
+ node->limitOffset = limitOffset;
+ node->limitCount = limitCount;
+
+ return node;
+}
+
Result *
make_result(List *tlist,
Node *resconstantqual,
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index d73ca9a34ac..f9c70f7137d 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.92 2000/10/05 19:11:29 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.93 2000/10/26 21:36:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -341,8 +341,6 @@ is_simple_subquery(Query *subquery)
*/
if (subquery->rowMarks)
elog(ERROR, "FOR UPDATE is not supported in subselects");
- if (subquery->limitOffset || subquery->limitCount)
- elog(ERROR, "LIMIT is not supported in subselects");
/*
* Can't currently pull up a query with setops.
* Maybe after querytree redesign...
@@ -350,13 +348,16 @@ is_simple_subquery(Query *subquery)
if (subquery->setOperations)
return false;
/*
- * Can't pull up a subquery involving grouping, aggregation, or sorting.
+ * Can't pull up a subquery involving grouping, aggregation, sorting,
+ * or limiting.
*/
if (subquery->hasAggs ||
subquery->groupClause ||
subquery->havingQual ||
subquery->sortClause ||
- subquery->distinctClause)
+ subquery->distinctClause ||
+ subquery->limitOffset ||
+ subquery->limitCount)
return false;
/*
* Hack: don't try to pull up a subquery with an empty jointree.
@@ -831,7 +832,7 @@ union_planner(Query *parse,
}
else
{
- /* It's a PARAM ... punt ... */
+ /* It's an expression ... punt ... */
tuple_fraction = 0.10;
}
}
@@ -839,9 +840,8 @@ union_planner(Query *parse,
}
else
{
-
/*
- * COUNT is a PARAM ... don't know exactly what the
+ * COUNT is an expression ... don't know exactly what the
* limit will be, but for lack of a better idea assume
* 10% of the plan's result is wanted.
*/
@@ -1024,7 +1024,7 @@ union_planner(Query *parse,
}
/*
- * Finally, if there is a DISTINCT clause, add the UNIQUE node.
+ * If there is a DISTINCT clause, add the UNIQUE node.
*/
if (parse->distinctClause)
{
@@ -1032,6 +1032,16 @@ union_planner(Query *parse,
parse->distinctClause);
}
+ /*
+ * Finally, if there is a LIMIT/OFFSET clause, add the LIMIT node.
+ */
+ if (parse->limitOffset || parse->limitCount)
+ {
+ result_plan = (Plan *) make_limit(tlist, result_plan,
+ parse->limitOffset,
+ parse->limitCount);
+ }
+
return result_plan;
}
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index 14c9dad3ef3..deb020e2565 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.67 2000/10/05 19:11:29 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.68 2000/10/26 21:36:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -139,6 +139,7 @@ set_plan_references(Plan *plan)
case T_Sort:
case T_Unique:
case T_SetOp:
+ case T_Limit:
case T_Hash:
/*
diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c
index 03e38371df5..296164acb89 100644
--- a/src/backend/optimizer/plan/subselect.c
+++ b/src/backend/optimizer/plan/subselect.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.43 2000/10/05 19:11:29 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.44 2000/10/26 21:36:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -657,6 +657,7 @@ SS_finalize_plan(Plan *plan)
case T_Sort:
case T_Unique:
case T_SetOp:
+ case T_Limit:
case T_Group:
break;