1
0
mirror of https://github.com/MariaDB/server.git synced 2025-05-28 13:01:41 +03:00
Gleb Shchepa 994c0f8308 Bug #45640: optimizer bug produces wrong results
Grouping by a subquery in a query with a distinct aggregate
function lead to a wrong result (wrong and unordered
grouping values).

There are two related problems:

1) The query like this:

   SELECT (SELECT t1.a) aa, COUNT(DISTINCT b) c
   FROM t1 GROUP BY aa

returned wrong result, because the outer reference "t1.a"
in the subquery was substituted with the Item_ref item.

The Item_ref item obtains data from the result_field object
that refreshes once after the end of each group. This data
is not applicable to filesort since filesort() doesn't care
about groups (and doesn't update result_field objects with
copy_fields() and so on). Also that data is not applicable
to group separation algorithm: end_send_group() checks every
record with test_if_group_changed() that evaluates Item_ref
items, but it refreshes those Item_ref-s only after the end
of group, that is a vicious circle and the grouped column
values in the output are shifted.

Fix: if
       a) we grouping by a subquery and
       b) that subquery has outer references to FROM list
          of the grouping query,
     then we substitute these outer references with
     Item_direct_ref like references under aggregate
     functions: Item_direct_ref obtains data directly
     from the current record.

2) The query with a non-trivial grouping expression like:

   SELECT (SELECT t1.a) aa, COUNT(DISTINCT b) c
   FROM t1 GROUP BY aa+0

also returned wrong result, since JOIN::exec() substitutes
references to top-level aliases in SELECT list with Item_copy
caching items. Item_copy items have same refreshing policy
as Item_ref items, so the whole groping expression with
Item_copy inside returns wrong result in filesort() and
end_send_group().

Fix: include aliased items into GROUP BY item tree instead
     of Item_ref references to them.



mysql-test/r/group_by.result:
  Test case for bug #45640
mysql-test/t/group_by.test:
  Test case for bug #45640
sql/item.cc:
  Bug #45640: optimizer bug produces wrong results
  
  Item_field::fix_fields() has been modified to resolve
  aliases in GROUP BY item trees into aliased items instead
  of Item_ref items.
sql/item.h:
  Bug #45640: optimizer bug produces wrong results
  
  - Item::find_item_processor() has been introduced.
  - Item_ref::walk() has been modified to apply processors
    to itself too (not only to referenced item).
sql/mysql_priv.h:
  Bug #45640: optimizer bug produces wrong results
  
  fix_inner_refs() has been modified to accept group_list
  parameter.
sql/sql_lex.cc:
  Bug #45640: optimizer bug produces wrong results
  
  Initialization of st_select_lex::group_fix_field has
  been added.
sql/sql_lex.h:
  Bug #45640: optimizer bug produces wrong results
  
  The st_select_lex::group_fix_field field has been introduced
  to control alias resolution in Itef_fied::fix_fields.
sql/sql_select.cc:
  Bug #45640: optimizer bug produces wrong results
  
  - The fix_inner_refs function has been modified to treat
    subquery outer references like outer fields under aggregate
    functions, if they are included in GROUP BY item tree.
  
  - The find_order_in_list function has been modified to
    fix Item_field alias fields included in the GROUP BY item
    trees in a special manner.
2010-02-06 23:54:30 +04:00
..
2009-09-29 17:38:40 +02:00
2009-09-29 17:38:40 +02:00
2010-01-29 15:08:49 +04:00
2010-01-19 17:02:51 +01:00
2007-10-11 13:29:09 -04:00
2007-10-11 13:29:09 -04:00
2010-01-13 12:28:42 +02:00
2010-01-13 12:28:42 +02:00
2009-12-22 14:38:33 +04:00
2010-01-28 19:51:40 -02:00
2010-01-28 19:51:40 -02:00
2009-11-24 18:30:21 +03:00
2009-08-28 18:21:54 +02:00
2010-01-24 15:03:23 +08:00
2010-01-27 19:27:49 +02:00
2009-09-29 17:38:40 +02:00
2007-10-11 13:29:09 -04:00
2008-11-27 12:33:04 +01:00
2007-10-16 16:11:50 -04:00
2009-07-28 22:44:28 +04:00
2008-11-22 01:10:38 +01:00
2008-11-22 01:10:38 +01:00
2008-08-25 21:18:22 +04:00
2009-06-01 16:00:38 +04:00
2007-10-11 14:37:45 -04:00
2009-11-03 20:45:52 +03:00
2010-01-28 19:51:40 -02:00
2010-01-28 19:51:40 -02:00
2009-09-29 17:38:40 +02:00
2008-07-03 23:41:22 +04:00
2010-01-24 15:03:23 +08:00
2009-04-29 07:59:10 +05:00
2009-12-18 16:44:24 -02:00
2008-01-23 13:26:41 -07:00
2009-08-28 18:21:54 +02:00
2009-06-17 16:56:44 +02:00
2009-06-17 16:56:44 +02:00
2010-01-24 15:03:23 +08:00
2010-01-24 15:03:23 +08:00
2009-12-18 16:44:24 -02:00
2008-12-10 18:16:21 +04:00
2007-10-16 16:11:50 -04:00
2010-01-28 19:51:40 -02:00
2010-01-24 15:03:23 +08:00
2009-09-17 17:25:52 +02:00
2009-06-17 16:56:44 +02:00
2010-01-24 15:03:23 +08:00
2010-01-24 15:03:23 +08:00
2010-01-24 15:03:23 +08:00
2010-01-24 15:03:23 +08:00
2010-01-28 19:51:40 -02:00
2010-01-24 15:03:23 +08:00
2010-01-24 15:03:23 +08:00
2009-01-14 18:50:51 +04:00
2010-01-25 10:55:05 +08:00
2010-01-24 15:03:23 +08:00
2010-01-24 15:03:23 +08:00
2009-11-03 20:45:52 +03:00
2009-06-29 16:00:47 +02:00
2009-06-17 16:56:44 +02:00
2009-09-17 17:25:52 +02:00
2009-06-17 16:56:44 +02:00
2009-07-31 15:28:15 -04:00