summaryrefslogtreecommitdiff
path: root/src/backend/optimizer
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2010-02-12 17:33:21 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2010-02-12 17:33:21 +0000
commitec4be2ee6827b6bd85e0813c7a8993cfbb0e6fa7 (patch)
treef4f98eb0f5ff45dbcd23778a1c683a1f597431b7 /src/backend/optimizer
parenta5348fafd182d5b84c89b43af3746711ce28f319 (diff)
Extend the set of frame options supported for window functions.
This patch allows the frame to start from CURRENT ROW (in either RANGE or ROWS mode), and it also adds support for ROWS n PRECEDING and ROWS n FOLLOWING start and end points. (RANGE value PRECEDING/FOLLOWING isn't there yet --- the grammar works, but that's all.) Hitoshi Harada, reviewed by Pavel Stehule
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r--src/backend/optimizer/plan/createplan.c7
-rw-r--r--src/backend/optimizer/plan/planner.c20
-rw-r--r--src/backend/optimizer/plan/setrefs.c20
-rw-r--r--src/backend/optimizer/plan/subselect.c10
4 files changed, 49 insertions, 8 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 41e048359f3..112c2389d11 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.270 2010/01/02 16:57:47 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.271 2010/02/12 17:33:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -3364,7 +3364,8 @@ make_windowagg(PlannerInfo *root, List *tlist,
int numWindowFuncs, Index winref,
int partNumCols, AttrNumber *partColIdx, Oid *partOperators,
int ordNumCols, AttrNumber *ordColIdx, Oid *ordOperators,
- int frameOptions, Plan *lefttree)
+ int frameOptions, Node *startOffset, Node *endOffset,
+ Plan *lefttree)
{
WindowAgg *node = makeNode(WindowAgg);
Plan *plan = &node->plan;
@@ -3379,6 +3380,8 @@ make_windowagg(PlannerInfo *root, List *tlist,
node->ordColIdx = ordColIdx;
node->ordOperators = ordOperators;
node->frameOptions = frameOptions;
+ node->startOffset = startOffset;
+ node->endOffset = endOffset;
copy_plan_costsize(plan, lefttree); /* only care about copying size */
cost_windowagg(&windowagg_path, root,
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 3748c83fd65..77e9d65ae7e 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.264 2010/02/10 03:38:35 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.265 2010/02/12 17:33:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -398,7 +398,10 @@ subquery_planner(PlannerGlobal *glob, Query *parse,
root->hasPseudoConstantQuals = false;
/*
- * Do expression preprocessing on targetlist and quals.
+ * Do expression preprocessing on targetlist and quals, as well as other
+ * random expressions in the querytree. Note that we do not need to
+ * handle sort/group expressions explicitly, because they are actually
+ * part of the targetlist.
*/
parse->targetList = (List *)
preprocess_expression(root, (Node *) parse->targetList,
@@ -413,6 +416,17 @@ subquery_planner(PlannerGlobal *glob, Query *parse,
parse->havingQual = preprocess_expression(root, parse->havingQual,
EXPRKIND_QUAL);
+ foreach(l, parse->windowClause)
+ {
+ WindowClause *wc = (WindowClause *) lfirst(l);
+
+ /* partitionClause/orderClause are sort/group expressions */
+ wc->startOffset = preprocess_expression(root, wc->startOffset,
+ EXPRKIND_LIMIT);
+ wc->endOffset = preprocess_expression(root, wc->endOffset,
+ EXPRKIND_LIMIT);
+ }
+
parse->limitOffset = preprocess_expression(root, parse->limitOffset,
EXPRKIND_LIMIT);
parse->limitCount = preprocess_expression(root, parse->limitCount,
@@ -1513,6 +1527,8 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
ordColIdx,
ordOperators,
wc->frameOptions,
+ wc->startOffset,
+ wc->endOffset,
result_plan);
}
}
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index aa4fd4e1ebe..18e721a581c 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/plan/setrefs.c,v 1.157 2010/01/15 22:36:32 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/setrefs.c,v 1.158 2010/02/12 17:33:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -466,10 +466,26 @@ set_plan_refs(PlannerGlobal *glob, Plan *plan, int rtoffset)
}
break;
case T_Agg:
- case T_WindowAgg:
case T_Group:
set_upper_references(glob, plan, rtoffset);
break;
+ case T_WindowAgg:
+ {
+ WindowAgg *wplan = (WindowAgg *) plan;
+
+ set_upper_references(glob, plan, rtoffset);
+
+ /*
+ * Like Limit node limit/offset expressions, WindowAgg has
+ * frame offset expressions, which cannot contain subplan
+ * variable refs, so fix_scan_expr works for them.
+ */
+ wplan->startOffset =
+ fix_scan_expr(glob, wplan->startOffset, rtoffset);
+ wplan->endOffset =
+ fix_scan_expr(glob, wplan->endOffset, rtoffset);
+ }
+ break;
case T_Result:
{
Result *splan = (Result *) plan;
diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c
index 2e99cc6b4ba..d75981467b9 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
- * $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.158 2010/01/18 18:17:45 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.159 2010/02/12 17:33:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -2098,9 +2098,15 @@ finalize_plan(PlannerInfo *root, Plan *plan, Bitmapset *valid_params,
locally_added_param);
break;
+ case T_WindowAgg:
+ finalize_primnode(((WindowAgg *) plan)->startOffset,
+ &context);
+ finalize_primnode(((WindowAgg *) plan)->endOffset,
+ &context);
+ break;
+
case T_Hash:
case T_Agg:
- case T_WindowAgg:
case T_Material:
case T_Sort:
case T_Unique: