mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 02:05:57 +01:00
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. mysql-test/t/type_time.test: Extended test case for the bug#29555. mysql-test/r/type_time.result: Extended test case for the bug#29555. sql/item_cmpfunc.cc: 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. sql/item_cmpfunc.h: Extended fix for the bug#29555. The get_value_func variable is added to the Arg_comparator class. It points to a getter function for the DATE/DATETIME/TIME comparator.
This commit is contained in:
parent
4b7e6a3842
commit
6e078ff543
4 changed files with 86 additions and 7 deletions
|
@ -103,6 +103,12 @@ cast('100:55:50' as time) > cast('024:00:00' as time)
|
|||
select cast('300:55:50' as time) > cast('240:00:00' as time);
|
||||
cast('300:55:50' as time) > cast('240:00:00' as time)
|
||||
1
|
||||
create table t1 (f1 time);
|
||||
insert into t1 values ('24:00:00');
|
||||
select cast('24:00:00' as time) = (select f1 from t1);
|
||||
cast('24:00:00' as time) = (select f1 from t1)
|
||||
1
|
||||
drop table t1;
|
||||
create table t1(f1 time, f2 time);
|
||||
insert into t1 values('20:00:00','150:00:00');
|
||||
select 1 from t1 where cast('100:00:00' as time) between f1 and f2;
|
||||
|
|
|
@ -50,6 +50,10 @@ select cast('300:55:50' as time) < cast('240:00:00' as time);
|
|||
select cast('100:55:50' as time) > cast('24:00:00' as time);
|
||||
select cast('100:55:50' as time) > cast('024:00:00' as time);
|
||||
select cast('300:55:50' as time) > cast('240:00:00' as time);
|
||||
create table t1 (f1 time);
|
||||
insert into t1 values ('24:00:00');
|
||||
select cast('24:00:00' as time) = (select f1 from t1);
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#29739: Incorrect time comparison in BETWEEN.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -42,6 +42,8 @@ class Arg_comparator: public Sql_alloc
|
|||
bool is_nulls_eq; // TRUE <=> compare for the EQUAL_FUNC
|
||||
enum enum_date_cmp_type { CMP_DATE_DFLT= 0, CMP_DATE_WITH_DATE,
|
||||
CMP_DATE_WITH_STR, CMP_STR_WITH_DATE };
|
||||
ulonglong (*get_value_func)(THD *thd, Item ***item_arg, Item **cache_arg,
|
||||
Item *warn_item, bool *is_null);
|
||||
public:
|
||||
DTCollation cmp_collation;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue