summaryrefslogtreecommitdiff
path: root/sql/item_cmpfunc.cc
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2013-11-21 15:19:25 -0800
committerIgor Babaev <igor@askmonty.org>2013-11-21 15:19:25 -0800
commitc0f31dc9f3e0a42911beb6655a40601d2fddfe8e (patch)
treeeceda1a471f3179d772999bf15a77d282e226c45 /sql/item_cmpfunc.cc
parentf8a6ee59acb082678cf601a10cbe9c1152748242 (diff)
downloadmariadb-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.cc33
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);
}