Commit 7cc77106 authored by Alexander Barkov's avatar Alexander Barkov

Merging MDEV-4635 from 5.3.

Also, fixing a bug in STR_TO_DATE(). It erroneously returned
error in strict mode for dates like '0000-01-01'
(zero year, but non-zero month and day).

According to the manual:
- NO_ZERO_DATE disallows 0000-00-00 (all date parts are zeros)
- NO_ZERO_IN_DATE disallows zero month (YYYY-00-DD) or day (YYYY-MM-00).

0000-01-01 is a valid date, even in strict mode.


modified:
  mysql-test/r/func_time.result
  mysql-test/r/strict.result
  mysql-test/t/func_time.test
  mysql-test/t/strict.test
  sql/item_timefunc.cc
  sql/sql_time.h
pending merges:
  Alexander Barkov 2013-06-17 MDEV-4635 Crash in UNIX_TIMESTAMP(STR_TO_DAT...
parents be06b886 4085836a
...@@ -1936,3 +1936,13 @@ SELECT 1 FROM DUAL WHERE MINUTE(TIMEDIFF(NULL, '12:12:12')); ...@@ -1936,3 +1936,13 @@ SELECT 1 FROM DUAL WHERE MINUTE(TIMEDIFF(NULL, '12:12:12'));
1 1
SELECT 1 FROM DUAL WHERE SECOND(TIMEDIFF(NULL, '12:12:12')); SELECT 1 FROM DUAL WHERE SECOND(TIMEDIFF(NULL, '12:12:12'));
1 1
#
# MDEV-4635 Crash in UNIX_TIMESTAMP(STR_TO_DATE('2020','%Y'))
#
SET TIME_ZONE='+02:00';
SELECT UNIX_TIMESTAMP(STR_TO_DATE('2020','%Y'));
UNIX_TIMESTAMP(STR_TO_DATE('2020','%Y'))
NULL
Warnings:
Warning 1411 Incorrect datetime value: '2020' for function str_to_date
SET TIME_ZONE=DEFAULT;
...@@ -206,7 +206,9 @@ INSERT INTO t1 (col1) VALUES (STR_TO_DATE('15.10.2004','%d.%m.%Y')); ...@@ -206,7 +206,9 @@ INSERT INTO t1 (col1) VALUES (STR_TO_DATE('15.10.2004','%d.%m.%Y'));
INSERT INTO t1 (col2) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i')); INSERT INTO t1 (col2) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i'));
INSERT INTO t1 (col3) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i')); INSERT INTO t1 (col3) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i'));
INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i')); INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i'));
ERROR HY000: Incorrect datetime value: '31.10.0000 15.30' for function str_to_date Warnings:
Note 1265 Data truncated for column 'col1' at row 1
INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i'));
INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i')); INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i'));
ERROR HY000: Incorrect datetime value: '31.0.2004 15.30' for function str_to_date ERROR HY000: Incorrect datetime value: '31.0.2004 15.30' for function str_to_date
INSERT INTO t1 (col1) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i')); INSERT INTO t1 (col1) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i'));
...@@ -221,8 +223,6 @@ INSERT INTO t1 (col1) VALUES(STR_TO_DATE('15.13.2004 15.30','%d.%m.%Y %H.%i')); ...@@ -221,8 +223,6 @@ INSERT INTO t1 (col1) VALUES(STR_TO_DATE('15.13.2004 15.30','%d.%m.%Y %H.%i'));
ERROR HY000: Incorrect datetime value: '15.13.2004 15.30' for function str_to_date ERROR HY000: Incorrect datetime value: '15.13.2004 15.30' for function str_to_date
INSERT INTO t1 (col1) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y')); INSERT INTO t1 (col1) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y'));
ERROR HY000: Incorrect datetime value: '00.00.0000' for function str_to_date ERROR HY000: Incorrect datetime value: '00.00.0000' for function str_to_date
INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i'));
ERROR HY000: Incorrect datetime value: '31.10.0000 15.30' for function str_to_date
INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i')); INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i'));
ERROR HY000: Incorrect datetime value: '31.0.2004 15.30' for function str_to_date ERROR HY000: Incorrect datetime value: '31.0.2004 15.30' for function str_to_date
INSERT INTO t1 (col2) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i')); INSERT INTO t1 (col2) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i'));
...@@ -238,7 +238,7 @@ ERROR HY000: Incorrect datetime value: '15.13.2004 15.30' for function str_to_da ...@@ -238,7 +238,7 @@ ERROR HY000: Incorrect datetime value: '15.13.2004 15.30' for function str_to_da
INSERT INTO t1 (col2) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y')); INSERT INTO t1 (col2) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y'));
ERROR HY000: Incorrect datetime value: '00.00.0000' for function str_to_date ERROR HY000: Incorrect datetime value: '00.00.0000' for function str_to_date
INSERT INTO t1 (col3) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i')); INSERT INTO t1 (col3) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i'));
ERROR HY000: Incorrect datetime value: '31.10.0000 15.30' for function str_to_date ERROR 22007: Incorrect datetime value: '0000-10-31 15:30:00' for column 'col3' at row 1
INSERT INTO t1 (col3) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i')); INSERT INTO t1 (col3) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i'));
ERROR HY000: Incorrect datetime value: '31.0.2004 15.30' for function str_to_date ERROR HY000: Incorrect datetime value: '31.0.2004 15.30' for function str_to_date
INSERT INTO t1 (col3) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i')); INSERT INTO t1 (col3) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i'));
......
...@@ -1184,3 +1184,11 @@ SELECT 1 FROM DUAL WHERE DAYOFMONTH(TIMEDIFF(NULL, '12:12:12')); ...@@ -1184,3 +1184,11 @@ SELECT 1 FROM DUAL WHERE DAYOFMONTH(TIMEDIFF(NULL, '12:12:12'));
SELECT 1 FROM DUAL WHERE HOUR(TIMEDIFF(NULL, '12:12:12')); SELECT 1 FROM DUAL WHERE HOUR(TIMEDIFF(NULL, '12:12:12'));
SELECT 1 FROM DUAL WHERE MINUTE(TIMEDIFF(NULL, '12:12:12')); SELECT 1 FROM DUAL WHERE MINUTE(TIMEDIFF(NULL, '12:12:12'));
SELECT 1 FROM DUAL WHERE SECOND(TIMEDIFF(NULL, '12:12:12')); SELECT 1 FROM DUAL WHERE SECOND(TIMEDIFF(NULL, '12:12:12'));
--echo #
--echo # MDEV-4635 Crash in UNIX_TIMESTAMP(STR_TO_DATE('2020','%Y'))
--echo #
SET TIME_ZONE='+02:00';
SELECT UNIX_TIMESTAMP(STR_TO_DATE('2020','%Y'));
SET TIME_ZONE=DEFAULT;
...@@ -188,12 +188,14 @@ INSERT INTO t1 (col1) VALUES (STR_TO_DATE('15.10.2004','%d.%m.%Y')); ...@@ -188,12 +188,14 @@ INSERT INTO t1 (col1) VALUES (STR_TO_DATE('15.10.2004','%d.%m.%Y'));
INSERT INTO t1 (col2) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i')); INSERT INTO t1 (col2) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i'));
INSERT INTO t1 (col3) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i')); INSERT INTO t1 (col3) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i'));
# Zero year is not a problem for DATE/DATETIME
INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i'));
INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i'));
## Test INSERT with STR_TO_DATE into DATE ## Test INSERT with STR_TO_DATE into DATE
# All test cases expected to fail should return # All test cases expected to fail should return
# SQLSTATE 22007 <invalid date value> # SQLSTATE 22007 <invalid date value>
--error 1411
INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i'));
--error 1411 --error 1411
INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i')); INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i'));
--error 1411 --error 1411
...@@ -213,8 +215,6 @@ INSERT INTO t1 (col1) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y')); ...@@ -213,8 +215,6 @@ INSERT INTO t1 (col1) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y'));
# All test cases expected to fail should return # All test cases expected to fail should return
# SQLSTATE 22007 <invalid datetime value> # SQLSTATE 22007 <invalid datetime value>
--error 1411
INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i'));
--error 1411 --error 1411
INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i')); INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i'));
--error 1411 --error 1411
...@@ -234,7 +234,7 @@ INSERT INTO t1 (col2) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y')); ...@@ -234,7 +234,7 @@ INSERT INTO t1 (col2) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y'));
# All test cases expected to fail should return # All test cases expected to fail should return
# SQLSTATE 22007 <invalid datetime value> # SQLSTATE 22007 <invalid datetime value>
--error 1411 --error 1292
INSERT INTO t1 (col3) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i')); INSERT INTO t1 (col3) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i'));
--error 1411 --error 1411
INSERT INTO t1 (col3) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i')); INSERT INTO t1 (col3) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i'));
......
...@@ -415,8 +415,8 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, ...@@ -415,8 +415,8 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
l_time->minute > 59 || l_time->second > 59) l_time->minute > 59 || l_time->second > 59)
goto err; goto err;
if ((fuzzy_date & TIME_NO_ZERO_DATE) && int was_cut;
(l_time->year == 0 || l_time->month == 0 || l_time->day == 0)) if (check_date(l_time, fuzzy_date | TIME_INVALID_DATES, &was_cut))
goto err; goto err;
if (val != val_end) if (val != val_end)
...@@ -866,7 +866,6 @@ longlong Item_func_to_days::val_int_endpoint(bool left_endp, bool *incl_endp) ...@@ -866,7 +866,6 @@ longlong Item_func_to_days::val_int_endpoint(bool left_endp, bool *incl_endp)
res=(longlong) calc_daynr(ltime.year,ltime.month,ltime.day); res=(longlong) calc_daynr(ltime.year,ltime.month,ltime.day);
/* Set to NULL if invalid date, but keep the value */ /* Set to NULL if invalid date, but keep the value */
null_value= check_date(&ltime, null_value= check_date(&ltime,
(ltime.year || ltime.month || ltime.day),
(TIME_NO_ZERO_IN_DATE | TIME_NO_ZERO_DATE), (TIME_NO_ZERO_IN_DATE | TIME_NO_ZERO_DATE),
&dummy); &dummy);
if (null_value) if (null_value)
...@@ -1190,7 +1189,7 @@ bool Item_func_unix_timestamp::get_timestamp_value(my_time_t *seconds, ...@@ -1190,7 +1189,7 @@ bool Item_func_unix_timestamp::get_timestamp_value(my_time_t *seconds,
} }
MYSQL_TIME ltime; MYSQL_TIME ltime;
if (get_arg0_date(&ltime, 0)) if (get_arg0_date(&ltime, TIME_NO_ZERO_IN_DATE))
return 1; return 1;
uint error_code; uint error_code;
...@@ -2432,8 +2431,7 @@ bool Item_date_typecast::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) ...@@ -2432,8 +2431,7 @@ bool Item_date_typecast::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
ltime->time_type= MYSQL_TIMESTAMP_DATE; ltime->time_type= MYSQL_TIMESTAMP_DATE;
int unused; int unused;
if (check_date(ltime, ltime->year || ltime->month || ltime->day, if (check_date(ltime, fuzzy_date, &unused))
fuzzy_date, &unused))
{ {
ErrConvTime str(ltime); ErrConvTime str(ltime);
make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
......
...@@ -110,4 +110,16 @@ extern DATE_TIME_FORMAT global_time_format; ...@@ -110,4 +110,16 @@ extern DATE_TIME_FORMAT global_time_format;
extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[]; extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[];
extern LEX_STRING interval_type_to_name[]; extern LEX_STRING interval_type_to_name[];
static inline bool
non_zero_date(const MYSQL_TIME *ltime)
{
return ltime->year || ltime->month || ltime->day;
}
static inline bool
check_date(const MYSQL_TIME *ltime, ulonglong flags, int *was_cut)
{
return check_date(ltime, non_zero_date(ltime), flags, was_cut);
}
#endif /* SQL_TIME_INCLUDED */ #endif /* SQL_TIME_INCLUDED */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment