diff options
author | evgen@moonbone.local <> | 2007-07-15 21:51:36 +0400 |
---|---|---|
committer | evgen@moonbone.local <> | 2007-07-15 21:51:36 +0400 |
commit | 975d22327ef5235222307f2c015649d3558b5ea7 (patch) | |
tree | 4ef5486e94cf10e1661efa4c4a3fa315f4093b7f /sql/item_cmpfunc.cc | |
parent | 1baf8a9301928fc7ef7309e1ab57668c814549b4 (diff) | |
download | mariadb-git-975d22327ef5235222307f2c015649d3558b5ea7.tar.gz |
Extended fix for the bug#29555.
The get_time_value function is added. It is used to obtain TIME values both
from items the can return time as an integer and from items that can return
time only as a string.
The Arg_comparator::compare_datetime function now uses pointer to a getter
function to obtain values to compare. Now this function is also used for
comparison of TIME values.
The get_value_func variable is added to the Arg_comparator class.
It points to a getter function for the DATE/DATETIME/TIME comparator.
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r-- | sql/item_cmpfunc.cc | 81 |
1 files changed, 74 insertions, 7 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 555384b2bfc..8e16dfb4145 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -666,6 +666,68 @@ Arg_comparator::can_compare_as_dates(Item *a, Item *b, ulonglong *const_value) } +/* + Retrieves correct TIME value from the given item. + + SYNOPSIS + get_time_value() + thd thread handle + item_arg [in/out] item to retrieve TIME value from + cache_arg [in/out] pointer to place to store the caching item to + warn_item [in] unused + is_null [out] TRUE <=> the item_arg is null + + DESCRIPTION + Retrieves the correct TIME value from given item for comparison by the + compare_datetime() function. + If item's result can be compared as longlong then its int value is used + and a value returned by get_time function is used otherwise. + If an item is a constant one then its value is cached and it isn't + get parsed again. An Item_cache_int object is used for caching values. It + seamlessly substitutes the original item. The cache item is marked as + non-constant to prevent re-caching it again. + + RETURN + obtained value +*/ + +ulonglong +get_time_value(THD *thd, Item ***item_arg, Item **cache_arg, + Item *warn_item, bool *is_null) +{ + ulonglong value; + Item *item= **item_arg; + MYSQL_TIME ltime; + + if (item->result_as_longlong()) + { + value= item->val_int(); + *is_null= item->null_value; + } + else + { + *is_null= item->get_time(<ime); + if (!is_null) + value= TIME_to_ulonglong_datetime(<ime); + } + /* + Do not cache GET_USER_VAR() function as its const_item() may return TRUE + for the current thread but it still may change during the execution. + */ + if (item->const_item() && cache_arg && (item->type() != Item::FUNC_ITEM || + ((Item_func*)item)->functype() != Item_func::GUSERVAR_FUNC)) + { + Item_cache_int *cache= new Item_cache_int(); + /* Mark the cache as non-const to prevent re-caching. */ + cache->set_used_tables(1); + cache->store(item, value); + *cache_arg= cache; + *item_arg= cache_arg; + } + return value; +} + + int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg, Item **a1, Item **a2, Item_result type) @@ -704,6 +766,7 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg, } is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC); func= &Arg_comparator::compare_datetime; + get_value_func= &get_datetime_value; return 0; } else if (type == STRING_RESULT && (*a)->field_type() == MYSQL_TYPE_TIME && @@ -712,9 +775,11 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg, /* Compare TIME values as integers. */ thd= current_thd; owner= owner_arg; - func= ((test(owner && owner->functype() == Item_func::EQUAL_FUNC)) ? - &Arg_comparator::compare_e_int : - &Arg_comparator::compare_int_unsigned); + a_cache= 0; + b_cache= 0; + is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC); + func= &Arg_comparator::compare_datetime; + get_value_func= &get_time_value; return 0; } @@ -735,8 +800,10 @@ void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1) b_cache= 0; is_nulls_eq= FALSE; func= &Arg_comparator::compare_datetime; + get_value_func= &get_datetime_value; } + /* Retrieves correct DATETIME value from given item. @@ -850,8 +917,8 @@ int Arg_comparator::compare_datetime() bool is_null= FALSE; ulonglong a_value, b_value; - /* Get DATE/DATETIME value of the 'a' item. */ - a_value= get_datetime_value(thd, &a, &a_cache, *b, &is_null); + /* Get DATE/DATETIME/TIME value of the 'a' item. */ + a_value= (*get_value_func)(thd, &a, &a_cache, *b, &is_null); if (!is_nulls_eq && is_null) { if (owner) @@ -859,8 +926,8 @@ int Arg_comparator::compare_datetime() return -1; } - /* Get DATE/DATETIME value of the 'b' item. */ - b_value= get_datetime_value(thd, &b, &b_cache, *a, &is_null); + /* Get DATE/DATETIME/TIME value of the 'b' item. */ + b_value= (*get_value_func)(thd, &b, &b_cache, *a, &is_null); if (is_null) { if (owner) |