summaryrefslogtreecommitdiff
path: root/sql/item_cmpfunc.cc
diff options
context:
space:
mode:
authorevgen@moonbone.local <>2007-07-15 21:51:36 +0400
committerevgen@moonbone.local <>2007-07-15 21:51:36 +0400
commit975d22327ef5235222307f2c015649d3558b5ea7 (patch)
tree4ef5486e94cf10e1661efa4c4a3fa315f4093b7f /sql/item_cmpfunc.cc
parent1baf8a9301928fc7ef7309e1ab57668c814549b4 (diff)
downloadmariadb-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.cc81
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(&ltime);
+ if (!is_null)
+ value= TIME_to_ulonglong_datetime(&ltime);
+ }
+ /*
+ 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)