Skip to content
/ server Public
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions mysql-test/main/table_elim.result
Original file line number Diff line number Diff line change
Expand Up @@ -1086,5 +1086,20 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
DROP TABLE t1, t2;
#
# MDEV-28817: Derived table elimination fails when field aliases are used
#
create table t1 (a int, b int);
insert into t1 values (0,1),(1,2),(2,3),(3,4);
create table t2 (a int, b int, c int);
insert into t2 values (1,1,2),(2,3,4),(3,8,9);
# Field 'a' used both as straight 'a' and as an alias 'a2'.
# Derived table D should be eliminated anyway.
explain select t1.* from t1 left join
(select a, b, a as a2 from t2 group by a, b) D
on D.a2=t1.a and D.b=t1.b;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4
drop table t1, t2;
#
# End of 10.11 tests
#
17 changes: 17 additions & 0 deletions mysql-test/main/table_elim.test
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,23 @@ select t1.null_col from t1 left join t2 on (t2.unique_col<=>t1.notnull_col);

DROP TABLE t1, t2;

--echo #
--echo # MDEV-28817: Derived table elimination fails when field aliases are used
--echo #

create table t1 (a int, b int);
insert into t1 values (0,1),(1,2),(2,3),(3,4);
create table t2 (a int, b int, c int);
insert into t2 values (1,1,2),(2,3,4),(3,8,9);

--echo # Field 'a' used both as straight 'a' and as an alias 'a2'.
--echo # Derived table D should be eliminated anyway.
explain select t1.* from t1 left join
(select a, b, a as a2 from t2 group by a, b) D
on D.a2=t1.a and D.b=t1.b;

drop table t1, t2;

--echo #
--echo # End of 10.11 tests
--echo #
28 changes: 18 additions & 10 deletions sql/opt_table_elimination.cc
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,8 @@ class Dep_analysis_context
private:
void create_unique_pseudo_key_if_needed(TABLE_LIST *table_list,
Dep_value_table *tbl_dep);
int find_field_in_list(List<Item> &fields_list, Item *field);
bool find_field_in_list(List<Item> &fields_list, Item *field,
MY_BITMAP *bitmap);
};


Expand Down Expand Up @@ -1764,8 +1765,9 @@ void Dep_analysis_context::create_unique_pseudo_key_if_needed(
valid= false;
break;
}
auto field_no= find_field_in_list(first_select->join->fields_list, elem);
if (field_no == -1)
bool found= find_field_in_list(first_select->join->fields_list,
elem, exposed_fields);
if (!found)
{
/*
This GROUP BY element is not present in the select list. This is a
Expand All @@ -1778,7 +1780,6 @@ void Dep_analysis_context::create_unique_pseudo_key_if_needed(
valid= false;
break;
}
bitmap_set_bit(exposed_fields, field_no);
exposed_fields_count++;
}
if (valid)
Expand All @@ -1794,22 +1795,29 @@ void Dep_analysis_context::create_unique_pseudo_key_if_needed(

/*
Iterate the list of fields and look for the given field.
Returns the index of the field if it is found on the list
and -1 otherwise
Set bitmap bits for ALL matching positions in the list.
A GROUP BY field may appear multiple times in the SELECT list
under different aliases (e.g. "SELECT a, a as a2 ... GROUP BY a").
Returns true if at least one match was found, false otherwise.
*/

int Dep_analysis_context::find_field_in_list(List<Item> &fields_list,
Item *field)
bool Dep_analysis_context::find_field_in_list(List<Item> &fields_list,
Item *field,
MY_BITMAP *bitmap)
{
List_iterator<Item> it(fields_list);
int field_idx= 0;
bool found= false;
while (auto next_field= it++)
{
if (next_field->eq(field, false))
return field_idx;
{
bitmap_set_bit(bitmap, field_idx);
found= true;
}
field_idx++;
}
return -1; /*not found*/
return found;
}


Expand Down