diff options
author | Alexander Barkov <bar@mariadb.org> | 2015-07-08 19:20:07 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2015-07-08 19:20:07 +0400 |
commit | 77803703431d79f5dcc2b23b3f878dfdbaf01c2b (patch) | |
tree | f372def78612580f0089ff4ce976fd8911b57198 | |
parent | 8154ef4b16fe140a42f3e90903192bb3b0fec041 (diff) | |
download | mariadb-git-77803703431d79f5dcc2b23b3f878dfdbaf01c2b.tar.gz |
MDEV-8336 The meaning of NO_ZERO_DATE is not clear for DATETIME.
In some cases NO_ZERO_DATE did not allow datetime values with zero date part
and non-zero time part (e.g. '0000-00-00 10:20:30.123456').
Allowing values of this kind in all known pieces of the code.
-rw-r--r-- | mysql-test/r/type_datetime.result | 52 | ||||
-rw-r--r-- | mysql-test/t/type_datetime.test | 27 | ||||
-rw-r--r-- | sql/sql_time.h | 15 |
3 files changed, 92 insertions, 2 deletions
diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result index d8c18711293..0c62007d2a0 100644 --- a/mysql-test/r/type_datetime.result +++ b/mysql-test/r/type_datetime.result @@ -893,5 +893,57 @@ DROP TABLE t1; # End of MDEV-8373 Zero date can be inserted in strict no-zero mode through CREATE TABLE AS SELECT timestamp_field # # +# MDEV-8336 The meaning of NO_ZERO_DATE is not clear for DATETIME +# +SET sql_mode='NO_ZERO_DATE'; +SELECT TIMESTAMP'0000-00-01 10:20:30'; +TIMESTAMP'0000-00-01 10:20:30' +0000-00-01 10:20:30 +SELECT TIMESTAMP'0000-00-00 10:20:30'; +TIMESTAMP'0000-00-00 10:20:30' +0000-00-00 10:20:30 +SELECT TIMESTAMP'0000-00-00 00:00:00.000001'; +TIMESTAMP'0000-00-00 00:00:00.000001' +0000-00-00 00:00:00.000001 +CREATE TABLE t1 (a DATETIME); +INSERT INTO t1 VALUES ('0000-00-00 10:20:30'); +SELECT a, LEAST(a,'2001-01-01 10:20:30') FROM t1; +a LEAST(a,'2001-01-01 10:20:30') +0000-00-00 10:20:30 0000-00-00 10:20:30.000000 +DROP TABLE t1; +CREATE TABLE t1 (a DATETIME(6)); +INSERT INTO t1 VALUES ('0000-00-00 00:00:00.000001'); +SELECT a, LEAST(a,'2001-01-01 10:20:30') FROM t1; +a LEAST(a,'2001-01-01 10:20:30') +0000-00-00 00:00:00.000001 0000-00-00 00:00:00.000001 +DROP TABLE t1; +SELECT STR_TO_DATE('0000-00-00 10:20:30','%Y-%m-%d %h:%i:%s'); +STR_TO_DATE('0000-00-00 10:20:30','%Y-%m-%d %h:%i:%s') +0000-00-00 10:20:30 +SELECT STR_TO_DATE('0000-00-00 00:00:00.000001','%Y-%m-%d %H:%i:%s.%f'); +STR_TO_DATE('0000-00-00 00:00:00.000001','%Y-%m-%d %H:%i:%s.%f') +0000-00-00 00:00:00.000001 +SET old_mode=zero_date_time_cast; +SELECT CAST(TIME'10:20:30' AS DATETIME); +CAST(TIME'10:20:30' AS DATETIME) +0000-00-00 10:20:30 +SELECT CAST(TIME'00:00:00.000001' AS DATETIME(6)); +CAST(TIME'00:00:00.000001' AS DATETIME(6)) +0000-00-00 00:00:00.000001 +SELECT CAST(CAST('10:20:30' AS TIME) AS DATETIME); +CAST(CAST('10:20:30' AS TIME) AS DATETIME) +0000-00-00 10:20:30 +SELECT CAST(CAST('00:00:00.000001' AS TIME(6)) AS DATETIME(6)); +CAST(CAST('00:00:00.000001' AS TIME(6)) AS DATETIME(6)) +0000-00-00 00:00:00.000001 +SELECT CAST(CAST(TIMESTAMP'0000-00-00 10:20:30' AS TIME) AS DATETIME); +CAST(CAST(TIMESTAMP'0000-00-00 10:20:30' AS TIME) AS DATETIME) +0000-00-00 10:20:30 +SELECT CAST(CAST(TIMESTAMP'0000-00-00 00:00:00.000001' AS TIME(6)) AS DATETIME(6)); +CAST(CAST(TIMESTAMP'0000-00-00 00:00:00.000001' AS TIME(6)) AS DATETIME(6)) +0000-00-00 00:00:00.000001 +SET old_mode=DEFAULT; +SET sql_mode=DEFAULT; +# # End of 10.1 tests # diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test index f3e603e9da8..cd311182921 100644 --- a/mysql-test/t/type_datetime.test +++ b/mysql-test/t/type_datetime.test @@ -623,5 +623,32 @@ let defval='0000-00-00 00:00:00'; --source include/type_temporal_zero_default.inc --echo # +--echo # MDEV-8336 The meaning of NO_ZERO_DATE is not clear for DATETIME +--echo # +SET sql_mode='NO_ZERO_DATE'; +SELECT TIMESTAMP'0000-00-01 10:20:30'; +SELECT TIMESTAMP'0000-00-00 10:20:30'; +SELECT TIMESTAMP'0000-00-00 00:00:00.000001'; +CREATE TABLE t1 (a DATETIME); +INSERT INTO t1 VALUES ('0000-00-00 10:20:30'); +SELECT a, LEAST(a,'2001-01-01 10:20:30') FROM t1; +DROP TABLE t1; +CREATE TABLE t1 (a DATETIME(6)); +INSERT INTO t1 VALUES ('0000-00-00 00:00:00.000001'); +SELECT a, LEAST(a,'2001-01-01 10:20:30') FROM t1; +DROP TABLE t1; +SELECT STR_TO_DATE('0000-00-00 10:20:30','%Y-%m-%d %h:%i:%s'); +SELECT STR_TO_DATE('0000-00-00 00:00:00.000001','%Y-%m-%d %H:%i:%s.%f'); +SET old_mode=zero_date_time_cast; +SELECT CAST(TIME'10:20:30' AS DATETIME); +SELECT CAST(TIME'00:00:00.000001' AS DATETIME(6)); +SELECT CAST(CAST('10:20:30' AS TIME) AS DATETIME); +SELECT CAST(CAST('00:00:00.000001' AS TIME(6)) AS DATETIME(6)); +SELECT CAST(CAST(TIMESTAMP'0000-00-00 10:20:30' AS TIME) AS DATETIME); +SELECT CAST(CAST(TIMESTAMP'0000-00-00 00:00:00.000001' AS TIME(6)) AS DATETIME(6)); +SET old_mode=DEFAULT; +SET sql_mode=DEFAULT; + +--echo # --echo # End of 10.1 tests --echo # diff --git a/sql/sql_time.h b/sql/sql_time.h index dc8e4668e1e..8e13ee1870a 100644 --- a/sql/sql_time.h +++ b/sql/sql_time.h @@ -143,13 +143,24 @@ 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) +non_zero_hhmmssuu(const MYSQL_TIME *ltime) +{ + return ltime->hour || ltime->minute || ltime->second || ltime->second_part; +} +static inline bool +non_zero_YYMMDD(const MYSQL_TIME *ltime) { return ltime->year || ltime->month || ltime->day; } static inline bool +non_zero_date(const MYSQL_TIME *ltime) +{ + return non_zero_YYMMDD(ltime) || + (ltime->time_type == MYSQL_TIMESTAMP_DATETIME && + non_zero_hhmmssuu(ltime)); +} +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); |