1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Bug#27759: Wrong DATE/DATETIME comparison in LEAST()/GREATEST() functions.

The LEAST/GREATEST functions compared DATE/DATETIME values as
strings which in some cases could lead to a wrong result.

A new member function called cmp_datetimes() is added to the
Item_func_min_max class. It compares arguments in DATETIME context
and returns index of the least/greatest argument.
The Item_func_min_max::fix_length_and_dec() function now detects when
arguments should be compared in DATETIME context and sets the newly
added flag compare_as_dates. It indicates that the cmp_datetimes() function
should be called to get a correct result.
Item_func_min_max::val_xxx() methods are corrected to call the
cmp_datetimes() function when needed.
Objects of the Item_splocal class now stores and reports correct original
field type.


mysql-test/t/type_datetime.test:
  Added a test case for the bug#27759: Wrong DATE/DATETIME comparison in LEAST()/GREATEST() functions.
mysql-test/r/type_datetime.result:
  Added a test case for the bug#27759: Wrong DATE/DATETIME comparison in LEAST()/GREATEST() functions.
mysql-test/r/sp-vars.result:
  A test case result corrected after the fix for the bug#27759.
sql/mysql_priv.h:
  Bug#27759: Wrong DATE/DATETIME comparison in LEAST()/GREATEST() functions.
  Added the prototype of the get_datetime_value() function.
sql/item_func.h:
  Bug#27759: Wrong DATE/DATETIME comparison in LEAST()/GREATEST() functions.
  A new member function called cmp_datetimes() is added to the
  Item_func_min_max class.
sql/item_func.cc:
  Bug#27759: Wrong DATE/DATETIME comparison in LEAST()/GREATEST() functions.
  A new member function called cmp_datetimes() is added to the
  Item_func_min_max class. It compares arguments in DATETIME context
  and returns index of the least/greatest argument.
  The Item_func_min_max::fix_length_and_dec() function now detects when
  arguments should be compared in DATETIME context and sets the newly
  added flag compare_as_dates. It indicates that the cmp_datetimes() function
  should be called to get a correct result.
  Item_func_min_max::val_xxx() methods are corrected to call the
  cmp_datetimes() function when needed.
sql/item_cmpfunc.cc:
  Bug#27759: Wrong DATE/DATETIME comparison in LEAST()/GREATEST() functions.
  The get_datetime_value() function is no longer static.
sql/item.h:
  Bug#27759: Wrong DATE/DATETIME comparison in LEAST()/GREATEST() functions.
  Objects of the Item_splocal class now stores and reports correct original
  field type.
sql/item.cc:
  Bug#27759: Wrong DATE/DATETIME comparison in LEAST()/GREATEST() functions.
  Objects of the Item_splocal class now stores and reports correct original
  field type.
This commit is contained in:
unknown
2007-05-04 18:57:10 +04:00
parent 8e8ece72eb
commit 99bde6d9ec
9 changed files with 164 additions and 6 deletions

View File

@ -690,12 +690,12 @@ END|
CALL p1(NOW());
Table Create Table
t1 CREATE TABLE "t1" (
"x" varbinary(19) default NULL
"x" datetime default NULL
)
CALL p1('test');
Table Create Table
t1 CREATE TABLE "t1" (
"x" varbinary(19) default NULL
"x" datetime default NULL
)
Warnings:
Warning 1264 Out of range value adjusted for column 'x' at row 1

View File

@ -264,3 +264,33 @@ f2
SELECT 1 from dual where NOW() BETWEEN CURRENT_DATE() - INTERVAL 1 DAY AND CURRENT_DATE();
1
drop table t1;
select least(cast('01-01-01' as date), '01-01-02');
least(cast('01-01-01' as date), '01-01-02')
2001-01-01
select greatest(cast('01-01-01' as date), '01-01-02');
greatest(cast('01-01-01' as date), '01-01-02')
01-01-02
select least(cast('01-01-01' as date), '01-01-02') + 0;
least(cast('01-01-01' as date), '01-01-02') + 0
20010101
select greatest(cast('01-01-01' as date), '01-01-02') + 0;
greatest(cast('01-01-01' as date), '01-01-02') + 0
20010102
select least(cast('01-01-01' as datetime), '01-01-02') + 0;
least(cast('01-01-01' as datetime), '01-01-02') + 0
20010101000000
DROP PROCEDURE IF EXISTS test27759 ;
CREATE PROCEDURE test27759()
BEGIN
declare v_a date default '2007-4-10';
declare v_b date default '2007-4-11';
declare v_c datetime default '2004-4-9 0:0:0';
select v_a as a,v_b as b,
least( v_a, v_b ) as a_then_b,
least( v_b, v_a ) as b_then_a,
least( v_c, v_a ) as c_then_a;
END;|
call test27759();
a b a_then_b b_then_a c_then_a
2007-04-10 2007-04-11 2007-04-10 2007-04-10 2004-04-09 00:00:00
drop procedure test27759;

View File

@ -178,3 +178,29 @@ select f2, f3 from t1 where '01-03-10' between f2 and f3;
select f2 from t1 where DATE(f2) between "2001-4-15" AND "01-4-15";
SELECT 1 from dual where NOW() BETWEEN CURRENT_DATE() - INTERVAL 1 DAY AND CURRENT_DATE();
drop table t1;
#
# Bug#27759: Wrong DATE/DATETIME comparison in LEAST()/GREATEST() functions.
#
select least(cast('01-01-01' as date), '01-01-02');
select greatest(cast('01-01-01' as date), '01-01-02');
select least(cast('01-01-01' as date), '01-01-02') + 0;
select greatest(cast('01-01-01' as date), '01-01-02') + 0;
select least(cast('01-01-01' as datetime), '01-01-02') + 0;
--disable_warnings
DROP PROCEDURE IF EXISTS test27759 ;
--enable_warnings
DELIMITER |;
CREATE PROCEDURE test27759()
BEGIN
declare v_a date default '2007-4-10';
declare v_b date default '2007-4-11';
declare v_c datetime default '2004-4-9 0:0:0';
select v_a as a,v_b as b,
least( v_a, v_b ) as a_then_b,
least( v_b, v_a ) as b_then_a,
least( v_c, v_a ) as c_then_a;
END;|
DELIMITER ;|
call test27759();
drop procedure test27759;