diff options
author | unknown <evgen@moonbone.local> | 2007-06-06 00:25:06 +0400 |
---|---|---|
committer | unknown <evgen@moonbone.local> | 2007-06-06 00:25:06 +0400 |
commit | 0304a13ee7140727786adf4feb5e1639e85e8138 (patch) | |
tree | 29e692a106429cf57a596e6d2f4fcba6cb8f68bd | |
parent | e409a8a5c0402859ec0754e5d060e3ae06df4c6e (diff) | |
download | mariadb-git-0304a13ee7140727786adf4feb5e1639e85e8138.tar.gz |
Bug#28778: Wrong result of BETWEEN when comparing a DATETIME field with an
integer constants.
This bug is introduced by the fix for bug#16377. Before the fix the
Item_func_between::fix_length_and_dec method converted the second and third
arguments to the type of the first argument if they were constant and the first
argument is of the DATE/DATETIME type. That approach worked well for integer
constants and sometimes produced bad result for string constants. The fix for
the bug#16377 wrongly removed that code at all and as a result of this the
comparison of a DATETIME field and an integer constant was carried out in a
wrong way and sometimes led to wrong result sets.
Now the Item_func_between::fix_length_and_dec method converts the second and
third arguments to the type of the first argument if they are constant, the
first argument is of the DATE/DATETIME type and the DATETIME comparator isn't
applicable.
sql/item_cmpfunc.cc:
Bug#28778: Wrong result of BETWEEN when comparing a DATETIME field with an
integer constants.
Now the Item_func_between::fix_length_and_dec method converts the second and
third arguments to the type of the first argument if they are constant, the
first argument is of the DATE/DATETIME type and the DATETIME comparator isn't
applicable.
mysql-test/r/type_datetime.result:
Added a test case for the bug#28778: Wrong result of BETWEEN when comparing a DATETIME
field with an integer constants.
mysql-test/t/type_datetime.test:
Added a test case for the bug#28778: Wrong result of BETWEEN when comparing a DATETIME
field with an integer constants.
-rw-r--r-- | mysql-test/r/type_datetime.result | 16 | ||||
-rw-r--r-- | mysql-test/t/type_datetime.test | 11 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 17 |
3 files changed, 44 insertions, 0 deletions
diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result index ba02f19712a..9e47b5da2b6 100644 --- a/mysql-test/r/type_datetime.result +++ b/mysql-test/r/type_datetime.result @@ -411,3 +411,19 @@ if(@bug28261 = f1, '', @bug28261:= f1) 2001-01-01 2002-02-02 drop table t1; +create table t1(f1 datetime); +insert into t1 values('2001-01-01'),('2002-02-02'); +select * from t1 where f1 between 20020101 and 20070101000000; +f1 +2002-02-02 00:00:00 +select * from t1 where f1 between 2002010 and 20070101000000; +f1 +2001-01-01 00:00:00 +2002-02-02 00:00:00 +Warnings: +Warning 1292 Incorrect datetime value: '2002010' for column 'f1' at row 1 +select * from t1 where f1 between 20020101 and 2007010100000; +f1 +Warnings: +Warning 1292 Incorrect datetime value: '2007010100000' for column 'f1' at row 1 +drop table t1; diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test index d420afbde37..ffda593f320 100644 --- a/mysql-test/t/type_datetime.test +++ b/mysql-test/t/type_datetime.test @@ -271,3 +271,14 @@ select if(@bug28261 = f1, '', @bug28261:= f1) from t1; select if(@bug28261 = f1, '', @bug28261:= f1) from t1; select if(@bug28261 = f1, '', @bug28261:= f1) from t1; drop table t1; + +# +# Bug#28778: Wrong result of BETWEEN when comparing a DATETIME field with an +# integer constants. +# +create table t1(f1 datetime); +insert into t1 values('2001-01-01'),('2002-02-02'); +select * from t1 where f1 between 20020101 and 20070101000000; +select * from t1 where f1 between 2002010 and 20070101000000; +select * from t1 where f1 between 20020101 and 2007010100000; +drop table t1; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 06c825334c2..919015140c1 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1755,6 +1755,23 @@ 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 (args[0]->real_item()->type() == FIELD_ITEM && + thd->lex->sql_command != SQLCOM_CREATE_VIEW && + thd->lex->sql_command != SQLCOM_SHOW_CREATE) + { + Field *field=((Item_field*) (args[0]->real_item()))->field; + if (field->can_be_compared_as_longlong()) + { + /* + The following can't be recoded with || as convert_constant_item + changes the argument + */ + if (convert_constant_item(thd, field,&args[1])) + cmp_type=INT_RESULT; // Works for all types. + if (convert_constant_item(thd, field,&args[2])) + cmp_type=INT_RESULT; // Works for all types. + } + } } |