summaryrefslogtreecommitdiff
path: root/sql/item_cmpfunc.cc
diff options
context:
space:
mode:
authorunknown <sanja@montyprogram.com>2013-11-11 20:38:04 +0200
committerunknown <sanja@montyprogram.com>2013-11-11 20:38:04 +0200
commitdfed447888e1ab71ec0c80b61459bde6ee6eaf66 (patch)
treeb921c0e431da431f8254f434f720fcc469547269 /sql/item_cmpfunc.cc
parent668a5a4ab814d14f95cfbda7776a1f05246dd52e (diff)
parentc98a054fdeab9c2d3a637cf4fce57a2f9756dcc8 (diff)
downloadmariadb-git-dfed447888e1ab71ec0c80b61459bde6ee6eaf66.tar.gz
merge 5.3->5.5
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r--sql/item_cmpfunc.cc36
1 files changed, 31 insertions, 5 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index d71185d49a4..22049ac26b4 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1438,9 +1438,11 @@ bool Item_in_optimizer::eval_not_null_tables(uchar *opt_arg)
bool Item_in_optimizer::fix_left(THD *thd, Item **ref)
{
+ DBUG_ENTER("Item_in_optimizer::fix_left");
if ((!args[0]->fixed && args[0]->fix_fields(thd, args)) ||
(!cache && !(cache= Item_cache::get_cache(args[0]))))
- return 1;
+ DBUG_RETURN(1);
+ DBUG_PRINT("info", ("actual fix fields"));
cache->setup(args[0]);
if (cache->cols() == 1)
@@ -1466,11 +1468,15 @@ bool Item_in_optimizer::fix_left(THD *thd, Item **ref)
{
my_error(ER_NOT_SUPPORTED_YET, MYF(0),
"SUBQUERY in ROW in left expression of IN/ALL/ANY");
- return 1;
+ DBUG_RETURN(1);
}
Item *element=args[0]->element_index(i);
if (element->used_tables() || !element->const_item())
- ((Item_cache *)cache->element_index(i))->set_used_tables(OUTER_REF_TABLE_BIT);
+ {
+ ((Item_cache *)cache->element_index(i))->
+ set_used_tables(OUTER_REF_TABLE_BIT);
+ cache->set_used_tables(OUTER_REF_TABLE_BIT);
+ }
else
((Item_cache *)cache->element_index(i))->set_used_tables(0);
}
@@ -1484,7 +1490,7 @@ bool Item_in_optimizer::fix_left(THD *thd, Item **ref)
cache->store(args[0]);
cache->cache_value();
}
- return 0;
+ DBUG_RETURN(0);
}
@@ -5681,6 +5687,12 @@ 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;
}
@@ -5885,7 +5897,8 @@ void Item_equal::merge_into_list(List<Item_equal> *list,
void Item_equal::sort(Item_field_cmpfunc compare, void *arg)
{
- bubble_sort<Item>(&equal_items, compare, arg);
+ if (equal_items.elements > 1)
+ bubble_sort<Item>(&equal_items, compare, arg);
}
@@ -5999,6 +6012,12 @@ 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))
return;
Item_equal_fields_iterator it(*this);
@@ -6048,6 +6067,8 @@ longlong Item_equal::val_int()
{
if (cond_false)
return 0;
+ if (is_cond_true())
+ return 1;
Item *item= get_const();
Item_equal_fields_iterator it(*this);
if (!item)
@@ -6072,6 +6093,11 @@ 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);
}