Commit 03e7620d authored by timour@mysql.com's avatar timour@mysql.com

Fix for BUG#8532.

The problem was in that the code that analyses the applicability of the
QUICK_GROUP_MIN_MAX access method for DISTINC queries assumed that there
are no duplicate column references in the DISTINCT clause, and it added
non-exiting key parts for the duplicate column references. 

The solution adds a test to check whether the select list already contained
a field with the same name. If such field was already present, then it was
already decided to use its key part for index access. In this such case we
must skip the duplicate field instead of counting it as a new field.
parent 21ca91aa
...@@ -1657,6 +1657,44 @@ a ...@@ -1657,6 +1657,44 @@ a
b b
c c
d d
select distinct a1,a1 from t1;
a1 a1
a a
b b
c c
d d
select distinct a2,a1,a2,a1 from t1;
a2 a1 a2 a1
a a a a
b a b a
a b a b
b b b b
a c a c
b c b c
a d a d
b d b d
select distinct t1.a1,t2.a1 from t1,t2;
a1 a1
a a
b a
c a
d a
a b
b b
c b
d b
a c
b c
c c
d c
a d
b d
c d
d d
a e
b e
c e
d e
explain select distinct a1,a2,b from t1; explain select distinct a1,a2,b from t1;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL idx_t1_1 147 NULL 17 Using index for group-by 1 SIMPLE t1 range NULL idx_t1_1 147 NULL 17 Using index for group-by
......
...@@ -475,11 +475,15 @@ select distinct a1,a2,b,c from t2 where (a2 >= 'b') and (b = 'a') and (c = 'i121 ...@@ -475,11 +475,15 @@ select distinct a1,a2,b,c from t2 where (a2 >= 'b') and (b = 'a') and (c = 'i121
select distinct a1,a2,b from t2 where (a1 > 'a') and (a2 > 'a') and (b = 'c'); select distinct a1,a2,b from t2 where (a1 > 'a') and (a2 > 'a') and (b = 'c');
select distinct b from t2 where (a2 >= 'b') and (b = 'a'); select distinct b from t2 where (a2 >= 'b') and (b = 'a');
-- BUG 6303 -- BUG #6303
select distinct t_00.a1 select distinct t_00.a1
from t1 t_00 from t1 t_00
where exists ( select * from t2 where a1 = t_00.a1 ); where exists ( select * from t2 where a1 = t_00.a1 );
-- BUG #8532 - SELECT DISTINCT a, a causes server to crash
select distinct a1,a1 from t1;
select distinct a2,a1,a2,a1 from t1;
select distinct t1.a1,t2.a1 from t1,t2;
-- --
-- DISTINCT queries with GROUP-BY -- DISTINCT queries with GROUP-BY
......
...@@ -6878,6 +6878,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) ...@@ -6878,6 +6878,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
SEL_ARG *cur_index_tree= NULL; SEL_ARG *cur_index_tree= NULL;
ha_rows cur_quick_prefix_records= 0; ha_rows cur_quick_prefix_records= 0;
uint cur_param_idx; uint cur_param_idx;
key_map cur_used_key_parts;
for (uint cur_index= 0 ; cur_index_info != cur_index_info_end ; for (uint cur_index= 0 ; cur_index_info != cur_index_info_end ;
cur_index_info++, cur_index++) cur_index_info++, cur_index++)
...@@ -6925,17 +6926,25 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) ...@@ -6925,17 +6926,25 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
else if (join->select_distinct) else if (join->select_distinct)
{ {
select_items_it.rewind(); select_items_it.rewind();
cur_used_key_parts.clear_all();
while ((item= select_items_it++)) while ((item= select_items_it++))
{ {
item_field= (Item_field*) item; /* (SA5) already checked above. */ item_field= (Item_field*) item; /* (SA5) already checked above. */
/* Find the order of the key part in the index. */ /* Find the order of the key part in the index. */
key_part_nr= get_field_keypart(cur_index_info, item_field->field); key_part_nr= get_field_keypart(cur_index_info, item_field->field);
/*
Check if this attribute was already present in the select list.
If it was present, then its corresponding key part was alredy used.
*/
if (cur_used_key_parts.is_set(key_part_nr))
continue;
if (key_part_nr < 1 || key_part_nr > join->fields_list.elements) if (key_part_nr < 1 || key_part_nr > join->fields_list.elements)
goto next_index; goto next_index;
cur_part= cur_index_info->key_part + key_part_nr - 1; cur_part= cur_index_info->key_part + key_part_nr - 1;
cur_group_prefix_len+= cur_part->store_length; cur_group_prefix_len+= cur_part->store_length;
cur_used_key_parts.set_bit(key_part_nr);
++cur_group_key_parts;
} }
cur_group_key_parts= join->fields_list.elements;
} }
else else
DBUG_ASSERT(FALSE); DBUG_ASSERT(FALSE);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment