aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2007-02-06 06:50:26 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2007-02-06 06:50:26 +0000
commit56e59edd7509f8726157cd8039529fc077f57ebb (patch)
treeb7dc7fa4d6a3549b884e5f2ec1d110b299fba6e0
parent91e18dbbccd6ec00e6b1f879d98bbd9376a0689b (diff)
downloadpostgresql-56e59edd7509f8726157cd8039529fc077f57ebb.tar.gz
postgresql-56e59edd7509f8726157cd8039529fc077f57ebb.zip
Fix a performance regression in 8.2: optimization of MIN/MAX into indexscans
had stopped working for tables buried inside views or sub-selects. This is because I had gotten rid of the simplify_jointree() preprocessing step, and optimize_minmax_aggregates() wasn't smart enough to deal with a non-canonical FromExpr. Per gripe from Bill Howe.
-rw-r--r--src/backend/optimizer/plan/planagg.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/src/backend/optimizer/plan/planagg.c b/src/backend/optimizer/plan/planagg.c
index bce3b1ac442..77ad0176db2 100644
--- a/src/backend/optimizer/plan/planagg.c
+++ b/src/backend/optimizer/plan/planagg.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/plan/planagg.c,v 1.25 2007/01/09 02:14:13 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/planagg.c,v 1.26 2007/02/06 06:50:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -70,6 +70,7 @@ Plan *
optimize_minmax_aggregates(PlannerInfo *root, List *tlist, Path *best_path)
{
Query *parse = root->parse;
+ FromExpr *jtnode;
RangeTblRef *rtr;
RangeTblEntry *rte;
RelOptInfo *rel;
@@ -102,14 +103,19 @@ optimize_minmax_aggregates(PlannerInfo *root, List *tlist, Path *best_path)
* We also restrict the query to reference exactly one table, since join
* conditions can't be handled reasonably. (We could perhaps handle a
* query containing cartesian-product joins, but it hardly seems worth the
- * trouble.)
+ * trouble.) However, the single real table could be buried in several
+ * levels of FromExpr.
*/
- Assert(parse->jointree != NULL && IsA(parse->jointree, FromExpr));
- if (list_length(parse->jointree->fromlist) != 1)
- return NULL;
- rtr = (RangeTblRef *) linitial(parse->jointree->fromlist);
- if (!IsA(rtr, RangeTblRef))
+ jtnode = parse->jointree;
+ while (IsA(jtnode, FromExpr))
+ {
+ if (list_length(jtnode->fromlist) != 1)
+ return NULL;
+ jtnode = linitial(jtnode->fromlist);
+ }
+ if (!IsA(jtnode, RangeTblRef))
return NULL;
+ rtr = (RangeTblRef *) jtnode;
rte = rt_fetch(rtr->rtindex, parse->rtable);
if (rte->rtekind != RTE_RELATION || rte->inh)
return NULL;