summaryrefslogtreecommitdiff
path: root/sql/opt_range.cc
diff options
context:
space:
mode:
authorunknown <timour@mysql.com>2005-02-28 16:20:02 +0200
committerunknown <timour@mysql.com>2005-02-28 16:20:02 +0200
commit7a703d6acee84b845184f86e7d50865967308c77 (patch)
tree25102b84202ed8c9b4d5c0d16ddcf5d7271a0f94 /sql/opt_range.cc
parent108702a34e37bae22f117a3a7e18e7cead3e63c8 (diff)
downloadmariadb-git-7a703d6acee84b845184f86e7d50865967308c77.tar.gz
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. mysql-test/r/group_min_max.result: Added test results for BUG#8532. mysql-test/t/group_min_max.test: Added tests for BUG#8532. sql/opt_range.cc: 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.
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r--sql/opt_range.cc11
1 files changed, 10 insertions, 1 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 12e5c60312b..812d5a41cbc 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -6878,6 +6878,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
SEL_ARG *cur_index_tree= NULL;
ha_rows cur_quick_prefix_records= 0;
uint cur_param_idx;
+ key_map cur_used_key_parts;
for (uint cur_index= 0 ; cur_index_info != cur_index_info_end ;
cur_index_info++, cur_index++)
@@ -6925,17 +6926,25 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
else if (join->select_distinct)
{
select_items_it.rewind();
+ cur_used_key_parts.clear_all();
while ((item= select_items_it++))
{
item_field= (Item_field*) item; /* (SA5) already checked above. */
/* Find the order of the key part in the index. */
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)
goto next_index;
cur_part= cur_index_info->key_part + key_part_nr - 1;
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
DBUG_ASSERT(FALSE);