diff options
author | unknown <timour@mysql.com> | 2006-03-31 12:34:28 +0300 |
---|---|---|
committer | unknown <timour@mysql.com> | 2006-03-31 12:34:28 +0300 |
commit | a01d48f92e9c2eebe91e92962b5fdb075978c712 (patch) | |
tree | 69470df2afebeaffdacddbd994da021e73d309ae /sql/item.cc | |
parent | 82f645531ca1843de7651102e8653fdee1faf5a6 (diff) | |
download | mariadb-git-a01d48f92e9c2eebe91e92962b5fdb075978c712.tar.gz |
Fix for BUG#16710.
The bug was due to a missed case in the detection of whether an index
can be used for loose scan. More precisely, the range optimizer chose
to use loose index scan for queries for which the condition(s) over
an index key part could not be pushed to the index together with the
loose scan.
As a result, loose index scan was selecting the first row in the
index with a given GROUP BY prefix, and was applying the WHERE
clause after that, while it should have inspected all rows with
the given prefix, and apply the WHERE clause to all of them.
The fix detects and skips such cases.
mysql-test/r/group_min_max.result:
Added test for BUG#16710.
mysql-test/t/group_min_max.test:
Added test for BUG#16710.
sql/item.cc:
Added new method [Item | Item_field]::find_item_in_field_list_processor.
sql/item.h:
Added new method [Item | Item_field]::find_item_in_field_list_processor.
sql/opt_range.cc:
Handle the case when there is no MIN/MAX aggregate function, and a
keypart of the index being considered, that is after the GROUP BY
prefix, is used in the WHERE clause and the condition where it is
used cannot be pushed to the index.
If this is the case, we rule out this index.
Diffstat (limited to 'sql/item.cc')
-rw-r--r-- | sql/item.cc | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/sql/item.cc b/sql/item.cc index 70fea63ba7e..e8cfab34d54 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -499,7 +499,7 @@ bool Item_ident::remove_dependence_processor(byte * arg) arguments in a condition the method must return false. RETURN - false to force the evaluation of collect_item_field_processor + FALSE to force the evaluation of collect_item_field_processor for the subsequent items. */ @@ -520,6 +520,38 @@ bool Item_field::collect_item_field_processor(byte *arg) } +/* + Check if an Item_field references some field from a list of fields. + + SYNOPSIS + Item_field::find_item_in_field_list_processor + arg Field being compared, arg must be of type Field + + DESCRIPTION + Check whether the Item_field represented by 'this' references any + of the fields in the keyparts passed via 'arg'. Used with the + method Item::walk() to test whether any keypart in a sequence of + keyparts is referenced in an expression. + + RETURN + TRUE if 'this' references the field 'arg' + FALE otherwise +*/ +bool Item_field::find_item_in_field_list_processor(byte *arg) +{ + KEY_PART_INFO *first_non_group_part= *((KEY_PART_INFO **) arg); + KEY_PART_INFO *last_part= *(((KEY_PART_INFO **) arg) + 1); + KEY_PART_INFO *cur_part; + + for (cur_part= first_non_group_part; cur_part != last_part; cur_part++) + { + if (field->eq(cur_part->field)) + return TRUE; + } + return FALSE; +} + + bool Item::check_cols(uint c) { if (c != 1) |