aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2007-02-06 06:50:33 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2007-02-06 06:50:33 +0000
commita95abdf8564e36b7c9de62423fcbe039fcc20efa (patch)
tree09750e90a9a1b1e8dd5d786e04ec81413de872e4
parent5338847fcd105554e4eee92c3f5477f41bdc2e68 (diff)
downloadpostgresql-a95abdf8564e36b7c9de62423fcbe039fcc20efa.tar.gz
postgresql-a95abdf8564e36b7c9de62423fcbe039fcc20efa.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 e64340ed21c..1b929caa655 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.22 2006/10/04 00:29:54 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/planagg.c,v 1.22.2.1 2007/02/06 06:50:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -69,6 +69,7 @@ Plan *
optimize_minmax_aggregates(PlannerInfo *root, List *tlist, Path *best_path)
{
Query *parse = root->parse;
+ FromExpr *jtnode;
RangeTblRef *rtr;
RangeTblEntry *rte;
RelOptInfo *rel;
@@ -101,14 +102,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;