mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
Bug#18997: DATE_ADD and DATE_SUB perform year2K autoconversion magic on 4-digit year value
if input year for date_add() / date_sub() with INTERVAL is low enough for calc_daynr() to possibly return incorrect results (calc_daynr() has no information on whether the year is low because it was a two-digit year ('77) or because it was a really low four-digit year (0077) and will indiscriminately try to turn the value into a four-digit year by adding 1900 or 2000 respectively), the functions will now throw NULL.
This commit is contained in:
@@ -38,7 +38,10 @@ typedef long my_time_t;
|
|||||||
#define MY_TIME_T_MAX LONG_MAX
|
#define MY_TIME_T_MAX LONG_MAX
|
||||||
#define MY_TIME_T_MIN LONG_MIN
|
#define MY_TIME_T_MIN LONG_MIN
|
||||||
|
|
||||||
|
/* two-digit years < this are 20..; >= this are 19.. */
|
||||||
#define YY_PART_YEAR 70
|
#define YY_PART_YEAR 70
|
||||||
|
/* apply above magic to years < this */
|
||||||
|
#define YY_MAGIC_BELOW 200
|
||||||
|
|
||||||
/* Flags to str_to_datetime */
|
/* Flags to str_to_datetime */
|
||||||
#define TIME_FUZZY_DATE 1
|
#define TIME_FUZZY_DATE 1
|
||||||
|
@@ -736,31 +736,6 @@ select last_day('2005-00-00');
|
|||||||
last_day('2005-00-00')
|
last_day('2005-00-00')
|
||||||
NULL
|
NULL
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1292 Truncated incorrect datetime value: '2005-00-00'
|
|
||||||
select last_day('2005-00-01');
|
|
||||||
last_day('2005-00-01')
|
|
||||||
NULL
|
|
||||||
Warnings:
|
|
||||||
Warning 1292 Truncated incorrect datetime value: '2005-00-01'
|
|
||||||
select last_day('2005-01-00');
|
|
||||||
last_day('2005-01-00')
|
|
||||||
NULL
|
|
||||||
Warnings:
|
|
||||||
Warning 1292 Truncated incorrect datetime value: '2005-01-00'
|
|
||||||
select monthname(str_to_date(null, '%m')), monthname(str_to_date(null, '%m')),
|
|
||||||
monthname(str_to_date(1, '%m')), monthname(str_to_date(0, '%m'));
|
|
||||||
monthname(str_to_date(null, '%m')) monthname(str_to_date(null, '%m')) monthname(str_to_date(1, '%m')) monthname(str_to_date(0, '%m'))
|
|
||||||
NULL NULL January NULL
|
|
||||||
explain extended select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a1,
|
|
||||||
timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05-01 12:58:58.119999') as a2;
|
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
|
||||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
|
|
||||||
Warnings:
|
|
||||||
Note 1003 select timestampdiff(WEEK,_latin1'2001-02-01',_latin1'2001-05-01') AS `a1`,timestampdiff(SECOND_FRAC,_latin1'2001-02-01 12:59:59.120000',_latin1'2001-05-01 12:58:58.119999') AS `a2`
|
|
||||||
select last_day('2005-00-00');
|
|
||||||
last_day('2005-00-00')
|
|
||||||
NULL
|
|
||||||
Warnings:
|
|
||||||
Warning 1292 Incorrect datetime value: '2005-00-00'
|
Warning 1292 Incorrect datetime value: '2005-00-00'
|
||||||
select last_day('2005-00-01');
|
select last_day('2005-00-01');
|
||||||
last_day('2005-00-01')
|
last_day('2005-00-01')
|
||||||
@@ -772,6 +747,17 @@ last_day('2005-01-00')
|
|||||||
NULL
|
NULL
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1292 Incorrect datetime value: '2005-01-00'
|
Warning 1292 Incorrect datetime value: '2005-01-00'
|
||||||
|
select monthname(str_to_date(null, '%m')), monthname(str_to_date(null, '%m')),
|
||||||
|
monthname(str_to_date(1, '%m')), monthname(str_to_date(0, '%m'));
|
||||||
|
monthname(str_to_date(null, '%m')) monthname(str_to_date(null, '%m')) monthname(str_to_date(1, '%m')) monthname(str_to_date(0, '%m'))
|
||||||
|
NULL NULL January NULL
|
||||||
|
End of 4.1 tests
|
||||||
|
explain extended select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a1,
|
||||||
|
timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05-01 12:58:58.119999') as a2;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select timestampdiff(WEEK,_latin1'2001-02-01',_latin1'2001-05-01') AS `a1`,timestampdiff(SECOND_FRAC,_latin1'2001-02-01 12:59:59.120000',_latin1'2001-05-01 12:58:58.119999') AS `a2`
|
||||||
select time_format('100:00:00', '%H %k %h %I %l');
|
select time_format('100:00:00', '%H %k %h %I %l');
|
||||||
time_format('100:00:00', '%H %k %h %I %l')
|
time_format('100:00:00', '%H %k %h %I %l')
|
||||||
100 100 04 04 4
|
100 100 04 04 4
|
||||||
@@ -891,3 +877,38 @@ id day id day
|
|||||||
1 2005-06-01 3 2005-07-15
|
1 2005-06-01 3 2005-07-15
|
||||||
3 2005-07-01 3 2005-07-15
|
3 2005-07-01 3 2005-07-15
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
|
End of 5.0 tests
|
||||||
|
select date_sub("0050-01-01 00:00:01",INTERVAL 2 SECOND);
|
||||||
|
date_sub("0050-01-01 00:00:01",INTERVAL 2 SECOND)
|
||||||
|
NULL
|
||||||
|
select date_sub("0199-01-01 00:00:01",INTERVAL 2 SECOND);
|
||||||
|
date_sub("0199-01-01 00:00:01",INTERVAL 2 SECOND)
|
||||||
|
NULL
|
||||||
|
select date_add("0199-12-31 23:59:59",INTERVAL 2 SECOND);
|
||||||
|
date_add("0199-12-31 23:59:59",INTERVAL 2 SECOND)
|
||||||
|
NULL
|
||||||
|
select date_sub("0200-01-01 00:00:01",INTERVAL 2 SECOND);
|
||||||
|
date_sub("0200-01-01 00:00:01",INTERVAL 2 SECOND)
|
||||||
|
0199-12-31 23:59:59
|
||||||
|
select date_sub("0200-01-01 00:00:01",INTERVAL 1 SECOND);
|
||||||
|
date_sub("0200-01-01 00:00:01",INTERVAL 1 SECOND)
|
||||||
|
0200-01-01 00:00:00
|
||||||
|
select date_sub("0200-01-01 00:00:01",INTERVAL 2 SECOND);
|
||||||
|
date_sub("0200-01-01 00:00:01",INTERVAL 2 SECOND)
|
||||||
|
0199-12-31 23:59:59
|
||||||
|
select date_add("2001-01-01 23:59:59",INTERVAL -2000 YEAR);
|
||||||
|
date_add("2001-01-01 23:59:59",INTERVAL -2000 YEAR)
|
||||||
|
0001-01-01 23:59:59
|
||||||
|
select date_sub("50-01-01 00:00:01",INTERVAL 2 SECOND);
|
||||||
|
date_sub("50-01-01 00:00:01",INTERVAL 2 SECOND)
|
||||||
|
2049-12-31 23:59:59
|
||||||
|
select date_sub("90-01-01 00:00:01",INTERVAL 2 SECOND);
|
||||||
|
date_sub("90-01-01 00:00:01",INTERVAL 2 SECOND)
|
||||||
|
1989-12-31 23:59:59
|
||||||
|
select date_sub("0069-01-01 00:00:01",INTERVAL 2 SECOND);
|
||||||
|
date_sub("0069-01-01 00:00:01",INTERVAL 2 SECOND)
|
||||||
|
NULL
|
||||||
|
select date_sub("0169-01-01 00:00:01",INTERVAL 2 SECOND);
|
||||||
|
date_sub("0169-01-01 00:00:01",INTERVAL 2 SECOND)
|
||||||
|
NULL
|
||||||
|
End of 5.1 tests
|
||||||
|
@@ -367,19 +367,11 @@ select last_day('2005-01-00');
|
|||||||
select monthname(str_to_date(null, '%m')), monthname(str_to_date(null, '%m')),
|
select monthname(str_to_date(null, '%m')), monthname(str_to_date(null, '%m')),
|
||||||
monthname(str_to_date(1, '%m')), monthname(str_to_date(0, '%m'));
|
monthname(str_to_date(1, '%m')), monthname(str_to_date(0, '%m'));
|
||||||
|
|
||||||
# End of 4.1 tests
|
--echo End of 4.1 tests
|
||||||
|
|
||||||
explain extended select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a1,
|
explain extended select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a1,
|
||||||
timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05-01 12:58:58.119999') as a2;
|
timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05-01 12:58:58.119999') as a2;
|
||||||
|
|
||||||
#
|
|
||||||
# Bug #10568
|
|
||||||
#
|
|
||||||
|
|
||||||
select last_day('2005-00-00');
|
|
||||||
select last_day('2005-00-01');
|
|
||||||
select last_day('2005-01-00');
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bug #10590: %h, %I, and %l format specifies should all return results in
|
# Bug #10590: %h, %I, and %l format specifies should all return results in
|
||||||
# the 0-11 range
|
# the 0-11 range
|
||||||
@@ -482,4 +474,23 @@ SELECT * FROM t1, t2
|
|||||||
|
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
|
|
||||||
# End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #18997
|
||||||
|
#
|
||||||
|
|
||||||
|
select date_sub("0050-01-01 00:00:01",INTERVAL 2 SECOND);
|
||||||
|
select date_sub("0199-01-01 00:00:01",INTERVAL 2 SECOND);
|
||||||
|
select date_add("0199-12-31 23:59:59",INTERVAL 2 SECOND);
|
||||||
|
select date_sub("0200-01-01 00:00:01",INTERVAL 2 SECOND);
|
||||||
|
select date_sub("0200-01-01 00:00:01",INTERVAL 1 SECOND);
|
||||||
|
select date_sub("0200-01-01 00:00:01",INTERVAL 2 SECOND);
|
||||||
|
select date_add("2001-01-01 23:59:59",INTERVAL -2000 YEAR);
|
||||||
|
select date_sub("50-01-01 00:00:01",INTERVAL 2 SECOND);
|
||||||
|
select date_sub("90-01-01 00:00:01",INTERVAL 2 SECOND);
|
||||||
|
select date_sub("0069-01-01 00:00:01",INTERVAL 2 SECOND);
|
||||||
|
select date_sub("0169-01-01 00:00:01",INTERVAL 2 SECOND);
|
||||||
|
|
||||||
|
|
||||||
|
--echo End of 5.1 tests
|
||||||
|
@@ -689,7 +689,7 @@ long calc_daynr(uint year,uint month,uint day)
|
|||||||
|
|
||||||
if (year == 0 && month == 0 && day == 0)
|
if (year == 0 && month == 0 && day == 0)
|
||||||
DBUG_RETURN(0); /* Skip errors */
|
DBUG_RETURN(0); /* Skip errors */
|
||||||
if (year < 200)
|
if (year < YY_MAGIC_BELOW)
|
||||||
{
|
{
|
||||||
if ((year=year+1900) < 1900+YY_PART_YEAR)
|
if ((year=year+1900) < 1900+YY_PART_YEAR)
|
||||||
year+=100;
|
year+=100;
|
||||||
|
@@ -1963,6 +1963,9 @@ bool Item_date_add_interval::get_date(TIME *ltime, uint fuzzy_date)
|
|||||||
if (date_sub_interval)
|
if (date_sub_interval)
|
||||||
interval.neg = !interval.neg;
|
interval.neg = !interval.neg;
|
||||||
|
|
||||||
|
if (ltime->year < YY_MAGIC_BELOW)
|
||||||
|
return (null_value=1);
|
||||||
|
|
||||||
return (null_value= date_add_interval(ltime, int_type, interval));
|
return (null_value= date_add_interval(ltime, int_type, interval));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user