summaryrefslogtreecommitdiff
path: root/sql/item_cmpfunc.cc
diff options
context:
space:
mode:
authorEvgeny Potemkin <epotemkin@mysql.com>2009-11-06 22:42:24 +0300
committerEvgeny Potemkin <epotemkin@mysql.com>2009-11-06 22:42:24 +0300
commit47d850a89df4fe3c1f136643c15aade734d54895 (patch)
tree87a29826dd6b7a9c6edd9743ac44ef603633fa21 /sql/item_cmpfunc.cc
parent9ea972dc47fa582e23c1578bc0de16ac75999ae1 (diff)
parent60d358af278413af666ab06e07f4c58a41bd5374 (diff)
downloadmariadb-git-47d850a89df4fe3c1f136643c15aade734d54895.tar.gz
Auto-merged fix for the bug#34384.
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r--sql/item_cmpfunc.cc47
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)
{