diff options
author | Igor Babaev <igor@askmonty.org> | 2013-11-21 15:19:25 -0800 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2013-11-21 15:19:25 -0800 |
commit | c0f31dc9f3e0a42911beb6655a40601d2fddfe8e (patch) | |
tree | eceda1a471f3179d772999bf15a77d282e226c45 /sql/item_cmpfunc.cc | |
parent | f8a6ee59acb082678cf601a10cbe9c1152748242 (diff) | |
download | mariadb-git-c0f31dc9f3e0a42911beb6655a40601d2fddfe8e.tar.gz |
Another attempt to fix bug mdev-5103.
The earlier pushed fix for the bug was incomplete. It did not remove
the main cause of the problem: the function remove_eq_conds()
removed always true multiple equalities from any conjunct, but did not
adjust the list of them stored in Item_cond_and::cond_equal.current_level.
Simplified the test case for the bug and moved it to another test file.
The fix triggered changes in EXPLAIN EXTENDED for some queries.
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r-- | sql/item_cmpfunc.cc | 33 |
1 files changed, 10 insertions, 23 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 49e56a46e84..f5c41ff854c 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -5485,7 +5485,8 @@ Item *Item_bool_rowready_func2::negated_item() */ Item_equal::Item_equal(Item *f1, Item *f2, bool with_const_item) - : Item_bool_func(), eval_item(0), cond_false(0), context_field(NULL) + : Item_bool_func(), eval_item(0), cond_false(0), cond_true(0), + context_field(NULL) { const_item_cache= 0; with_const= with_const_item; @@ -5510,7 +5511,8 @@ Item_equal::Item_equal(Item *f1, Item *f2, bool with_const_item) */ Item_equal::Item_equal(Item_equal *item_equal) - : Item_bool_func(), eval_item(0), cond_false(0), context_field(NULL) + : Item_bool_func(), eval_item(0), cond_false(0), cond_true(0), + context_field(NULL) { const_item_cache= 0; List_iterator_fast<Item> li(item_equal->equal_items); @@ -5569,12 +5571,6 @@ void Item_equal::add_const(Item *c, Item *f) func->quick_fix_field(); cond_false= !func->val_int(); } - /* - TODO: also support the case where Item_equal becomes singular with - this->is_cond_true()=1. When I attempted to mark the item as constant, - the optimizer attempted to remove it, however it is still referenced from - COND_EQUAL and I got a crash. - */ if (cond_false) const_item_cache= 1; } @@ -5779,8 +5775,7 @@ void Item_equal::merge_into_list(List<Item_equal> *list, void Item_equal::sort(Item_field_cmpfunc compare, void *arg) { - if (equal_items.elements > 1) - bubble_sort<Item>(&equal_items, compare, arg); + bubble_sort<Item>(&equal_items, compare, arg); } @@ -5816,6 +5811,9 @@ void Item_equal::update_const() { it.remove(); add_const(item); + if (equal_items.elements == 1) + cond_true= TRUE; + update_used_tables(); } } } @@ -5880,13 +5878,7 @@ bool Item_equal::fix_fields(THD *thd, Item **ref) void Item_equal::update_used_tables() { not_null_tables_cache= used_tables_cache= 0; - /* - TODO: also support the case where Item_equal becomes singular with - this->is_cond_true()=1. When I attempted to mark the item as constant, - the optimizer attempted to remove it, however it is still referenced from - COND_EQUAL and I got a crash. - */ - if ((const_item_cache= cond_false)) + if ((const_item_cache= cond_false || cond_true)) return; Item_equal_fields_iterator it(*this); Item *item; @@ -5934,7 +5926,7 @@ longlong Item_equal::val_int() { if (cond_false) return 0; - if (is_cond_true()) + if (cond_true) return 1; Item *item= get_const(); Item_equal_fields_iterator it(*this); @@ -5960,11 +5952,6 @@ longlong Item_equal::val_int() void Item_equal::fix_length_and_dec() { Item *item= get_first(NO_PARTICULAR_TAB, NULL); - if (!item) - { - DBUG_ASSERT(is_cond_true()); // it should be the only constant - item= equal_items.head(); - } eval_item= cmp_item::get_comparator(item->cmp_type(), item, item->collation.collation); } |