Commit 1b1464ba authored by evgen@moonbone.local's avatar evgen@moonbone.local

Bug#29739: Incorrect time comparison in BETWEEN.

Time values were compared by the BETWEEN function as strings. This led to a
wrong result in cases when some of arguments are less than 100 hours and other
are greater.

Now if all 3 arguments of the BETWEEN function are of the TIME type then
they are compared as integers.
parent c118fe53
......@@ -103,3 +103,9 @@ 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, 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;
1
1
drop table t1;
......@@ -50,3 +50,11 @@ 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);
#
# Bug#29739: Incorrect time comparison in BETWEEN.
#
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;
drop table t1;
......@@ -1728,6 +1728,7 @@ void Item_func_between::fix_length_and_dec()
THD *thd= current_thd;
int i;
bool datetime_found= FALSE;
int time_items_found= 0;
compare_as_dates= TRUE;
/*
......@@ -1747,17 +1748,19 @@ void Item_func_between::fix_length_and_dec()
At least one of items should be a DATE/DATETIME item and other items
should return the STRING result.
*/
for (i= 0; i < 3; i++)
if (cmp_type == STRING_RESULT)
{
if (args[i]->is_datetime())
for (i= 0; i < 3; i++)
{
datetime_found= TRUE;
continue;
if (args[i]->is_datetime())
{
datetime_found= TRUE;
continue;
}
if (args[i]->field_type() == MYSQL_TYPE_TIME &&
args[i]->result_as_longlong())
time_items_found++;
}
if (args[i]->result_type() == STRING_RESULT)
continue;
compare_as_dates= FALSE;
break;
}
if (!datetime_found)
compare_as_dates= FALSE;
......@@ -1767,6 +1770,11 @@ void Item_func_between::fix_length_and_dec()
ge_cmp.set_datetime_cmp_func(args, args + 1);
le_cmp.set_datetime_cmp_func(args, args + 2);
}
else if (time_items_found == 3)
{
/* Compare TIME items as integers. */
cmp_type= INT_RESULT;
}
else if (args[0]->real_item()->type() == FIELD_ITEM &&
thd->lex->sql_command != SQLCOM_CREATE_VIEW &&
thd->lex->sql_command != SQLCOM_SHOW_CREATE)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment