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

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
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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;
+8 −0
Original line number Diff line number Diff line
@@ -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;
+16 −8
Original line number Diff line number Diff line
@@ -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,6 +1748,8 @@ 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.
  */
  if (cmp_type == STRING_RESULT)
  {
    for (i= 0; i < 3; i++)
    {
      if (args[i]->is_datetime())
@@ -1754,10 +1757,10 @@ void Item_func_between::fix_length_and_dec()
        datetime_found= TRUE;
        continue;
      }
    if (args[i]->result_type() == STRING_RESULT)
      continue;
    compare_as_dates= FALSE;
    break;
      if (args[i]->field_type() == MYSQL_TYPE_TIME &&
          args[i]->result_as_longlong())
        time_items_found++;
    }
  }
  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)