Auto-merged fix for the bug#34384.

This commit is contained in:
Evgeny Potemkin 2009-11-06 22:42:24 +03:00
commit 5594215c58
7 changed files with 198 additions and 40 deletions

View file

@ -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)
{