diff options
author | Evgeny Potemkin <epotemkin@mysql.com> | 2009-11-06 22:42:24 +0300 |
---|---|---|
committer | Evgeny Potemkin <epotemkin@mysql.com> | 2009-11-06 22:42:24 +0300 |
commit | 47d850a89df4fe3c1f136643c15aade734d54895 (patch) | |
tree | 87a29826dd6b7a9c6edd9743ac44ef603633fa21 /sql/item_cmpfunc.cc | |
parent | 9ea972dc47fa582e23c1578bc0de16ac75999ae1 (diff) | |
parent | 60d358af278413af666ab06e07f4c58a41bd5374 (diff) | |
download | mariadb-git-47d850a89df4fe3c1f136643c15aade734d54895.tar.gz |
Auto-merged fix for the bug#34384.
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r-- | sql/item_cmpfunc.cc | 47 |
1 files changed, 43 insertions, 4 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 0f02b83ade4..317f4fff400 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -887,13 +887,13 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg, { enum enum_date_cmp_type cmp_type; ulonglong const_value= (ulonglong)-1; + thd= current_thd; + owner= owner_arg; a= a1; b= a2; if ((cmp_type= can_compare_as_dates(*a, *b, &const_value))) { - thd= current_thd; - owner= owner_arg; a_type= (*a)->field_type(); b_type= (*b)->field_type(); a_cache= 0; @@ -901,6 +901,10 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg, if (const_value != (ulonglong)-1) { + /* + cache_converted_constant can't be used here because it can't + correctly convert a DATETIME value from string to int representation. + */ Item_cache_int *cache= new Item_cache_int(); /* Mark the cache as non-const to prevent re-caching. */ cache->set_used_tables(1); @@ -926,8 +930,6 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg, (*b)->field_type() == MYSQL_TYPE_TIME) { /* Compare TIME values as integers. */ - thd= current_thd; - owner= owner_arg; a_cache= 0; b_cache= 0; is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC); @@ -946,10 +948,46 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg, return 1; } + a= cache_converted_constant(thd, a, &a_cache, type); + b= cache_converted_constant(thd, b, &b_cache, type); return set_compare_func(owner_arg, type); } +/** + Convert and cache a constant. + + @param value [in] An item to cache + @param cache_item [out] Placeholder for the cache item + @param type [in] Comparison type + + @details + When given item is a constant and its type differs from comparison type + then cache its value to avoid type conversion of this constant on each + evaluation. In this case the value is cached and the reference to the cache + is returned. + Original value is returned otherwise. + + @return cache item or original value. +*/ + +Item** Arg_comparator::cache_converted_constant(THD *thd, Item **value, + Item **cache_item, + Item_result type) +{ + /* Don't need cache if doing context analysis only. */ + if (!thd->is_context_analysis_only() && + (*value)->const_item() && type != (*value)->result_type()) + { + Item_cache *cache= Item_cache::get_cache(*value, type); + cache->store(*value); + *cache_item= cache; + return cache_item; + } + return value; +} + + void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1) { thd= current_thd; @@ -1588,6 +1626,7 @@ longlong Item_in_optimizer::val_int() bool tmp; DBUG_ASSERT(fixed == 1); cache->store(args[0]); + cache->cache_value(); if (cache->null_value) { |