mirror of
https://github.com/postgres/postgres.git
synced 2025-07-02 09:02:37 +03:00
Apply my original fix for Taiki Yamaguchi's bug report about DISTINCT MAX().
Add some regression tests for plausible failures in this area.
This commit is contained in:
@ -10,7 +10,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/equivclass.c,v 1.9 2008/01/09 20:42:27 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/equivclass.c,v 1.10 2008/03/31 16:59:26 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -1638,6 +1638,44 @@ add_child_rel_equivalences(PlannerInfo *root,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* mutate_eclass_expressions
|
||||
* Apply an expression tree mutator to all expressions stored in
|
||||
* equivalence classes.
|
||||
*
|
||||
* This is a bit of a hack ... it's currently needed only by planagg.c,
|
||||
* which needs to do a global search-and-replace of MIN/MAX Aggrefs
|
||||
* after eclasses are already set up. Without changing the eclasses too,
|
||||
* subsequent matching of ORDER BY clauses would fail.
|
||||
*
|
||||
* Note that we assume the mutation won't affect relation membership or any
|
||||
* other properties we keep track of (which is a bit bogus, but by the time
|
||||
* planagg.c runs, it no longer matters). Also we must be called in the
|
||||
* main planner memory context.
|
||||
*/
|
||||
void
|
||||
mutate_eclass_expressions(PlannerInfo *root,
|
||||
Node *(*mutator) (),
|
||||
void *context)
|
||||
{
|
||||
ListCell *lc1;
|
||||
|
||||
foreach(lc1, root->eq_classes)
|
||||
{
|
||||
EquivalenceClass *cur_ec = (EquivalenceClass *) lfirst(lc1);
|
||||
ListCell *lc2;
|
||||
|
||||
foreach(lc2, cur_ec->ec_members)
|
||||
{
|
||||
EquivalenceMember *cur_em = (EquivalenceMember *) lfirst(lc2);
|
||||
|
||||
cur_em->em_expr = (Expr *)
|
||||
mutator((Node *) cur_em->em_expr, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* find_eclass_clauses_for_index_join
|
||||
* Create joinclauses usable for a nestloop-with-inner-indexscan
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planagg.c,v 1.36 2008/01/01 19:45:50 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planagg.c,v 1.37 2008/03/31 16:59:26 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -187,6 +187,18 @@ optimize_minmax_aggregates(PlannerInfo *root, List *tlist, Path *best_path)
|
||||
hqual = replace_aggs_with_params_mutator(parse->havingQual,
|
||||
&aggs_list);
|
||||
|
||||
/*
|
||||
* We have to replace Aggrefs with Params in equivalence classes too,
|
||||
* else ORDER BY or DISTINCT on an optimized aggregate will fail.
|
||||
*
|
||||
* Note: at some point it might become necessary to mutate other
|
||||
* data structures too, such as the query's sortClause or distinctClause.
|
||||
* Right now, those won't be examined after this point.
|
||||
*/
|
||||
mutate_eclass_expressions(root,
|
||||
replace_aggs_with_params_mutator,
|
||||
&aggs_list);
|
||||
|
||||
/*
|
||||
* Generate the output plan --- basically just a Result
|
||||
*/
|
||||
|
Reference in New Issue
Block a user