summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <evgen@moonbone.local>2007-06-06 00:25:06 +0400
committerunknown <evgen@moonbone.local>2007-06-06 00:25:06 +0400
commit0304a13ee7140727786adf4feb5e1639e85e8138 (patch)
tree29e692a106429cf57a596e6d2f4fcba6cb8f68bd
parente409a8a5c0402859ec0754e5d060e3ae06df4c6e (diff)
downloadmariadb-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.result16
-rw-r--r--mysql-test/t/type_datetime.test11
-rw-r--r--sql/item_cmpfunc.cc17
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.
+ }
+ }
}