summaryrefslogtreecommitdiff
path: root/sql/opt_range.cc
diff options
context:
space:
mode:
authorunknown <evgen@moonbone.local>2005-11-24 19:54:02 +0300
committerunknown <evgen@moonbone.local>2005-11-24 19:54:02 +0300
commit5f120f6bed5043c28837b5017844beaa63dda700 (patch)
tree9fbad6e137ca207e248e14a1ac2e4cf6c9934eb0 /sql/opt_range.cc
parent40524854d0786bc2059a5ea39aca2b086e34e28b (diff)
downloadmariadb-git-5f120f6bed5043c28837b5017844beaa63dda700.tar.gz
Fix bug#13293 Wrongly used index results in endless loop.
Loose index scan using only second part of multipart index was choosen, which results in creating wrong keys and endless loop. get_best_group_min_max() now allows loose index scan for distinct only if used keyparts forms a prefix of the index. mysql-test/t/group_min_max.test: Test case for bug #13293 Wrongly used index results in endless loop. mysql-test/r/group_min_max.result: Test case for bug #13293 Wrongly used index results in endless loop. sql/opt_range.cc: Fix bug #13293 Wrongly used index results in endless loop. get_best_group_min_max() now allows loose index scan for distinct only if used keyparts forms a prefix of the index.
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r--sql/opt_range.cc13
1 files changed, 13 insertions, 0 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 323e829f219..cddcec29ecc 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -7197,6 +7197,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
{
select_items_it.rewind();
cur_used_key_parts.clear_all();
+ uint max_key_part= 0;
while ((item= select_items_it++))
{
item_field= (Item_field*) item; /* (SA5) already checked above. */
@@ -7214,7 +7215,19 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
cur_group_prefix_len+= cur_part->store_length;
cur_used_key_parts.set_bit(key_part_nr);
++cur_group_key_parts;
+ max_key_part= max(max_key_part,key_part_nr);
}
+ /*
+ Check that used key parts forms a prefix of the index.
+ To check this we compare bits in all_parts and cur_parts.
+ all_parts have all bits set from 0 to (max_key_part-1).
+ cur_parts have bits set for only used keyparts.
+ */
+ ulonglong all_parts, cur_parts;
+ all_parts= (1<<max_key_part) - 1;
+ cur_parts= cur_used_key_parts.to_ulonglong() >> 1;
+ if (all_parts != cur_parts)
+ goto next_index;
}
else
DBUG_ASSERT(FALSE);