1
0
mirror of https://github.com/MariaDB/server.git synced 2026-01-06 05:22:24 +03:00

Bug #21456: SELECT DISTINCT(x) produces incorrect results when using order by

GROUP BY/DISTINCT pruning optimization must be done before ORDER BY 
optimization because ORDER BY may be removed when GROUP BY/DISTINCT
sorts as a side effect, e.g. in 
  SELECT DISTINCT <non-key-col>,<pk> FROM t1
  ORDER BY <non-key-col> DISTINCT
must be removed before ORDER BY as if done the other way around
it will remove both.
This commit is contained in:
timour/timka@lamia.home
2006-08-23 16:46:57 +03:00
parent 50ae5b7989
commit de723f2998
3 changed files with 52 additions and 30 deletions

View File

@@ -648,6 +648,36 @@ JOIN::optimize()
if (!order && org_order)
skip_sort_order= 1;
}
/*
Check if we can optimize away GROUP BY/DISTINCT.
We can do that if there are no aggregate functions and the
fields in DISTINCT clause (if present) and/or columns in GROUP BY
(if present) contain direct references to all key parts of
an unique index (in whatever order).
Note that the unique keys for DISTINCT and GROUP BY should not
be the same (as long as they are unique).
The FROM clause must contain a single non-constant table.
*/
if (tables - const_tables == 1 && (group_list || select_distinct) &&
!tmp_table_param.sum_func_count)
{
if (group_list &&
list_contains_unique_index(join_tab[const_tables].table,
find_field_in_order_list,
(void *) group_list))
{
group_list= 0;
group= 0;
}
if (select_distinct &&
list_contains_unique_index(join_tab[const_tables].table,
find_field_in_item_list,
(void *) &fields_list))
{
select_distinct= 0;
}
}
if (group_list || tmp_table_param.sum_func_count)
{
if (! hidden_group_fields && rollup.state == ROLLUP::STATE_NONE)
@@ -717,36 +747,6 @@ JOIN::optimize()
if (old_group_list && !group_list)
select_distinct= 0;
}
/*
Check if we can optimize away GROUP BY/DISTINCT.
We can do that if there are no aggregate functions and the
fields in DISTINCT clause (if present) and/or columns in GROUP BY
(if present) contain direct references to all key parts of
an unique index (in whatever order).
Note that the unique keys for DISTINCT and GROUP BY should not
be the same (as long as they are unique).
The FROM clause must contain a single non-constant table.
*/
if (tables - const_tables == 1 && (group_list || select_distinct) &&
!tmp_table_param.sum_func_count)
{
if (group_list &&
list_contains_unique_index(join_tab[const_tables].table,
find_field_in_order_list,
(void *) group_list))
{
group_list= 0;
group= 0;
}
if (select_distinct &&
list_contains_unique_index(join_tab[const_tables].table,
find_field_in_item_list,
(void *) &fields_list))
{
select_distinct= 0;
}
}
if (!group_list && group)
{
order=0; // The output has only one row