summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/func_time.result10
-rw-r--r--mysql-test/r/strict.result8
-rw-r--r--mysql-test/t/func_time.test8
-rw-r--r--mysql-test/t/strict.test10
-rw-r--r--sql/item_timefunc.cc10
-rw-r--r--sql/sql_time.h12
6 files changed, 43 insertions, 15 deletions
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index 38a547843ad..67844eddef2 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -1936,3 +1936,13 @@ SELECT 1 FROM DUAL WHERE MINUTE(TIMEDIFF(NULL, '12:12:12'));
1
SELECT 1 FROM DUAL WHERE SECOND(TIMEDIFF(NULL, '12:12:12'));
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;
diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result
index b1e4cb669ed..da3c658b5a4 100644
--- a/mysql-test/r/strict.result
+++ b/mysql-test/r/strict.result
@@ -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 (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'));
-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'));
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'));
@@ -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
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
-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'));
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'));
@@ -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'));
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'));
-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'));
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'));
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index 109734c3316..1a7cd42054b 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -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 MINUTE(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;
diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test
index f6080de6c2c..c429e9cfe5b 100644
--- a/mysql-test/t/strict.test
+++ b/mysql-test/t/strict.test
@@ -188,13 +188,15 @@ 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 (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
# All test cases expected to fail should return
# 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
INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i'));
--error 1411
INSERT INTO t1 (col1) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i'));
@@ -214,8 +216,6 @@ INSERT INTO t1 (col1) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y'));
# 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
INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i'));
--error 1411
INSERT INTO t1 (col2) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i'));
@@ -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
# 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'));
--error 1411
INSERT INTO t1 (col3) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i'));
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 69a6dac5381..8f818b60ae7 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -415,8 +415,8 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
l_time->minute > 59 || l_time->second > 59)
goto err;
- if ((fuzzy_date & TIME_NO_ZERO_DATE) &&
- (l_time->year == 0 || l_time->month == 0 || l_time->day == 0))
+ int was_cut;
+ if (check_date(l_time, fuzzy_date | TIME_INVALID_DATES, &was_cut))
goto err;
if (val != val_end)
@@ -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);
/* Set to NULL if invalid date, but keep the value */
null_value= check_date(&ltime,
- (ltime.year || ltime.month || ltime.day),
(TIME_NO_ZERO_IN_DATE | TIME_NO_ZERO_DATE),
&dummy);
if (null_value)
@@ -1190,7 +1189,7 @@ bool Item_func_unix_timestamp::get_timestamp_value(my_time_t *seconds,
}
MYSQL_TIME ltime;
- if (get_arg0_date(&ltime, 0))
+ if (get_arg0_date(&ltime, TIME_NO_ZERO_IN_DATE))
return 1;
uint error_code;
@@ -2432,8 +2431,7 @@ bool Item_date_typecast::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
ltime->time_type= MYSQL_TIMESTAMP_DATE;
int unused;
- if (check_date(ltime, ltime->year || ltime->month || ltime->day,
- fuzzy_date, &unused))
+ if (check_date(ltime, fuzzy_date, &unused))
{
ErrConvTime str(ltime);
make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
diff --git a/sql/sql_time.h b/sql/sql_time.h
index c1a75bb2ad3..998d7d78da1 100644
--- a/sql/sql_time.h
+++ b/sql/sql_time.h
@@ -110,4 +110,16 @@ extern DATE_TIME_FORMAT global_time_format;
extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[];
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 */