diff options
author | unknown <sanja@montyprogram.com> | 2013-11-11 20:38:04 +0200 |
---|---|---|
committer | unknown <sanja@montyprogram.com> | 2013-11-11 20:38:04 +0200 |
commit | dfed447888e1ab71ec0c80b61459bde6ee6eaf66 (patch) | |
tree | b921c0e431da431f8254f434f720fcc469547269 /sql/item_cmpfunc.cc | |
parent | 668a5a4ab814d14f95cfbda7776a1f05246dd52e (diff) | |
parent | c98a054fdeab9c2d3a637cf4fce57a2f9756dcc8 (diff) | |
download | mariadb-git-dfed447888e1ab71ec0c80b61459bde6ee6eaf66.tar.gz |
merge 5.3->5.5
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r-- | sql/item_cmpfunc.cc | 36 |
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); } |