diff options
author | Alexander Barkov <bar@mariadb.com> | 2019-08-22 14:17:04 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2019-08-22 15:09:59 +0400 |
commit | 235cf969d21ba3406a9325d952fda47c589e58d6 (patch) | |
tree | 850e3fe62f7d4baec24847bd15808402bda48517 | |
parent | 7b4de10477a7bdb51656d827ad2d914d29a4be4c (diff) | |
download | mariadb-git-235cf969d21ba3406a9325d952fda47c589e58d6.tar.gz |
MDEV-20397 Support TIMESTAMP, DATETIME, TIME in ROUND() and TRUNCATE()
-rw-r--r-- | mysql-test/include/type_hrtime.inc | 2 | ||||
-rw-r--r-- | mysql-test/main/func_time.result | 4 | ||||
-rw-r--r-- | mysql-test/main/timezone2.result | 26 | ||||
-rw-r--r-- | mysql-test/main/timezone2.test | 26 | ||||
-rw-r--r-- | mysql-test/main/type_datetime_hires.result | 543 | ||||
-rw-r--r-- | mysql-test/main/type_datetime_hires.test | 70 | ||||
-rw-r--r-- | mysql-test/main/type_time_hires.result | 315 | ||||
-rw-r--r-- | mysql-test/main/type_time_hires.test | 63 | ||||
-rw-r--r-- | mysql-test/main/type_timestamp_hires.result | 299 | ||||
-rw-r--r-- | mysql-test/main/type_timestamp_hires.test | 70 | ||||
-rw-r--r-- | sql/item_func.cc | 66 | ||||
-rw-r--r-- | sql/item_func.h | 19 | ||||
-rw-r--r-- | sql/sql_time.cc | 3 | ||||
-rw-r--r-- | sql/sql_time.h | 2 | ||||
-rw-r--r-- | sql/sql_type.cc | 41 | ||||
-rw-r--r-- | sql/sql_type.h | 3 |
16 files changed, 1536 insertions, 16 deletions
diff --git a/mysql-test/include/type_hrtime.inc b/mysql-test/include/type_hrtime.inc index d666dc63bba..128e3295133 100644 --- a/mysql-test/include/type_hrtime.inc +++ b/mysql-test/include/type_hrtime.inc @@ -18,7 +18,7 @@ insert t1 values (20101211030405.789e0); insert ignore t1 values (99991231235959e1); select * from t1; --replace_regex /121000/121094/ /457000/457031/ /789000/789062/ -select truncate(a, 6) from t1; # Field::val_real() +select cast(a AS double(30,6)) from t1; # Field::val_real() select a DIV 1 from t1; # Field::val_int() select group_concat(distinct a) from t1; # Field::cmp() alter table t1 engine=innodb; diff --git a/mysql-test/main/func_time.result b/mysql-test/main/func_time.result index 0b5fb46c1d5..a9d4f365f9b 100644 --- a/mysql-test/main/func_time.result +++ b/mysql-test/main/func_time.result @@ -2180,13 +2180,13 @@ CREATE TABLE t1 (a TIMESTAMP(3)); INSERT INTO t1 VALUES ('2001-01-01 10:20:30.999'); SELECT CAST(COALESCE(a,a) AS SIGNED) AS c1, CAST(COALESCE(a,a) AS DECIMAL(25,3)) AS c2, ROUND(COALESCE(a,a)) AS c2 FROM t1; c1 c2 c2 -20010101102030 20010101102030.999 20010101102031 +20010101102030 20010101102030.999 2001-01-01 10:20:31 DROP TABLE t1; CREATE TABLE t1 (a TIME(3)); INSERT INTO t1 VALUES ('10:20:30.999'); SELECT CAST(COALESCE(a,a) AS SIGNED) AS c1, CAST(COALESCE(a,a) AS DECIMAL(25,3)) AS c2, ROUND(COALESCE(a,a)) AS c2 FROM t1; c1 c2 c2 -102030 102030.999 102031 +102030 102030.999 10:20:31 DROP TABLE t1; SELECT CAST(COALESCE(DATE('2001-01-01'),TIMESTAMP('2001-01-02 10:20:30')) AS SIGNED) AS c1, diff --git a/mysql-test/main/timezone2.result b/mysql-test/main/timezone2.result index 7b5b2e6dd71..b858e761a81 100644 --- a/mysql-test/main/timezone2.result +++ b/mysql-test/main/timezone2.result @@ -610,5 +610,31 @@ DROP TABLE t1; SET timestamp=DEFAULT; SET time_zone=DEFAULT; # +# MDEV-20397 Support TIMESTAMP, DATETIME, TIME in ROUND() and TRUNCATE() +# +SET time_zone='Europe/Moscow'; +CREATE TABLE t1 (i INT, d TIMESTAMP(6)); +SET timestamp=1288479599.999999 /* this is the last second in summer time */ ; +INSERT INTO t1 VALUES (1,NULL); +SET timestamp=1288479600.000000 /* this is the first second in winter time */ ; +INSERT INTO t1 VALUES (2,NULL); +SELECT i, d, UNIX_TIMESTAMP(d) FROM t1 ORDER BY d; +i d UNIX_TIMESTAMP(d) +1 2010-10-31 02:59:59.999999 1288479599.999999 +2 2010-10-31 02:00:00.000000 1288479600.000000 +CREATE TABLE t2 (i INT, d TIMESTAMP, expected_unix_timestamp INT UNSIGNED); +INSERT INTO t2 SELECT i, ROUND(d) AS d, ROUND(UNIX_TIMESTAMP(d)) FROM t1; +# UNIX_TIMESTAMP(d) and expected_unix_timestamp should return the same value. +# Currently they do not, because ROUND(timestamp) is performed as DATETIME. +# We should fix this eventually. +SELECT i, d, UNIX_TIMESTAMP(d), expected_unix_timestamp FROM t2 ORDER BY i; +i d UNIX_TIMESTAMP(d) expected_unix_timestamp +1 2010-10-31 03:00:00 1288483200 1288479600 +2 2010-10-31 02:00:00 1288476000 1288479600 +DROP TABLE t2; +DROP TABLE t1; +SET timestamp=DEFAULT; +SET time_zone=DEFAULT; +# # End of 10.4 tests # diff --git a/mysql-test/main/timezone2.test b/mysql-test/main/timezone2.test index d0c6588cd05..9d364224311 100644 --- a/mysql-test/main/timezone2.test +++ b/mysql-test/main/timezone2.test @@ -551,6 +551,32 @@ DROP TABLE t1; SET timestamp=DEFAULT; SET time_zone=DEFAULT; +--echo # +--echo # MDEV-20397 Support TIMESTAMP, DATETIME, TIME in ROUND() and TRUNCATE() +--echo # + +SET time_zone='Europe/Moscow'; +CREATE TABLE t1 (i INT, d TIMESTAMP(6)); +SET timestamp=1288479599.999999 /* this is the last second in summer time */ ; +INSERT INTO t1 VALUES (1,NULL); +SET timestamp=1288479600.000000 /* this is the first second in winter time */ ; +INSERT INTO t1 VALUES (2,NULL); +SELECT i, d, UNIX_TIMESTAMP(d) FROM t1 ORDER BY d; + +CREATE TABLE t2 (i INT, d TIMESTAMP, expected_unix_timestamp INT UNSIGNED); +INSERT INTO t2 SELECT i, ROUND(d) AS d, ROUND(UNIX_TIMESTAMP(d)) FROM t1; + +--echo # UNIX_TIMESTAMP(d) and expected_unix_timestamp should return the same value. +--echo # Currently they do not, because ROUND(timestamp) is performed as DATETIME. +--echo # We should fix this eventually. + +SELECT i, d, UNIX_TIMESTAMP(d), expected_unix_timestamp FROM t2 ORDER BY i; +DROP TABLE t2; + +DROP TABLE t1; +SET timestamp=DEFAULT; +SET time_zone=DEFAULT; + --echo # --echo # End of 10.4 tests diff --git a/mysql-test/main/type_datetime_hires.result b/mysql-test/main/type_datetime_hires.result index 38e2c2a5ac8..ebb9c6032b9 100644 --- a/mysql-test/main/type_datetime_hires.result +++ b/mysql-test/main/type_datetime_hires.result @@ -17,8 +17,8 @@ a 2010-12-11 01:02:03.456 2010-12-11 03:04:05.789 2010-12-11 15:47:11.123 -select truncate(a, 6) from t1; -truncate(a, 6) +select cast(a AS double(30,6)) from t1; +cast(a AS double(30,6)) 0.000000 20101211002003.120000 20101211010203.457031 @@ -352,3 +352,542 @@ NULL 978307200.0000 DROP TABLE t1; SET @@time_zone=DEFAULT; +# +# Start of 10.4 tests +# +# +# MDEV-20397 Support TIMESTAMP, DATETIME, TIME in ROUND() and TRUNCATE() +# +CREATE TABLE t1 (a1 DATETIME(6), a2 DATETIME(6) NOT NULL); +CREATE TABLE t2 AS SELECT +ROUND(a1) AS r1, +ROUND(a2) AS r2, +TRUNCATE(a1,0) AS t1, +TRUNCATE(a2,0) AS t2 +FROM t1; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `r1` datetime DEFAULT NULL, + `r2` datetime DEFAULT NULL, + `t1` datetime DEFAULT NULL, + `t2` datetime NOT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t2; +DROP TABLE t1; +CREATE TABLE t1 (a DATETIME(6)); +INSERT INTO t1 VALUES +('0000-00-00 00:00:00.999999'), +('0000-00-00 23:59:59.999999'), +('0000-00-01 00:00:00.999999'), +('0000-00-01 23:59:59.999999'), +('0000-00-31 23:59:59.999999'), +('0000-01-01 00:00:00.999999'), +('0000-01-01 23:59:59.999999'), +('0000-01-31 23:59:59.999999'), +('0000-02-28 23:59:59.999999'), +('0000-12-31 23:59:59.999999'), +('0001-01-01 00:00:00.999999'), +('0001-02-28 23:59:59.999999'), +('0001-12-31 23:59:59.999999'), +('0004-02-28 23:59:59.999999'), +('0004-02-29 23:59:59.999999'), +('2000-02-29 23:59:59.999999'), +('2000-12-31 23:59:59.999999'), +('9999-12-31 23:59:59.999999'); +SELECT a, TRUNCATE(a,0) FROM t1; +a TRUNCATE(a,0) +0000-00-00 00:00:00.999999 0000-00-00 00:00:00 +0000-00-00 23:59:59.999999 0000-00-00 23:59:59 +0000-00-01 00:00:00.999999 0000-00-01 00:00:00 +0000-00-01 23:59:59.999999 0000-00-01 23:59:59 +0000-00-31 23:59:59.999999 0000-00-31 23:59:59 +0000-01-01 00:00:00.999999 0000-01-01 00:00:00 +0000-01-01 23:59:59.999999 0000-01-01 23:59:59 +0000-01-31 23:59:59.999999 0000-01-31 23:59:59 +0000-02-28 23:59:59.999999 0000-02-28 23:59:59 +0000-12-31 23:59:59.999999 0000-12-31 23:59:59 +0001-01-01 00:00:00.999999 0001-01-01 00:00:00 +0001-02-28 23:59:59.999999 0001-02-28 23:59:59 +0001-12-31 23:59:59.999999 0001-12-31 23:59:59 +0004-02-28 23:59:59.999999 0004-02-28 23:59:59 +0004-02-29 23:59:59.999999 0004-02-29 23:59:59 +2000-02-29 23:59:59.999999 2000-02-29 23:59:59 +2000-12-31 23:59:59.999999 2000-12-31 23:59:59 +9999-12-31 23:59:59.999999 9999-12-31 23:59:59 +SELECT a, TRUNCATE(a,1) FROM t1; +a TRUNCATE(a,1) +0000-00-00 00:00:00.999999 0000-00-00 00:00:00.9 +0000-00-00 23:59:59.999999 0000-00-00 23:59:59.9 +0000-00-01 00:00:00.999999 0000-00-01 00:00:00.9 +0000-00-01 23:59:59.999999 0000-00-01 23:59:59.9 +0000-00-31 23:59:59.999999 0000-00-31 23:59:59.9 +0000-01-01 00:00:00.999999 0000-01-01 00:00:00.9 +0000-01-01 23:59:59.999999 0000-01-01 23:59:59.9 +0000-01-31 23:59:59.999999 0000-01-31 23:59:59.9 +0000-02-28 23:59:59.999999 0000-02-28 23:59:59.9 +0000-12-31 23:59:59.999999 0000-12-31 23:59:59.9 +0001-01-01 00:00:00.999999 0001-01-01 00:00:00.9 +0001-02-28 23:59:59.999999 0001-02-28 23:59:59.9 +0001-12-31 23:59:59.999999 0001-12-31 23:59:59.9 +0004-02-28 23:59:59.999999 0004-02-28 23:59:59.9 +0004-02-29 23:59:59.999999 0004-02-29 23:59:59.9 +2000-02-29 23:59:59.999999 2000-02-29 23:59:59.9 +2000-12-31 23:59:59.999999 2000-12-31 23:59:59.9 +9999-12-31 23:59:59.999999 9999-12-31 23:59:59.9 +SELECT a, TRUNCATE(a,2) FROM t1; +a TRUNCATE(a,2) +0000-00-00 00:00:00.999999 0000-00-00 00:00:00.99 +0000-00-00 23:59:59.999999 0000-00-00 23:59:59.99 +0000-00-01 00:00:00.999999 0000-00-01 00:00:00.99 +0000-00-01 23:59:59.999999 0000-00-01 23:59:59.99 +0000-00-31 23:59:59.999999 0000-00-31 23:59:59.99 +0000-01-01 00:00:00.999999 0000-01-01 00:00:00.99 +0000-01-01 23:59:59.999999 0000-01-01 23:59:59.99 +0000-01-31 23:59:59.999999 0000-01-31 23:59:59.99 +0000-02-28 23:59:59.999999 0000-02-28 23:59:59.99 +0000-12-31 23:59:59.999999 0000-12-31 23:59:59.99 +0001-01-01 00:00:00.999999 0001-01-01 00:00:00.99 +0001-02-28 23:59:59.999999 0001-02-28 23:59:59.99 +0001-12-31 23:59:59.999999 0001-12-31 23:59:59.99 +0004-02-28 23:59:59.999999 0004-02-28 23:59:59.99 +0004-02-29 23:59:59.999999 0004-02-29 23:59:59.99 +2000-02-29 23:59:59.999999 2000-02-29 23:59:59.99 +2000-12-31 23:59:59.999999 2000-12-31 23:59:59.99 +9999-12-31 23:59:59.999999 9999-12-31 23:59:59.99 +SELECT a, TRUNCATE(a,3) FROM t1; +a TRUNCATE(a,3) +0000-00-00 00:00:00.999999 0000-00-00 00:00:00.999 +0000-00-00 23:59:59.999999 0000-00-00 23:59:59.999 +0000-00-01 00:00:00.999999 0000-00-01 00:00:00.999 +0000-00-01 23:59:59.999999 0000-00-01 23:59:59.999 +0000-00-31 23:59:59.999999 0000-00-31 23:59:59.999 +0000-01-01 00:00:00.999999 0000-01-01 00:00:00.999 +0000-01-01 23:59:59.999999 0000-01-01 23:59:59.999 +0000-01-31 23:59:59.999999 0000-01-31 23:59:59.999 +0000-02-28 23:59:59.999999 0000-02-28 23:59:59.999 +0000-12-31 23:59:59.999999 0000-12-31 23:59:59.999 +0001-01-01 00:00:00.999999 0001-01-01 00:00:00.999 +0001-02-28 23:59:59.999999 0001-02-28 23:59:59.999 +0001-12-31 23:59:59.999999 0001-12-31 23:59:59.999 +0004-02-28 23:59:59.999999 0004-02-28 23:59:59.999 +0004-02-29 23:59:59.999999 0004-02-29 23:59:59.999 +2000-02-29 23:59:59.999999 2000-02-29 23:59:59.999 +2000-12-31 23:59:59.999999 2000-12-31 23:59:59.999 +9999-12-31 23:59:59.999999 9999-12-31 23:59:59.999 +SELECT a, TRUNCATE(a,4) FROM t1; +a TRUNCATE(a,4) +0000-00-00 00:00:00.999999 0000-00-00 00:00:00.9999 +0000-00-00 23:59:59.999999 0000-00-00 23:59:59.9999 +0000-00-01 00:00:00.999999 0000-00-01 00:00:00.9999 +0000-00-01 23:59:59.999999 0000-00-01 23:59:59.9999 +0000-00-31 23:59:59.999999 0000-00-31 23:59:59.9999 +0000-01-01 00:00:00.999999 0000-01-01 00:00:00.9999 +0000-01-01 23:59:59.999999 0000-01-01 23:59:59.9999 +0000-01-31 23:59:59.999999 0000-01-31 23:59:59.9999 +0000-02-28 23:59:59.999999 0000-02-28 23:59:59.9999 +0000-12-31 23:59:59.999999 0000-12-31 23:59:59.9999 +0001-01-01 00:00:00.999999 0001-01-01 00:00:00.9999 +0001-02-28 23:59:59.999999 0001-02-28 23:59:59.9999 +0001-12-31 23:59:59.999999 0001-12-31 23:59:59.9999 +0004-02-28 23:59:59.999999 0004-02-28 23:59:59.9999 +0004-02-29 23:59:59.999999 0004-02-29 23:59:59.9999 +2000-02-29 23:59:59.999999 2000-02-29 23:59:59.9999 +2000-12-31 23:59:59.999999 2000-12-31 23:59:59.9999 +9999-12-31 23:59:59.999999 9999-12-31 23:59:59.9999 +SELECT a, TRUNCATE(a,5) FROM t1; +a TRUNCATE(a,5) +0000-00-00 00:00:00.999999 0000-00-00 00:00:00.99999 +0000-00-00 23:59:59.999999 0000-00-00 23:59:59.99999 +0000-00-01 00:00:00.999999 0000-00-01 00:00:00.99999 +0000-00-01 23:59:59.999999 0000-00-01 23:59:59.99999 +0000-00-31 23:59:59.999999 0000-00-31 23:59:59.99999 +0000-01-01 00:00:00.999999 0000-01-01 00:00:00.99999 +0000-01-01 23:59:59.999999 0000-01-01 23:59:59.99999 +0000-01-31 23:59:59.999999 0000-01-31 23:59:59.99999 +0000-02-28 23:59:59.999999 0000-02-28 23:59:59.99999 +0000-12-31 23:59:59.999999 0000-12-31 23:59:59.99999 +0001-01-01 00:00:00.999999 0001-01-01 00:00:00.99999 +0001-02-28 23:59:59.999999 0001-02-28 23:59:59.99999 +0001-12-31 23:59:59.999999 0001-12-31 23:59:59.99999 +0004-02-28 23:59:59.999999 0004-02-28 23:59:59.99999 +0004-02-29 23:59:59.999999 0004-02-29 23:59:59.99999 +2000-02-29 23:59:59.999999 2000-02-29 23:59:59.99999 +2000-12-31 23:59:59.999999 2000-12-31 23:59:59.99999 +9999-12-31 23:59:59.999999 9999-12-31 23:59:59.99999 +SELECT a, TRUNCATE(a,6) FROM t1; +a TRUNCATE(a,6) +0000-00-00 00:00:00.999999 0000-00-00 00:00:00.999999 +0000-00-00 23:59:59.999999 0000-00-00 23:59:59.999999 +0000-00-01 00:00:00.999999 0000-00-01 00:00:00.999999 +0000-00-01 23:59:59.999999 0000-00-01 23:59:59.999999 +0000-00-31 23:59:59.999999 0000-00-31 23:59:59.999999 +0000-01-01 00:00:00.999999 0000-01-01 00:00:00.999999 +0000-01-01 23:59:59.999999 0000-01-01 23:59:59.999999 +0000-01-31 23:59:59.999999 0000-01-31 23:59:59.999999 +0000-02-28 23:59:59.999999 0000-02-28 23:59:59.999999 +0000-12-31 23:59:59.999999 0000-12-31 23:59:59.999999 +0001-01-01 00:00:00.999999 0001-01-01 00:00:00.999999 +0001-02-28 23:59:59.999999 0001-02-28 23:59:59.999999 +0001-12-31 23:59:59.999999 0001-12-31 23:59:59.999999 +0004-02-28 23:59:59.999999 0004-02-28 23:59:59.999999 +0004-02-29 23:59:59.999999 0004-02-29 23:59:59.999999 +2000-02-29 23:59:59.999999 2000-02-29 23:59:59.999999 +2000-12-31 23:59:59.999999 2000-12-31 23:59:59.999999 +9999-12-31 23:59:59.999999 9999-12-31 23:59:59.999999 +SELECT a, TRUNCATE(a,7) FROM t1; +a TRUNCATE(a,7) +0000-00-00 00:00:00.999999 0000-00-00 00:00:00.999999 +0000-00-00 23:59:59.999999 0000-00-00 23:59:59.999999 +0000-00-01 00:00:00.999999 0000-00-01 00:00:00.999999 +0000-00-01 23:59:59.999999 0000-00-01 23:59:59.999999 +0000-00-31 23:59:59.999999 0000-00-31 23:59:59.999999 +0000-01-01 00:00:00.999999 0000-01-01 00:00:00.999999 +0000-01-01 23:59:59.999999 0000-01-01 23:59:59.999999 +0000-01-31 23:59:59.999999 0000-01-31 23:59:59.999999 +0000-02-28 23:59:59.999999 0000-02-28 23:59:59.999999 +0000-12-31 23:59:59.999999 0000-12-31 23:59:59.999999 +0001-01-01 00:00:00.999999 0001-01-01 00:00:00.999999 +0001-02-28 23:59:59.999999 0001-02-28 23:59:59.999999 +0001-12-31 23:59:59.999999 0001-12-31 23:59:59.999999 +0004-02-28 23:59:59.999999 0004-02-28 23:59:59.999999 +0004-02-29 23:59:59.999999 0004-02-29 23:59:59.999999 +2000-02-29 23:59:59.999999 2000-02-29 23:59:59.999999 +2000-12-31 23:59:59.999999 2000-12-31 23:59:59.999999 +9999-12-31 23:59:59.999999 9999-12-31 23:59:59.999999 +SELECT a, TRUNCATE(a,-1) FROM t1; +a TRUNCATE(a,-1) +0000-00-00 00:00:00.999999 0000-00-00 00:00:00 +0000-00-00 23:59:59.999999 0000-00-00 23:59:59 +0000-00-01 00:00:00.999999 0000-00-01 00:00:00 +0000-00-01 23:59:59.999999 0000-00-01 23:59:59 +0000-00-31 23:59:59.999999 0000-00-31 23:59:59 +0000-01-01 00:00:00.999999 0000-01-01 00:00:00 +0000-01-01 23:59:59.999999 0000-01-01 23:59:59 +0000-01-31 23:59:59.999999 0000-01-31 23:59:59 +0000-02-28 23:59:59.999999 0000-02-28 23:59:59 +0000-12-31 23:59:59.999999 0000-12-31 23:59:59 +0001-01-01 00:00:00.999999 0001-01-01 00:00:00 +0001-02-28 23:59:59.999999 0001-02-28 23:59:59 +0001-12-31 23:59:59.999999 0001-12-31 23:59:59 +0004-02-28 23:59:59.999999 0004-02-28 23:59:59 +0004-02-29 23:59:59.999999 0004-02-29 23:59:59 +2000-02-29 23:59:59.999999 2000-02-29 23:59:59 +2000-12-31 23:59:59.999999 2000-12-31 23:59:59 +9999-12-31 23:59:59.999999 9999-12-31 23:59:59 +SELECT a, TRUNCATE(a,-6) FROM t1; +a TRUNCATE(a,-6) +0000-00-00 00:00:00.999999 0000-00-00 00:00:00 +0000-00-00 23:59:59.999999 0000-00-00 23:59:59 +0000-00-01 00:00:00.999999 0000-00-01 00:00:00 +0000-00-01 23:59:59.999999 0000-00-01 23:59:59 +0000-00-31 23:59:59.999999 0000-00-31 23:59:59 +0000-01-01 00:00:00.999999 0000-01-01 00:00:00 +0000-01-01 23:59:59.999999 0000-01-01 23:59:59 +0000-01-31 23:59:59.999999 0000-01-31 23:59:59 +0000-02-28 23:59:59.999999 0000-02-28 23:59:59 +0000-12-31 23:59:59.999999 0000-12-31 23:59:59 +0001-01-01 00:00:00.999999 0001-01-01 00:00:00 +0001-02-28 23:59:59.999999 0001-02-28 23:59:59 +0001-12-31 23:59:59.999999 0001-12-31 23:59:59 +0004-02-28 23:59:59.999999 0004-02-28 23:59:59 +0004-02-29 23:59:59.999999 0004-02-29 23:59:59 +2000-02-29 23:59:59.999999 2000-02-29 23:59:59 +2000-12-31 23:59:59.999999 2000-12-31 23:59:59 +9999-12-31 23:59:59.999999 9999-12-31 23:59:59 +SELECT a, ROUND(a) FROM t1; +a ROUND(a) +0000-00-00 00:00:00.999999 0000-00-00 00:00:01 +0000-00-00 23:59:59.999999 NULL +0000-00-01 00:00:00.999999 0000-00-01 00:00:01 +0000-00-01 23:59:59.999999 NULL +0000-00-31 23:59:59.999999 NULL +0000-01-01 00:00:00.999999 0000-01-01 00:00:01 +0000-01-01 23:59:59.999999 NULL +0000-01-31 23:59:59.999999 NULL +0000-02-28 23:59:59.999999 NULL +0000-12-31 23:59:59.999999 NULL +0001-01-01 00:00:00.999999 0001-01-01 00:00:01 +0001-02-28 23:59:59.999999 0001-03-01 00:00:00 +0001-12-31 23:59:59.999999 0002-01-01 00:00:00 +0004-02-28 23:59:59.999999 0004-02-29 00:00:00 +0004-02-29 23:59:59.999999 0004-03-01 00:00:00 +2000-02-29 23:59:59.999999 2000-03-01 00:00:00 +2000-12-31 23:59:59.999999 2001-01-01 00:00:00 +9999-12-31 23:59:59.999999 9999-12-31 23:59:59 +Warnings: +Warning 1411 Incorrect date value: '0000-00-00' for function round(datetime) +Warning 1411 Incorrect date value: '0000-00-01' for function round(datetime) +Warning 1411 Incorrect date value: '0000-00-31' for function round(datetime) +Warning 1411 Incorrect date value: '0000-01-01' for function round(datetime) +Warning 1411 Incorrect date value: '0000-01-31' for function round(datetime) +Warning 1411 Incorrect date value: '0000-02-28' for function round(datetime) +Warning 1411 Incorrect date value: '0000-12-31' for function round(datetime) +SELECT a, ROUND(a,0) FROM t1; +a ROUND(a,0) +0000-00-00 00:00:00.999999 0000-00-00 00:00:01 +0000-00-00 23:59:59.999999 NULL +0000-00-01 00:00:00.999999 0000-00-01 00:00:01 +0000-00-01 23:59:59.999999 NULL +0000-00-31 23:59:59.999999 NULL +0000-01-01 00:00:00.999999 0000-01-01 00:00:01 +0000-01-01 23:59:59.999999 NULL +0000-01-31 23:59:59.999999 NULL +0000-02-28 23:59:59.999999 NULL +0000-12-31 23:59:59.999999 NULL +0001-01-01 00:00:00.999999 0001-01-01 00:00:01 +0001-02-28 23:59:59.999999 0001-03-01 00:00:00 +0001-12-31 23:59:59.999999 0002-01-01 00:00:00 +0004-02-28 23:59:59.999999 0004-02-29 00:00:00 +0004-02-29 23:59:59.999999 0004-03-01 00:00:00 +2000-02-29 23:59:59.999999 2000-03-01 00:00:00 +2000-12-31 23:59:59.999999 2001-01-01 00:00:00 +9999-12-31 23:59:59.999999 9999-12-31 23:59:59 +Warnings: +Warning 1411 Incorrect date value: '0000-00-00' for function round(datetime) +Warning 1411 Incorrect date value: '0000-00-01' for function round(datetime) +Warning 1411 Incorrect date value: '0000-00-31' for function round(datetime) +Warning 1411 Incorrect date value: '0000-01-01' for function round(datetime) +Warning 1411 Incorrect date value: '0000-01-31' for function round(datetime) +Warning 1411 Incorrect date value: '0000-02-28' for function round(datetime) +Warning 1411 Incorrect date value: '0000-12-31' for function round(datetime) +SELECT a, ROUND(a,1) FROM t1; +a ROUND(a,1) +0000-00-00 00:00:00.999999 0000-00-00 00:00:01.0 +0000-00-00 23:59:59.999999 NULL +0000-00-01 00:00:00.999999 0000-00-01 00:00:01.0 +0000-00-01 23:59:59.999999 NULL +0000-00-31 23:59:59.999999 NULL +0000-01-01 00:00:00.999999 0000-01-01 00:00:01.0 +0000-01-01 23:59:59.999999 NULL +0000-01-31 23:59:59.999999 NULL +0000-02-28 23:59:59.999999 NULL +0000-12-31 23:59:59.999999 NULL +0001-01-01 00:00:00.999999 0001-01-01 00:00:01.0 +0001-02-28 23:59:59.999999 0001-03-01 00:00:00.0 +0001-12-31 23:59:59.999999 0002-01-01 00:00:00.0 +0004-02-28 23:59:59.999999 0004-02-29 00:00:00.0 +0004-02-29 23:59:59.999999 0004-03-01 00:00:00.0 +2000-02-29 23:59:59.999999 2000-03-01 00:00:00.0 +2000-12-31 23:59:59.999999 2001-01-01 00:00:00.0 +9999-12-31 23:59:59.999999 9999-12-31 23:59:59.9 +Warnings: +Warning 1411 Incorrect date value: '0000-00-00' for function round(datetime) +Warning 1411 Incorrect date value: '0000-00-01' for function round(datetime) +Warning 1411 Incorrect date value: '0000-00-31' for function round(datetime) +Warning 1411 Incorrect date value: '0000-01-01' for function round(datetime) +Warning 1411 Incorrect date value: '0000-01-31' for function round(datetime) +Warning 1411 Incorrect date value: '0000-02-28' for function round(datetime) +Warning 1411 Incorrect date value: '0000-12-31' for function round(datetime) +SELECT a, ROUND(a,2) FROM t1; +a ROUND(a,2) +0000-00-00 00:00:00.999999 0000-00-00 00:00:01.00 +0000-00-00 23:59:59.999999 NULL +0000-00-01 00:00:00.999999 0000-00-01 00:00:01.00 +0000-00-01 23:59:59.999999 NULL +0000-00-31 23:59:59.999999 NULL +0000-01-01 00:00:00.999999 0000-01-01 00:00:01.00 +0000-01-01 23:59:59.999999 NULL +0000-01-31 23:59:59.999999 NULL +0000-02-28 23:59:59.999999 NULL +0000-12-31 23:59:59.999999 NULL +0001-01-01 00:00:00.999999 0001-01-01 00:00:01.00 +0001-02-28 23:59:59.999999 0001-03-01 00:00:00.00 +0001-12-31 23:59:59.999999 0002-01-01 00:00:00.00 +0004-02-28 23:59:59.999999 0004-02-29 00:00:00.00 +0004-02-29 23:59:59.999999 0004-03-01 00:00:00.00 +2000-02-29 23:59:59.999999 2000-03-01 00:00:00.00 +2000-12-31 23:59:59.999999 2001-01-01 00:00:00.00 +9999-12-31 23:59:59.999999 9999-12-31 23:59:59.99 +Warnings: +Warning 1411 Incorrect date value: '0000-00-00' for function round(datetime) +Warning 1411 Incorrect date value: '0000-00-01' for function round(datetime) +Warning 1411 Incorrect date value: '0000-00-31' for function round(datetime) +Warning 1411 Incorrect date value: '0000-01-01' for function round(datetime) +Warning 1411 Incorrect date value: '0000-01-31' for function round(datetime) +Warning 1411 Incorrect date value: '0000-02-28' for function round(datetime) +Warning 1411 Incorrect date value: '0000-12-31' for function round(datetime) +SELECT a, ROUND(a,3) FROM t1; +a ROUND(a,3) +0000-00-00 00:00:00.999999 0000-00-00 00:00:01.000 +0000-00-00 23:59:59.999999 NULL +0000-00-01 00:00:00.999999 0000-00-01 00:00:01.000 +0000-00-01 23:59:59.999999 NULL +0000-00-31 23:59:59.999999 NULL +0000-01-01 00:00:00.999999 0000-01-01 00:00:01.000 +0000-01-01 23:59:59.999999 NULL +0000-01-31 23:59:59.999999 NULL +0000-02-28 23:59:59.999999 NULL +0000-12-31 23:59:59.999999 NULL +0001-01-01 00:00:00.999999 0001-01-01 00:00:01.000 +0001-02-28 23:59:59.999999 0001-03-01 00:00:00.000 +0001-12-31 23:59:59.999999 0002-01-01 00:00:00.000 +0004-02-28 23:59:59.999999 0004-02-29 00:00:00.000 +0004-02-29 23:59:59.999999 0004-03-01 00:00:00.000 +2000-02-29 23:59:59.999999 2000-03-01 00:00:00.000 +2000-12-31 23:59:59.999999 2001-01-01 00:00:00.000 +9999-12-31 23:59:59.999999 9999-12-31 23:59:59.999 +Warnings: +Warning 1411 Incorrect date value: '0000-00-00' for function round(datetime) +Warning 1411 Incorrect date value: '0000-00-01' for function round(datetime) +Warning 1411 Incorrect date value: '0000-00-31' for function round(datetime) +Warning 1411 Incorrect date value: '0000-01-01' for function round(datetime) +Warning 1411 Incorrect date value: '0000-01-31' for function round(datetime) +Warning 1411 Incorrect date value: '0000-02-28' for function round(datetime) +Warning 1411 Incorrect date value: '0000-12-31' for function round(datetime) +SELECT a, ROUND(a,4) FROM t1; +a ROUND(a,4) +0000-00-00 00:00:00.999999 0000-00-00 00:00:01.0000 +0000-00-00 23:59:59.999999 NULL +0000-00-01 00:00:00.999999 0000-00-01 00:00:01.0000 +0000-00-01 23:59:59.999999 NULL +0000-00-31 23:59:59.999999 NULL +0000-01-01 00:00:00.999999 0000-01-01 00:00:01.0000 +0000-01-01 23:59:59.999999 NULL +0000-01-31 23:59:59.999999 NULL +0000-02-28 23:59:59.999999 NULL +0000-12-31 23:59:59.999999 NULL +0001-01-01 00:00:00.999999 0001-01-01 00:00:01.0000 +0001-02-28 23:59:59.999999 0001-03-01 00:00:00.0000 +0001-12-31 23:59:59.999999 0002-01-01 00:00:00.0000 +0004-02-28 23:59:59.999999 0004-02-29 00:00:00.0000 +0004-02-29 23:59:59.999999 0004-03-01 00:00:00.0000 +2000-02-29 23:59:59.999999 2000-03-01 00:00:00.0000 +2000-12-31 23:59:59.999999 2001-01-01 00:00:00.0000 +9999-12-31 23:59:59.999999 9999-12-31 23:59:59.9999 +Warnings: +Warning 1411 Incorrect date value: '0000-00-00' for function round(datetime) +Warning 1411 Incorrect date value: '0000-00-01' for function round(datetime) +Warning 1411 Incorrect date value: '0000-00-31' for function round(datetime) +Warning 1411 Incorrect date value: '0000-01-01' for function round(datetime) +Warning 1411 Incorrect date value: '0000-01-31' for function round(datetime) +Warning 1411 Incorrect date value: '0000-02-28' for function round(datetime) +Warning 1411 Incorrect date value: '0000-12-31' for function round(datetime) +SELECT a, ROUND(a,5) FROM t1; +a ROUND(a,5) +0000-00-00 00:00:00.999999 0000-00-00 00:00:01.00000 +0000-00-00 23:59:59.999999 NULL +0000-00-01 00:00:00.999999 0000-00-01 00:00:01.00000 +0000-00-01 23:59:59.999999 NULL +0000-00-31 23:59:59.999999 NULL +0000-01-01 00:00:00.999999 0000-01-01 00:00:01.00000 +0000-01-01 23:59:59.999999 NULL +0000-01-31 23:59:59.999999 NULL +0000-02-28 23:59:59.999999 NULL +0000-12-31 23:59:59.999999 NULL +0001-01-01 00:00:00.999999 0001-01-01 00:00:01.00000 +0001-02-28 23:59:59.999999 0001-03-01 00:00:00.00000 +0001-12-31 23:59:59.999999 0002-01-01 00:00:00.00000 +0004-02-28 23:59:59.999999 0004-02-29 00:00:00.00000 +0004-02-29 23:59:59.999999 0004-03-01 00:00:00.00000 +2000-02-29 23:59:59.999999 2000-03-01 00:00:00.00000 +2000-12-31 23:59:59.999999 2001-01-01 00:00:00.00000 +9999-12-31 23:59:59.999999 9999-12-31 23:59:59.99999 +Warnings: +Warning 1411 Incorrect date value: '0000-00-00' for function round(datetime) +Warning 1411 Incorrect date value: '0000-00-01' for function round(datetime) +Warning 1411 Incorrect date value: '0000-00-31' for function round(datetime) +Warning 1411 Incorrect date value: '0000-01-01' for function round(datetime) +Warning 1411 Incorrect date value: '0000-01-31' for function round(datetime) +Warning 1411 Incorrect date value: '0000-02-28' for function round(datetime) +Warning 1411 Incorrect date value: '0000-12-31' for function round(datetime) +SELECT a, ROUND(a,6) FROM t1; +a ROUND(a,6) +0000-00-00 00:00:00.999999 0000-00-00 00:00:00.999999 +0000-00-00 23:59:59.999999 0000-00-00 23:59:59.999999 +0000-00-01 00:00:00.999999 0000-00-01 00:00:00.999999 +0000-00-01 23:59:59.999999 0000-00-01 23:59:59.999999 +0000-00-31 23:59:59.999999 0000-00-31 23:59:59.999999 +0000-01-01 00:00:00.999999 0000-01-01 00:00:00.999999 +0000-01-01 23:59:59.999999 0000-01-01 23:59:59.999999 +0000-01-31 23:59:59.999999 0000-01-31 23:59:59.999999 +0000-02-28 23:59:59.999999 0000-02-28 23:59:59.999999 +0000-12-31 23:59:59.999999 0000-12-31 23:59:59.999999 +0001-01-01 00:00:00.999999 0001-01-01 00:00:00.999999 +0001-02-28 23:59:59.999999 0001-02-28 23:59:59.999999 +0001-12-31 23:59:59.999999 0001-12-31 23:59:59.999999 +0004-02-28 23:59:59.999999 0004-02-28 23:59:59.999999 +0004-02-29 23:59:59.999999 0004-02-29 23:59:59.999999 +2000-02-29 23:59:59.999999 2000-02-29 23:59:59.999999 +2000-12-31 23:59:59.999999 2000-12-31 23:59:59.999999 +9999-12-31 23:59:59.999999 9999-12-31 23:59:59.999999 +SELECT a, ROUND(a,7) FROM t1; +a ROUND(a,7) +0000-00-00 00:00:00.999999 0000-00-00 00:00:00.999999 +0000-00-00 23:59:59.999999 0000-00-00 23:59:59.999999 +0000-00-01 00:00:00.999999 0000-00-01 00:00:00.999999 +0000-00-01 23:59:59.999999 0000-00-01 23:59:59.999999 +0000-00-31 23:59:59.999999 0000-00-31 23:59:59.999999 +0000-01-01 00:00:00.999999 0000-01-01 00:00:00.999999 +0000-01-01 23:59:59.999999 0000-01-01 23:59:59.999999 +0000-01-31 23:59:59.999999 0000-01-31 23:59:59.999999 +0000-02-28 23:59:59.999999 0000-02-28 23:59:59.999999 +0000-12-31 23:59:59.999999 0000-12-31 23:59:59.999999 +0001-01-01 00:00:00.999999 0001-01-01 00:00:00.999999 +0001-02-28 23:59:59.999999 0001-02-28 23:59:59.999999 +0001-12-31 23:59:59.999999 0001-12-31 23:59:59.999999 +0004-02-28 23:59:59.999999 0004-02-28 23:59:59.999999 +0004-02-29 23:59:59.999999 0004-02-29 23:59:59.999999 +2000-02-29 23:59:59.999999 2000-02-29 23:59:59.999999 +2000-12-31 23:59:59.999999 2000-12-31 23:59:59.999999 +9999-12-31 23:59:59.999999 9999-12-31 23:59:59.999999 +SELECT a, ROUND(a,-1) FROM t1; +a ROUND(a,-1) +0000-00-00 00:00:00.999999 0000-00-00 00:00:01 +0000-00-00 23:59:59.999999 NULL +0000-00-01 00:00:00.999999 0000-00-01 00:00:01 +0000-00-01 23:59:59.999999 NULL +0000-00-31 23:59:59.999999 NULL +0000-01-01 00:00:00.999999 0000-01-01 00:00:01 +0000-01-01 23:59:59.999999 NULL +0000-01-31 23:59:59.999999 NULL +0000-02-28 23:59:59.999999 NULL +0000-12-31 23:59:59.999999 NULL +0001-01-01 00:00:00.999999 0001-01-01 00:00:01 +0001-02-28 23:59:59.999999 0001-03-01 00:00:00 +0001-12-31 23:59:59.999999 0002-01-01 00:00:00 +0004-02-28 23:59:59.999999 0004-02-29 00:00:00 +0004-02-29 23:59:59.999999 0004-03-01 00:00:00 +2000-02-29 23:59:59.999999 2000-03-01 00:00:00 +2000-12-31 23:59:59.999999 2001-01-01 00:00:00 +9999-12-31 23:59:59.999999 9999-12-31 23:59:59 +Warnings: +Warning 1411 Incorrect date value: '0000-00-00' for function round(datetime) +Warning 1411 Incorrect date value: '0000-00-01' for function round(datetime) +Warning 1411 Incorrect date value: '0000-00-31' for function round(datetime) +Warning 1411 Incorrect date value: '0000-01-01' for function round(datetime) +Warning 1411 Incorrect date value: '0000-01-31' for function round(datetime) +Warning 1411 Incorrect date value: '0000-02-28' for function round(datetime) +Warning 1411 Incorrect date value: '0000-12-31' for function round(datetime) +SELECT a, ROUND(a,-6) FROM t1; +a ROUND(a,-6) +0000-00-00 00:00:00.999999 0000-00-00 00:00:01 +0000-00-00 23:59:59.999999 NULL +0000-00-01 00:00:00.999999 0000-00-01 00:00:01 +0000-00-01 23:59:59.999999 NULL +0000-00-31 23:59:59.999999 NULL +0000-01-01 00:00:00.999999 0000-01-01 00:00:01 +0000-01-01 23:59:59.999999 NULL +0000-01-31 23:59:59.999999 NULL +0000-02-28 23:59:59.999999 NULL +0000-12-31 23:59:59.999999 NULL +0001-01-01 00:00:00.999999 0001-01-01 00:00:01 +0001-02-28 23:59:59.999999 0001-03-01 00:00:00 +0001-12-31 23:59:59.999999 0002-01-01 00:00:00 +0004-02-28 23:59:59.999999 0004-02-29 00:00:00 +0004-02-29 23:59:59.999999 0004-03-01 00:00:00 +2000-02-29 23:59:59.999999 2000-03-01 00:00:00 +2000-12-31 23:59:59.999999 2001-01-01 00:00:00 +9999-12-31 23:59:59.999999 9999-12-31 23:59:59 +Warnings: +Warning 1411 Incorrect date value: '0000-00-00' for function round(datetime) +Warning 1411 Incorrect date value: '0000-00-01' for function round(datetime) +Warning 1411 Incorrect date value: '0000-00-31' for function round(datetime) +Warning 1411 Incorrect date value: '0000-01-01' for function round(datetime) +Warning 1411 Incorrect date value: '0000-01-31' for function round(datetime) +Warning 1411 Incorrect date value: '0000-02-28' for function round(datetime) +Warning 1411 Incorrect date value: '0000-12-31' for function round(datetime) +DROP TABLE t1; +# +# End of 10.4 tests +# diff --git a/mysql-test/main/type_datetime_hires.test b/mysql-test/main/type_datetime_hires.test index d220a4601eb..ed9a85bcda3 100644 --- a/mysql-test/main/type_datetime_hires.test +++ b/mysql-test/main/type_datetime_hires.test @@ -79,3 +79,73 @@ INSERT INTO t1 VALUES ('2001-01-01 00:00:00'),('2000-00-00 00:00:00'); SELECT UNIX_TIMESTAMP(a) FROM t1 ORDER BY 1; DROP TABLE t1; SET @@time_zone=DEFAULT; + + +--echo # +--echo # Start of 10.4 tests +--echo # + +--echo # +--echo # MDEV-20397 Support TIMESTAMP, DATETIME, TIME in ROUND() and TRUNCATE() +--echo # + +CREATE TABLE t1 (a1 DATETIME(6), a2 DATETIME(6) NOT NULL); +CREATE TABLE t2 AS SELECT + ROUND(a1) AS r1, + ROUND(a2) AS r2, + TRUNCATE(a1,0) AS t1, + TRUNCATE(a2,0) AS t2 +FROM t1; +SHOW CREATE TABLE t2; +DROP TABLE t2; +DROP TABLE t1; + + +CREATE TABLE t1 (a DATETIME(6)); +INSERT INTO t1 VALUES +('0000-00-00 00:00:00.999999'), +('0000-00-00 23:59:59.999999'), +('0000-00-01 00:00:00.999999'), +('0000-00-01 23:59:59.999999'), +('0000-00-31 23:59:59.999999'), +('0000-01-01 00:00:00.999999'), +('0000-01-01 23:59:59.999999'), +('0000-01-31 23:59:59.999999'), +('0000-02-28 23:59:59.999999'), +('0000-12-31 23:59:59.999999'), +('0001-01-01 00:00:00.999999'), +('0001-02-28 23:59:59.999999'), +('0001-12-31 23:59:59.999999'), +('0004-02-28 23:59:59.999999'), +('0004-02-29 23:59:59.999999'), +('2000-02-29 23:59:59.999999'), +('2000-12-31 23:59:59.999999'), +('9999-12-31 23:59:59.999999'); +SELECT a, TRUNCATE(a,0) FROM t1; +SELECT a, TRUNCATE(a,1) FROM t1; +SELECT a, TRUNCATE(a,2) FROM t1; +SELECT a, TRUNCATE(a,3) FROM t1; +SELECT a, TRUNCATE(a,4) FROM t1; +SELECT a, TRUNCATE(a,5) FROM t1; +SELECT a, TRUNCATE(a,6) FROM t1; +SELECT a, TRUNCATE(a,7) FROM t1; +SELECT a, TRUNCATE(a,-1) FROM t1; +SELECT a, TRUNCATE(a,-6) FROM t1; + +SELECT a, ROUND(a) FROM t1; +SELECT a, ROUND(a,0) FROM t1; +SELECT a, ROUND(a,1) FROM t1; +SELECT a, ROUND(a,2) FROM t1; +SELECT a, ROUND(a,3) FROM t1; +SELECT a, ROUND(a,4) FROM t1; +SELECT a, ROUND(a,5) FROM t1; +SELECT a, ROUND(a,6) FROM t1; +SELECT a, ROUND(a,7) FROM t1; +SELECT a, ROUND(a,-1) FROM t1; +SELECT a, ROUND(a,-6) FROM t1; + +DROP TABLE t1; + +--echo # +--echo # End of 10.4 tests +--echo # diff --git a/mysql-test/main/type_time_hires.result b/mysql-test/main/type_time_hires.result index ca19e9ed5bf..6122afcfc47 100644 --- a/mysql-test/main/type_time_hires.result +++ b/mysql-test/main/type_time_hires.result @@ -25,8 +25,8 @@ a 03:04:05.789 15:47:11.123 838:59:59.999 -select truncate(a, 6) from t1; -truncate(a, 6) +select cast(a AS double(30,6)) from t1; +cast(a AS double(30,6)) 2003.123000 10203.456000 30405.789062 @@ -359,3 +359,314 @@ drop table t1; select cast(1e-6 as time(6)); cast(1e-6 as time(6)) 00:00:00.000001 +# +# Start of 10.4 tests +# +# +# MDEV-20397 Support TIMESTAMP, DATETIME, TIME in ROUND() and TRUNCATE() +# +CREATE TABLE t1 (a1 TIME(6), a2 TIME(6) NOT NULL); +CREATE TABLE t2 AS SELECT +ROUND(a1) AS r1, +ROUND(a2) AS r2, +TRUNCATE(a1,0) AS t1, +TRUNCATE(a2,0) AS t2 +FROM t1; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `r1` time DEFAULT NULL, + `r2` time NOT NULL, + `t1` time DEFAULT NULL, + `t2` time NOT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t2; +DROP TABLE t1; +CREATE TABLE t1 (a TIME(6)); +INSERT INTO t1 VALUES +('-838:59:59.999999'), +('-837:59:59.999999'), +('-23:59:59.999999'), +('-00:59:59.999999'), +('-00:00:59.999999'), +('00:00:00.999999'), +('00:00:59.999999'), +('00:59:59.999999'), +('23:59:59.999999'), +('837:59:59.999999'), +('838:59:59.999999'); +SELECT a, TRUNCATE(a,0) FROM t1; +a TRUNCATE(a,0) +-838:59:59.999999 -838:59:59 +-837:59:59.999999 -837:59:59 +-23:59:59.999999 -23:59:59 +-00:59:59.999999 -00:59:59 +-00:00:59.999999 -00:00:59 +00:00:00.999999 00:00:00 +00:00:59.999999 00:00:59 +00:59:59.999999 00:59:59 +23:59:59.999999 23:59:59 +837:59:59.999999 837:59:59 +838:59:59.999999 838:59:59 +SELECT a, TRUNCATE(a,1) FROM t1; +a TRUNCATE(a,1) +-838:59:59.999999 -838:59:59.9 +-837:59:59.999999 -837:59:59.9 +-23:59:59.999999 -23:59:59.9 +-00:59:59.999999 -00:59:59.9 +-00:00:59.999999 -00:00:59.9 +00:00:00.999999 00:00:00.9 +00:00:59.999999 00:00:59.9 +00:59:59.999999 00:59:59.9 +23:59:59.999999 23:59:59.9 +837:59:59.999999 837:59:59.9 +838:59:59.999999 838:59:59.9 +SELECT a, TRUNCATE(a,2) FROM t1; +a TRUNCATE(a,2) +-838:59:59.999999 -838:59:59.99 +-837:59:59.999999 -837:59:59.99 +-23:59:59.999999 -23:59:59.99 +-00:59:59.999999 -00:59:59.99 +-00:00:59.999999 -00:00:59.99 +00:00:00.999999 00:00:00.99 +00:00:59.999999 00:00:59.99 +00:59:59.999999 00:59:59.99 +23:59:59.999999 23:59:59.99 +837:59:59.999999 837:59:59.99 +838:59:59.999999 838:59:59.99 +SELECT a, TRUNCATE(a,3) FROM t1; +a TRUNCATE(a,3) +-838:59:59.999999 -838:59:59.999 +-837:59:59.999999 -837:59:59.999 +-23:59:59.999999 -23:59:59.999 +-00:59:59.999999 -00:59:59.999 +-00:00:59.999999 -00:00:59.999 +00:00:00.999999 00:00:00.999 +00:00:59.999999 00:00:59.999 +00:59:59.999999 00:59:59.999 +23:59:59.999999 23:59:59.999 +837:59:59.999999 837:59:59.999 +838:59:59.999999 838:59:59.999 +SELECT a, TRUNCATE(a,4) FROM t1; +a TRUNCATE(a,4) +-838:59:59.999999 -838:59:59.9999 +-837:59:59.999999 -837:59:59.9999 +-23:59:59.999999 -23:59:59.9999 +-00:59:59.999999 -00:59:59.9999 +-00:00:59.999999 -00:00:59.9999 +00:00:00.999999 00:00:00.9999 +00:00:59.999999 00:00:59.9999 +00:59:59.999999 00:59:59.9999 +23:59:59.999999 23:59:59.9999 +837:59:59.999999 837:59:59.9999 +838:59:59.999999 838:59:59.9999 +SELECT a, TRUNCATE(a,5) FROM t1; +a TRUNCATE(a,5) +-838:59:59.999999 -838:59:59.99999 +-837:59:59.999999 -837:59:59.99999 +-23:59:59.999999 -23:59:59.99999 +-00:59:59.999999 -00:59:59.99999 +-00:00:59.999999 -00:00:59.99999 +00:00:00.999999 00:00:00.99999 +00:00:59.999999 00:00:59.99999 +00:59:59.999999 00:59:59.99999 +23:59:59.999999 23:59:59.99999 +837:59:59.999999 837:59:59.99999 +838:59:59.999999 838:59:59.99999 +SELECT a, TRUNCATE(a,6) FROM t1; +a TRUNCATE(a,6) +-838:59:59.999999 -838:59:59.999999 +-837:59:59.999999 -837:59:59.999999 +-23:59:59.999999 -23:59:59.999999 +-00:59:59.999999 -00:59:59.999999 +-00:00:59.999999 -00:00:59.999999 +00:00:00.999999 00:00:00.999999 +00:00:59.999999 00:00:59.999999 +00:59:59.999999 00:59:59.999999 +23:59:59.999999 23:59:59.999999 +837:59:59.999999 837:59:59.999999 +838:59:59.999999 838:59:59.999999 +SELECT a, TRUNCATE(a,7) FROM t1; +a TRUNCATE(a,7) +-838:59:59.999999 -838:59:59.999999 +-837:59:59.999999 -837:59:59.999999 +-23:59:59.999999 -23:59:59.999999 +-00:59:59.999999 -00:59:59.999999 +-00:00:59.999999 -00:00:59.999999 +00:00:00.999999 00:00:00.999999 +00:00:59.999999 00:00:59.999999 +00:59:59.999999 00:59:59.999999 +23:59:59.999999 23:59:59.999999 +837:59:59.999999 837:59:59.999999 +838:59:59.999999 838:59:59.999999 +SELECT a, TRUNCATE(a,-1) FROM t1; +a TRUNCATE(a,-1) +-838:59:59.999999 -838:59:59 +-837:59:59.999999 -837:59:59 +-23:59:59.999999 -23:59:59 +-00:59:59.999999 -00:59:59 +-00:00:59.999999 -00:00:59 +00:00:00.999999 00:00:00 +00:00:59.999999 00:00:59 +00:59:59.999999 00:59:59 +23:59:59.999999 23:59:59 +837:59:59.999999 837:59:59 +838:59:59.999999 838:59:59 +SELECT a, TRUNCATE(a,-6) FROM t1; +a TRUNCATE(a,-6) +-838:59:59.999999 -838:59:59 +-837:59:59.999999 -837:59:59 +-23:59:59.999999 -23:59:59 +-00:59:59.999999 -00:59:59 +-00:00:59.999999 -00:00:59 +00:00:00.999999 00:00:00 +00:00:59.999999 00:00:59 +00:59:59.999999 00:59:59 +23:59:59.999999 23:59:59 +837:59:59.999999 837:59:59 +838:59:59.999999 838:59:59 +SELECT a, ROUND(a) FROM t1; +a ROUND(a) +-838:59:59.999999 -838:59:59 +-837:59:59.999999 -838:00:00 +-23:59:59.999999 -24:00:00 +-00:59:59.999999 -01:00:00 +-00:00:59.999999 -00:01:00 +00:00:00.999999 00:00:01 +00:00:59.999999 00:01:00 +00:59:59.999999 01:00:00 +23:59:59.999999 24:00:00 +837:59:59.999999 838:00:00 +838:59:59.999999 838:59:59 +SELECT a, ROUND(a,0) FROM t1; +a ROUND(a,0) +-838:59:59.999999 -838:59:59 +-837:59:59.999999 -838:00:00 +-23:59:59.999999 -24:00:00 +-00:59:59.999999 -01:00:00 +-00:00:59.999999 -00:01:00 +00:00:00.999999 00:00:01 +00:00:59.999999 00:01:00 +00:59:59.999999 01:00:00 +23:59:59.999999 24:00:00 +837:59:59.999999 838:00:00 +838:59:59.999999 838:59:59 +SELECT a, ROUND(a,1) FROM t1; +a ROUND(a,1) +-838:59:59.999999 -838:59:59.9 +-837:59:59.999999 -838:00:00.0 +-23:59:59.999999 -24:00:00.0 +-00:59:59.999999 -01:00:00.0 +-00:00:59.999999 -00:01:00.0 +00:00:00.999999 00:00:01.0 +00:00:59.999999 00:01:00.0 +00:59:59.999999 01:00:00.0 +23:59:59.999999 24:00:00.0 +837:59:59.999999 838:00:00.0 +838:59:59.999999 838:59:59.9 +SELECT a, ROUND(a,2) FROM t1; +a ROUND(a,2) +-838:59:59.999999 -838:59:59.99 +-837:59:59.999999 -838:00:00.00 +-23:59:59.999999 -24:00:00.00 +-00:59:59.999999 -01:00:00.00 +-00:00:59.999999 -00:01:00.00 +00:00:00.999999 00:00:01.00 +00:00:59.999999 00:01:00.00 +00:59:59.999999 01:00:00.00 +23:59:59.999999 24:00:00.00 +837:59:59.999999 838:00:00.00 +838:59:59.999999 838:59:59.99 +SELECT a, ROUND(a,3) FROM t1; +a ROUND(a,3) +-838:59:59.999999 -838:59:59.999 +-837:59:59.999999 -838:00:00.000 +-23:59:59.999999 -24:00:00.000 +-00:59:59.999999 -01:00:00.000 +-00:00:59.999999 -00:01:00.000 +00:00:00.999999 00:00:01.000 +00:00:59.999999 00:01:00.000 +00:59:59.999999 01:00:00.000 +23:59:59.999999 24:00:00.000 +837:59:59.999999 838:00:00.000 +838:59:59.999999 838:59:59.999 +SELECT a, ROUND(a,4) FROM t1; +a ROUND(a,4) +-838:59:59.999999 -838:59:59.9999 +-837:59:59.999999 -838:00:00.0000 +-23:59:59.999999 -24:00:00.0000 +-00:59:59.999999 -01:00:00.0000 +-00:00:59.999999 -00:01:00.0000 +00:00:00.999999 00:00:01.0000 +00:00:59.999999 00:01:00.0000 +00:59:59.999999 01:00:00.0000 +23:59:59.999999 24:00:00.0000 +837:59:59.999999 838:00:00.0000 +838:59:59.999999 838:59:59.9999 +SELECT a, ROUND(a,5) FROM t1; +a ROUND(a,5) +-838:59:59.999999 -838:59:59.99999 +-837:59:59.999999 -838:00:00.00000 +-23:59:59.999999 -24:00:00.00000 +-00:59:59.999999 -01:00:00.00000 +-00:00:59.999999 -00:01:00.00000 +00:00:00.999999 00:00:01.00000 +00:00:59.999999 00:01:00.00000 +00:59:59.999999 01:00:00.00000 +23:59:59.999999 24:00:00.00000 +837:59:59.999999 838:00:00.00000 +838:59:59.999999 838:59:59.99999 +SELECT a, ROUND(a,6) FROM t1; +a ROUND(a,6) +-838:59:59.999999 -838:59:59.999999 +-837:59:59.999999 -837:59:59.999999 +-23:59:59.999999 -23:59:59.999999 +-00:59:59.999999 -00:59:59.999999 +-00:00:59.999999 -00:00:59.999999 +00:00:00.999999 00:00:00.999999 +00:00:59.999999 00:00:59.999999 +00:59:59.999999 00:59:59.999999 +23:59:59.999999 23:59:59.999999 +837:59:59.999999 837:59:59.999999 +838:59:59.999999 838:59:59.999999 +SELECT a, ROUND(a,7) FROM t1; +a ROUND(a,7) +-838:59:59.999999 -838:59:59.999999 +-837:59:59.999999 -837:59:59.999999 +-23:59:59.999999 -23:59:59.999999 +-00:59:59.999999 -00:59:59.999999 +-00:00:59.999999 -00:00:59.999999 +00:00:00.999999 00:00:00.999999 +00:00:59.999999 00:00:59.999999 +00:59:59.999999 00:59:59.999999 +23:59:59.999999 23:59:59.999999 +837:59:59.999999 837:59:59.999999 +838:59:59.999999 838:59:59.999999 +SELECT a, ROUND(a,-1) FROM t1; +a ROUND(a,-1) +-838:59:59.999999 -838:59:59 +-837:59:59.999999 -838:00:00 +-23:59:59.999999 -24:00:00 +-00:59:59.999999 -01:00:00 +-00:00:59.999999 -00:01:00 +00:00:00.999999 00:00:01 +00:00:59.999999 00:01:00 +00:59:59.999999 01:00:00 +23:59:59.999999 24:00:00 +837:59:59.999999 838:00:00 +838:59:59.999999 838:59:59 +SELECT a, ROUND(a,-6) FROM t1; +a ROUND(a,-6) +-838:59:59.999999 -838:59:59 +-837:59:59.999999 -838:00:00 +-23:59:59.999999 -24:00:00 +-00:59:59.999999 -01:00:00 +-00:00:59.999999 -00:01:00 +00:00:00.999999 00:00:01 +00:00:59.999999 00:01:00 +00:59:59.999999 01:00:00 +23:59:59.999999 24:00:00 +837:59:59.999999 838:00:00 +838:59:59.999999 838:59:59 +DROP TABLE t1; +SET time_zone=DEFAULT; diff --git a/mysql-test/main/type_time_hires.test b/mysql-test/main/type_time_hires.test index 3785a23f1eb..0949738e949 100644 --- a/mysql-test/main/type_time_hires.test +++ b/mysql-test/main/type_time_hires.test @@ -10,3 +10,66 @@ select min(a - interval 1 hour), max(a - interval 1 hour) from t1 where a < 0; drop table t1; select cast(1e-6 as time(6)); + + +--echo # +--echo # Start of 10.4 tests +--echo # + +--echo # +--echo # MDEV-20397 Support TIMESTAMP, DATETIME, TIME in ROUND() and TRUNCATE() +--echo # + +CREATE TABLE t1 (a1 TIME(6), a2 TIME(6) NOT NULL); +CREATE TABLE t2 AS SELECT + ROUND(a1) AS r1, + ROUND(a2) AS r2, + TRUNCATE(a1,0) AS t1, + TRUNCATE(a2,0) AS t2 +FROM t1; +SHOW CREATE TABLE t2; +DROP TABLE t2; +DROP TABLE t1; + + +CREATE TABLE t1 (a TIME(6)); +INSERT INTO t1 VALUES +('-838:59:59.999999'), +('-837:59:59.999999'), +('-23:59:59.999999'), +('-00:59:59.999999'), +('-00:00:59.999999'), +('00:00:00.999999'), +('00:00:59.999999'), +('00:59:59.999999'), +('23:59:59.999999'), +('837:59:59.999999'), +('838:59:59.999999'); + + +SELECT a, TRUNCATE(a,0) FROM t1; +SELECT a, TRUNCATE(a,1) FROM t1; +SELECT a, TRUNCATE(a,2) FROM t1; +SELECT a, TRUNCATE(a,3) FROM t1; +SELECT a, TRUNCATE(a,4) FROM t1; +SELECT a, TRUNCATE(a,5) FROM t1; +SELECT a, TRUNCATE(a,6) FROM t1; +SELECT a, TRUNCATE(a,7) FROM t1; +SELECT a, TRUNCATE(a,-1) FROM t1; +SELECT a, TRUNCATE(a,-6) FROM t1; + +SELECT a, ROUND(a) FROM t1; +SELECT a, ROUND(a,0) FROM t1; +SELECT a, ROUND(a,1) FROM t1; +SELECT a, ROUND(a,2) FROM t1; +SELECT a, ROUND(a,3) FROM t1; +SELECT a, ROUND(a,4) FROM t1; +SELECT a, ROUND(a,5) FROM t1; +SELECT a, ROUND(a,6) FROM t1; +SELECT a, ROUND(a,7) FROM t1; +SELECT a, ROUND(a,-1) FROM t1; +SELECT a, ROUND(a,-6) FROM t1; + +DROP TABLE t1; + +SET time_zone=DEFAULT; diff --git a/mysql-test/main/type_timestamp_hires.result b/mysql-test/main/type_timestamp_hires.result index fa6adc075ed..dc69aa36b0f 100644 --- a/mysql-test/main/type_timestamp_hires.result +++ b/mysql-test/main/type_timestamp_hires.result @@ -17,8 +17,8 @@ a 2010-12-11 01:02:03.456 2010-12-11 03:04:05.789 2010-12-11 15:47:11.123 -select truncate(a, 6) from t1; -truncate(a, 6) +select cast(a AS double(30,6)) from t1; +cast(a AS double(30,6)) 0.000000 20101211002003.120000 20101211010203.457031 @@ -333,3 +333,298 @@ t1 CREATE TABLE `t1` ( `a` timestamp(5) NOT NULL DEFAULT '0000-00-00 00:00:00.00000' ON UPDATE current_timestamp(5) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +# +# Start of 10.4 tests +# +# +# MDEV-20397 Support TIMESTAMP, DATETIME, TIME in ROUND() and TRUNCATE() +# +# ROUND(timestamp) and TRUNCATE(timestamp) currently return DATETIME. +# This may change in the future to return TIMESTAMP. +CREATE TABLE t1 (a1 TIMESTAMP(6) NULL DEFAULT '2001-01-01 00:00:00', a2 TIMESTAMP(6) NOT NULL); +CREATE TABLE t2 AS SELECT +ROUND(a1) AS r1, +ROUND(a2) AS r2, +TRUNCATE(a1,0) AS t1, +TRUNCATE(a2,0) AS t2 +FROM t1; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `r1` datetime DEFAULT NULL, + `r2` datetime DEFAULT NULL, + `t1` datetime DEFAULT NULL, + `t2` datetime NOT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t2; +DROP TABLE t1; +SET time_zone='+00:00'; +CREATE TABLE t1 (a TIMESTAMP(6)); +INSERT INTO t1 VALUES +('1970-01-01 00:00:01.999999'), +('2000-01-01 00:00:00.999999'), +('2000-01-01 23:59:59.999999'), +('2000-02-29 23:59:59.999999'), +('2000-12-31 23:59:59.999999'), +('2001-01-01 00:00:00.999999'), +('2001-01-01 23:59:59.999999'), +('2001-02-28 23:59:59.999999'), +('2001-12-31 23:59:59.999999'), +('2038-01-19 03:14:07.999999'); +SELECT a, TRUNCATE(a,0) FROM t1; +a TRUNCATE(a,0) +1970-01-01 00:00:01.999999 1970-01-01 00:00:01 +2000-01-01 00:00:00.999999 2000-01-01 00:00:00 +2000-01-01 23:59:59.999999 2000-01-01 23:59:59 +2000-02-29 23:59:59.999999 2000-02-29 23:59:59 +2000-12-31 23:59:59.999999 2000-12-31 23:59:59 +2001-01-01 00:00:00.999999 2001-01-01 00:00:00 +2001-01-01 23:59:59.999999 2001-01-01 23:59:59 +2001-02-28 23:59:59.999999 2001-02-28 23:59:59 +2001-12-31 23:59:59.999999 2001-12-31 23:59:59 +2038-01-19 03:14:07.999999 2038-01-19 03:14:07 +SELECT a, TRUNCATE(a,1) FROM t1; +a TRUNCATE(a,1) +1970-01-01 00:00:01.999999 1970-01-01 00:00:01.9 +2000-01-01 00:00:00.999999 2000-01-01 00:00:00.9 +2000-01-01 23:59:59.999999 2000-01-01 23:59:59.9 +2000-02-29 23:59:59.999999 2000-02-29 23:59:59.9 +2000-12-31 23:59:59.999999 2000-12-31 23:59:59.9 +2001-01-01 00:00:00.999999 2001-01-01 00:00:00.9 +2001-01-01 23:59:59.999999 2001-01-01 23:59:59.9 +2001-02-28 23:59:59.999999 2001-02-28 23:59:59.9 +2001-12-31 23:59:59.999999 2001-12-31 23:59:59.9 +2038-01-19 03:14:07.999999 2038-01-19 03:14:07.9 +SELECT a, TRUNCATE(a,2) FROM t1; +a TRUNCATE(a,2) +1970-01-01 00:00:01.999999 1970-01-01 00:00:01.99 +2000-01-01 00:00:00.999999 2000-01-01 00:00:00.99 +2000-01-01 23:59:59.999999 2000-01-01 23:59:59.99 +2000-02-29 23:59:59.999999 2000-02-29 23:59:59.99 +2000-12-31 23:59:59.999999 2000-12-31 23:59:59.99 +2001-01-01 00:00:00.999999 2001-01-01 00:00:00.99 +2001-01-01 23:59:59.999999 2001-01-01 23:59:59.99 +2001-02-28 23:59:59.999999 2001-02-28 23:59:59.99 +2001-12-31 23:59:59.999999 2001-12-31 23:59:59.99 +2038-01-19 03:14:07.999999 2038-01-19 03:14:07.99 +SELECT a, TRUNCATE(a,3) FROM t1; +a TRUNCATE(a,3) +1970-01-01 00:00:01.999999 1970-01-01 00:00:01.999 +2000-01-01 00:00:00.999999 2000-01-01 00:00:00.999 +2000-01-01 23:59:59.999999 2000-01-01 23:59:59.999 +2000-02-29 23:59:59.999999 2000-02-29 23:59:59.999 +2000-12-31 23:59:59.999999 2000-12-31 23:59:59.999 +2001-01-01 00:00:00.999999 2001-01-01 00:00:00.999 +2001-01-01 23:59:59.999999 2001-01-01 23:59:59.999 +2001-02-28 23:59:59.999999 2001-02-28 23:59:59.999 +2001-12-31 23:59:59.999999 2001-12-31 23:59:59.999 +2038-01-19 03:14:07.999999 2038-01-19 03:14:07.999 +SELECT a, TRUNCATE(a,4) FROM t1; +a TRUNCATE(a,4) +1970-01-01 00:00:01.999999 1970-01-01 00:00:01.9999 +2000-01-01 00:00:00.999999 2000-01-01 00:00:00.9999 +2000-01-01 23:59:59.999999 2000-01-01 23:59:59.9999 +2000-02-29 23:59:59.999999 2000-02-29 23:59:59.9999 +2000-12-31 23:59:59.999999 2000-12-31 23:59:59.9999 +2001-01-01 00:00:00.999999 2001-01-01 00:00:00.9999 +2001-01-01 23:59:59.999999 2001-01-01 23:59:59.9999 +2001-02-28 23:59:59.999999 2001-02-28 23:59:59.9999 +2001-12-31 23:59:59.999999 2001-12-31 23:59:59.9999 +2038-01-19 03:14:07.999999 2038-01-19 03:14:07.9999 +SELECT a, TRUNCATE(a,5) FROM t1; +a TRUNCATE(a,5) +1970-01-01 00:00:01.999999 1970-01-01 00:00:01.99999 +2000-01-01 00:00:00.999999 2000-01-01 00:00:00.99999 +2000-01-01 23:59:59.999999 2000-01-01 23:59:59.99999 +2000-02-29 23:59:59.999999 2000-02-29 23:59:59.99999 +2000-12-31 23:59:59.999999 2000-12-31 23:59:59.99999 +2001-01-01 00:00:00.999999 2001-01-01 00:00:00.99999 +2001-01-01 23:59:59.999999 2001-01-01 23:59:59.99999 +2001-02-28 23:59:59.999999 2001-02-28 23:59:59.99999 +2001-12-31 23:59:59.999999 2001-12-31 23:59:59.99999 +2038-01-19 03:14:07.999999 2038-01-19 03:14:07.99999 +SELECT a, TRUNCATE(a,6) FROM t1; +a TRUNCATE(a,6) +1970-01-01 00:00:01.999999 1970-01-01 00:00:01.999999 +2000-01-01 00:00:00.999999 2000-01-01 00:00:00.999999 +2000-01-01 23:59:59.999999 2000-01-01 23:59:59.999999 +2000-02-29 23:59:59.999999 2000-02-29 23:59:59.999999 +2000-12-31 23:59:59.999999 2000-12-31 23:59:59.999999 +2001-01-01 00:00:00.999999 2001-01-01 00:00:00.999999 +2001-01-01 23:59:59.999999 2001-01-01 23:59:59.999999 +2001-02-28 23:59:59.999999 2001-02-28 23:59:59.999999 +2001-12-31 23:59:59.999999 2001-12-31 23:59:59.999999 +2038-01-19 03:14:07.999999 2038-01-19 03:14:07.999999 +SELECT a, TRUNCATE(a,7) FROM t1; +a TRUNCATE(a,7) +1970-01-01 00:00:01.999999 1970-01-01 00:00:01.999999 +2000-01-01 00:00:00.999999 2000-01-01 00:00:00.999999 +2000-01-01 23:59:59.999999 2000-01-01 23:59:59.999999 +2000-02-29 23:59:59.999999 2000-02-29 23:59:59.999999 +2000-12-31 23:59:59.999999 2000-12-31 23:59:59.999999 +2001-01-01 00:00:00.999999 2001-01-01 00:00:00.999999 +2001-01-01 23:59:59.999999 2001-01-01 23:59:59.999999 +2001-02-28 23:59:59.999999 2001-02-28 23:59:59.999999 +2001-12-31 23:59:59.999999 2001-12-31 23:59:59.999999 +2038-01-19 03:14:07.999999 2038-01-19 03:14:07.999999 +SELECT a, TRUNCATE(a,-1) FROM t1; +a TRUNCATE(a,-1) +1970-01-01 00:00:01.999999 1970-01-01 00:00:01 +2000-01-01 00:00:00.999999 2000-01-01 00:00:00 +2000-01-01 23:59:59.999999 2000-01-01 23:59:59 +2000-02-29 23:59:59.999999 2000-02-29 23:59:59 +2000-12-31 23:59:59.999999 2000-12-31 23:59:59 +2001-01-01 00:00:00.999999 2001-01-01 00:00:00 +2001-01-01 23:59:59.999999 2001-01-01 23:59:59 +2001-02-28 23:59:59.999999 2001-02-28 23:59:59 +2001-12-31 23:59:59.999999 2001-12-31 23:59:59 +2038-01-19 03:14:07.999999 2038-01-19 03:14:07 +SELECT a, TRUNCATE(a,-6) FROM t1; +a TRUNCATE(a,-6) +1970-01-01 00:00:01.999999 1970-01-01 00:00:01 +2000-01-01 00:00:00.999999 2000-01-01 00:00:00 +2000-01-01 23:59:59.999999 2000-01-01 23:59:59 +2000-02-29 23:59:59.999999 2000-02-29 23:59:59 +2000-12-31 23:59:59.999999 2000-12-31 23:59:59 +2001-01-01 00:00:00.999999 2001-01-01 00:00:00 +2001-01-01 23:59:59.999999 2001-01-01 23:59:59 +2001-02-28 23:59:59.999999 2001-02-28 23:59:59 +2001-12-31 23:59:59.999999 2001-12-31 23:59:59 +2038-01-19 03:14:07.999999 2038-01-19 03:14:07 +SELECT a, ROUND(a) FROM t1; +a ROUND(a) +1970-01-01 00:00:01.999999 1970-01-01 00:00:02 +2000-01-01 00:00:00.999999 2000-01-01 00:00:01 +2000-01-01 23:59:59.999999 2000-01-02 00:00:00 +2000-02-29 23:59:59.999999 2000-03-01 00:00:00 +2000-12-31 23:59:59.999999 2001-01-01 00:00:00 +2001-01-01 00:00:00.999999 2001-01-01 00:00:01 +2001-01-01 23:59:59.999999 2001-01-02 00:00:00 +2001-02-28 23:59:59.999999 2001-03-01 00:00:00 +2001-12-31 23:59:59.999999 2002-01-01 00:00:00 +2038-01-19 03:14:07.999999 2038-01-19 03:14:08 +SELECT a, ROUND(a,0) FROM t1; +a ROUND(a,0) +1970-01-01 00:00:01.999999 1970-01-01 00:00:02 +2000-01-01 00:00:00.999999 2000-01-01 00:00:01 +2000-01-01 23:59:59.999999 2000-01-02 00:00:00 +2000-02-29 23:59:59.999999 2000-03-01 00:00:00 +2000-12-31 23:59:59.999999 2001-01-01 00:00:00 +2001-01-01 00:00:00.999999 2001-01-01 00:00:01 +2001-01-01 23:59:59.999999 2001-01-02 00:00:00 +2001-02-28 23:59:59.999999 2001-03-01 00:00:00 +2001-12-31 23:59:59.999999 2002-01-01 00:00:00 +2038-01-19 03:14:07.999999 2038-01-19 03:14:08 +SELECT a, ROUND(a,1) FROM t1; +a ROUND(a,1) +1970-01-01 00:00:01.999999 1970-01-01 00:00:02.0 +2000-01-01 00:00:00.999999 2000-01-01 00:00:01.0 +2000-01-01 23:59:59.999999 2000-01-02 00:00:00.0 +2000-02-29 23:59:59.999999 2000-03-01 00:00:00.0 +2000-12-31 23:59:59.999999 2001-01-01 00:00:00.0 +2001-01-01 00:00:00.999999 2001-01-01 00:00:01.0 +2001-01-01 23:59:59.999999 2001-01-02 00:00:00.0 +2001-02-28 23:59:59.999999 2001-03-01 00:00:00.0 +2001-12-31 23:59:59.999999 2002-01-01 00:00:00.0 +2038-01-19 03:14:07.999999 2038-01-19 03:14:08.0 +SELECT a, ROUND(a,2) FROM t1; +a ROUND(a,2) +1970-01-01 00:00:01.999999 1970-01-01 00:00:02.00 +2000-01-01 00:00:00.999999 2000-01-01 00:00:01.00 +2000-01-01 23:59:59.999999 2000-01-02 00:00:00.00 +2000-02-29 23:59:59.999999 2000-03-01 00:00:00.00 +2000-12-31 23:59:59.999999 2001-01-01 00:00:00.00 +2001-01-01 00:00:00.999999 2001-01-01 00:00:01.00 +2001-01-01 23:59:59.999999 2001-01-02 00:00:00.00 +2001-02-28 23:59:59.999999 2001-03-01 00:00:00.00 +2001-12-31 23:59:59.999999 2002-01-01 00:00:00.00 +2038-01-19 03:14:07.999999 2038-01-19 03:14:08.00 +SELECT a, ROUND(a,3) FROM t1; +a ROUND(a,3) +1970-01-01 00:00:01.999999 1970-01-01 00:00:02.000 +2000-01-01 00:00:00.999999 2000-01-01 00:00:01.000 +2000-01-01 23:59:59.999999 2000-01-02 00:00:00.000 +2000-02-29 23:59:59.999999 2000-03-01 00:00:00.000 +2000-12-31 23:59:59.999999 2001-01-01 00:00:00.000 +2001-01-01 00:00:00.999999 2001-01-01 00:00:01.000 +2001-01-01 23:59:59.999999 2001-01-02 00:00:00.000 +2001-02-28 23:59:59.999999 2001-03-01 00:00:00.000 +2001-12-31 23:59:59.999999 2002-01-01 00:00:00.000 +2038-01-19 03:14:07.999999 2038-01-19 03:14:08.000 +SELECT a, ROUND(a,4) FROM t1; +a ROUND(a,4) +1970-01-01 00:00:01.999999 1970-01-01 00:00:02.0000 +2000-01-01 00:00:00.999999 2000-01-01 00:00:01.0000 +2000-01-01 23:59:59.999999 2000-01-02 00:00:00.0000 +2000-02-29 23:59:59.999999 2000-03-01 00:00:00.0000 +2000-12-31 23:59:59.999999 2001-01-01 00:00:00.0000 +2001-01-01 00:00:00.999999 2001-01-01 00:00:01.0000 +2001-01-01 23:59:59.999999 2001-01-02 00:00:00.0000 +2001-02-28 23:59:59.999999 2001-03-01 00:00:00.0000 +2001-12-31 23:59:59.999999 2002-01-01 00:00:00.0000 +2038-01-19 03:14:07.999999 2038-01-19 03:14:08.0000 +SELECT a, ROUND(a,5) FROM t1; +a ROUND(a,5) +1970-01-01 00:00:01.999999 1970-01-01 00:00:02.00000 +2000-01-01 00:00:00.999999 2000-01-01 00:00:01.00000 +2000-01-01 23:59:59.999999 2000-01-02 00:00:00.00000 +2000-02-29 23:59:59.999999 2000-03-01 00:00:00.00000 +2000-12-31 23:59:59.999999 2001-01-01 00:00:00.00000 +2001-01-01 00:00:00.999999 2001-01-01 00:00:01.00000 +2001-01-01 23:59:59.999999 2001-01-02 00:00:00.00000 +2001-02-28 23:59:59.999999 2001-03-01 00:00:00.00000 +2001-12-31 23:59:59.999999 2002-01-01 00:00:00.00000 +2038-01-19 03:14:07.999999 2038-01-19 03:14:08.00000 +SELECT a, ROUND(a,6) FROM t1; +a ROUND(a,6) +1970-01-01 00:00:01.999999 1970-01-01 00:00:01.999999 +2000-01-01 00:00:00.999999 2000-01-01 00:00:00.999999 +2000-01-01 23:59:59.999999 2000-01-01 23:59:59.999999 +2000-02-29 23:59:59.999999 2000-02-29 23:59:59.999999 +2000-12-31 23:59:59.999999 2000-12-31 23:59:59.999999 +2001-01-01 00:00:00.999999 2001-01-01 00:00:00.999999 +2001-01-01 23:59:59.999999 2001-01-01 23:59:59.999999 +2001-02-28 23:59:59.999999 2001-02-28 23:59:59.999999 +2001-12-31 23:59:59.999999 2001-12-31 23:59:59.999999 +2038-01-19 03:14:07.999999 2038-01-19 03:14:07.999999 +SELECT a, ROUND(a,7) FROM t1; +a ROUND(a,7) +1970-01-01 00:00:01.999999 1970-01-01 00:00:01.999999 +2000-01-01 00:00:00.999999 2000-01-01 00:00:00.999999 +2000-01-01 23:59:59.999999 2000-01-01 23:59:59.999999 +2000-02-29 23:59:59.999999 2000-02-29 23:59:59.999999 +2000-12-31 23:59:59.999999 2000-12-31 23:59:59.999999 +2001-01-01 00:00:00.999999 2001-01-01 00:00:00.999999 +2001-01-01 23:59:59.999999 2001-01-01 23:59:59.999999 +2001-02-28 23:59:59.999999 2001-02-28 23:59:59.999999 +2001-12-31 23:59:59.999999 2001-12-31 23:59:59.999999 +2038-01-19 03:14:07.999999 2038-01-19 03:14:07.999999 +SELECT a, ROUND(a,-1) FROM t1; +a ROUND(a,-1) +1970-01-01 00:00:01.999999 1970-01-01 00:00:02 +2000-01-01 00:00:00.999999 2000-01-01 00:00:01 +2000-01-01 23:59:59.999999 2000-01-02 00:00:00 +2000-02-29 23:59:59.999999 2000-03-01 00:00:00 +2000-12-31 23:59:59.999999 2001-01-01 00:00:00 +2001-01-01 00:00:00.999999 2001-01-01 00:00:01 +2001-01-01 23:59:59.999999 2001-01-02 00:00:00 +2001-02-28 23:59:59.999999 2001-03-01 00:00:00 +2001-12-31 23:59:59.999999 2002-01-01 00:00:00 +2038-01-19 03:14:07.999999 2038-01-19 03:14:08 +SELECT a, ROUND(a,-6) FROM t1; +a ROUND(a,-6) +1970-01-01 00:00:01.999999 1970-01-01 00:00:02 +2000-01-01 00:00:00.999999 2000-01-01 00:00:01 +2000-01-01 23:59:59.999999 2000-01-02 00:00:00 +2000-02-29 23:59:59.999999 2000-03-01 00:00:00 +2000-12-31 23:59:59.999999 2001-01-01 00:00:00 +2001-01-01 00:00:00.999999 2001-01-01 00:00:01 +2001-01-01 23:59:59.999999 2001-01-02 00:00:00 +2001-02-28 23:59:59.999999 2001-03-01 00:00:00 +2001-12-31 23:59:59.999999 2002-01-01 00:00:00 +2038-01-19 03:14:07.999999 2038-01-19 03:14:08 +DROP TABLE t1; +SET time_zone=DEFAULT; +# +# End of 10.4 tests +# diff --git a/mysql-test/main/type_timestamp_hires.test b/mysql-test/main/type_timestamp_hires.test index 0b05f81ef42..f2e765d09fe 100644 --- a/mysql-test/main/type_timestamp_hires.test +++ b/mysql-test/main/type_timestamp_hires.test @@ -40,3 +40,73 @@ show create table t1; create or replace table t1 (a timestamp(5) on update current_timestamp(6)); show create table t1; drop table t1; + + +--echo # +--echo # Start of 10.4 tests +--echo # + +--echo # +--echo # MDEV-20397 Support TIMESTAMP, DATETIME, TIME in ROUND() and TRUNCATE() +--echo # + +--echo # ROUND(timestamp) and TRUNCATE(timestamp) currently return DATETIME. +--echo # This may change in the future to return TIMESTAMP. + +CREATE TABLE t1 (a1 TIMESTAMP(6) NULL DEFAULT '2001-01-01 00:00:00', a2 TIMESTAMP(6) NOT NULL); +CREATE TABLE t2 AS SELECT + ROUND(a1) AS r1, + ROUND(a2) AS r2, + TRUNCATE(a1,0) AS t1, + TRUNCATE(a2,0) AS t2 +FROM t1; +SHOW CREATE TABLE t2; +DROP TABLE t2; +DROP TABLE t1; + + +SET time_zone='+00:00'; + +CREATE TABLE t1 (a TIMESTAMP(6)); +INSERT INTO t1 VALUES +('1970-01-01 00:00:01.999999'), +('2000-01-01 00:00:00.999999'), +('2000-01-01 23:59:59.999999'), +('2000-02-29 23:59:59.999999'), +('2000-12-31 23:59:59.999999'), +('2001-01-01 00:00:00.999999'), +('2001-01-01 23:59:59.999999'), +('2001-02-28 23:59:59.999999'), +('2001-12-31 23:59:59.999999'), +('2038-01-19 03:14:07.999999'); + +SELECT a, TRUNCATE(a,0) FROM t1; +SELECT a, TRUNCATE(a,1) FROM t1; +SELECT a, TRUNCATE(a,2) FROM t1; +SELECT a, TRUNCATE(a,3) FROM t1; +SELECT a, TRUNCATE(a,4) FROM t1; +SELECT a, TRUNCATE(a,5) FROM t1; +SELECT a, TRUNCATE(a,6) FROM t1; +SELECT a, TRUNCATE(a,7) FROM t1; +SELECT a, TRUNCATE(a,-1) FROM t1; +SELECT a, TRUNCATE(a,-6) FROM t1; + +SELECT a, ROUND(a) FROM t1; +SELECT a, ROUND(a,0) FROM t1; +SELECT a, ROUND(a,1) FROM t1; +SELECT a, ROUND(a,2) FROM t1; +SELECT a, ROUND(a,3) FROM t1; +SELECT a, ROUND(a,4) FROM t1; +SELECT a, ROUND(a,5) FROM t1; +SELECT a, ROUND(a,6) FROM t1; +SELECT a, ROUND(a,7) FROM t1; +SELECT a, ROUND(a,-1) FROM t1; +SELECT a, ROUND(a,-6) FROM t1; + +DROP TABLE t1; + +SET time_zone=DEFAULT; + +--echo # +--echo # End of 10.4 tests +--echo # diff --git a/sql/item_func.cc b/sql/item_func.cc index ce01ef1a686..ced1d69caa9 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2338,6 +2338,42 @@ void Item_func_round::fix_arg_double() } +void Item_func_round::fix_arg_temporal(const Type_handler *h, + uint int_part_length) +{ + set_handler(h); + if (args[1]->const_item() && !args[1]->is_expensive()) + { + Longlong_hybrid_null dec= args[1]->to_longlong_hybrid_null(); + fix_attributes_temporal(int_part_length, + dec.is_null() ? args[0]->decimals : + dec.to_uint(TIME_SECOND_PART_DIGITS)); + } + else + fix_attributes_temporal(int_part_length, args[0]->decimals); +} + + +void Item_func_round::fix_arg_time() +{ + fix_arg_temporal(&type_handler_time2, MIN_TIME_WIDTH); +} + + +void Item_func_round::fix_arg_datetime() +{ + /* + Day increment operations are not supported for '0000-00-00', + see get_date_from_daynr() for details. Therefore, expressions like + ROUND('0000-00-00 23:59:59.999999') + return NULL. + */ + if (!truncate) + maybe_null= true; + fix_arg_temporal(&type_handler_datetime2, MAX_DATETIME_WIDTH); +} + + void Item_func_round::fix_arg_int() { if (args[1]->const_item()) @@ -2477,6 +2513,36 @@ my_decimal *Item_func_round::decimal_op(my_decimal *decimal_value) } +bool Item_func_round::time_op(THD *thd, MYSQL_TIME *to) +{ + DBUG_ASSERT(args[0]->type_handler()->mysql_timestamp_type() == + MYSQL_TIMESTAMP_TIME); + Time::Options opt(Time::default_flags_for_get_date(), + truncate ? TIME_FRAC_TRUNCATE : TIME_FRAC_ROUND, + Time::DATETIME_TO_TIME_DISALLOW); + Longlong_hybrid_null dec= args[1]->to_longlong_hybrid_null(); + Time *tm= new (to) Time(thd, args[0], opt, + dec.to_uint(TIME_SECOND_PART_DIGITS)); + null_value= !tm->is_valid_time() || dec.is_null(); + DBUG_ASSERT(maybe_null || !null_value); + return null_value; +} + + +bool Item_func_round::date_op(THD *thd, MYSQL_TIME *to, date_mode_t fuzzydate) +{ + DBUG_ASSERT(args[0]->type_handler()->mysql_timestamp_type() == + MYSQL_TIMESTAMP_DATETIME); + Datetime::Options opt(thd, truncate ? TIME_FRAC_TRUNCATE : TIME_FRAC_ROUND); + Longlong_hybrid_null dec= args[1]->to_longlong_hybrid_null(); + Datetime *tm= new (to) Datetime(thd, args[0], opt, + dec.to_uint(TIME_SECOND_PART_DIGITS)); + null_value= !tm->is_valid_datetime() || dec.is_null(); + DBUG_ASSERT(maybe_null || !null_value); + return null_value; +} + + void Item_func_rand::seed_random(Item *arg) { /* diff --git a/sql/item_func.h b/sql/item_func.h index 610adb4bb46..eaa5410dea2 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1700,21 +1700,36 @@ public: /* This handles round and truncate */ -class Item_func_round :public Item_func_numhybrid +class Item_func_round :public Item_func_hybrid_field_type { bool truncate; void fix_length_and_dec_decimal(uint decimals_to_set); void fix_length_and_dec_double(uint decimals_to_set); public: Item_func_round(THD *thd, Item *a, Item *b, bool trunc_arg) - :Item_func_numhybrid(thd, a, b), truncate(trunc_arg) {} + :Item_func_hybrid_field_type(thd, a, b), truncate(trunc_arg) {} const char *func_name() const { return truncate ? "truncate" : "round"; } double real_op(); longlong int_op(); my_decimal *decimal_op(my_decimal *); + bool date_op(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate); + bool time_op(THD *thd, MYSQL_TIME *ltime); + bool native_op(THD *thd, Native *to) + { + DBUG_ASSERT(0); + return true; + } + String *str_op(String *str) + { + DBUG_ASSERT(0); + return NULL; + } void fix_arg_decimal(); void fix_arg_int(); void fix_arg_double(); + void fix_arg_time(); + void fix_arg_datetime(); + void fix_arg_temporal(const Type_handler *h, uint int_part_length); bool fix_length_and_dec() { return args[0]->type_handler()->Item_func_round_fix_length_and_dec(this); diff --git a/sql/sql_time.cc b/sql/sql_time.cc index c64995fa3d6..b128a7f7291 100644 --- a/sql/sql_time.cc +++ b/sql/sql_time.cc @@ -914,7 +914,7 @@ void make_truncated_value_warning(THD *thd, #define GET_PART(X, N) X % N ## LL; X/= N ## LL bool date_add_interval(THD *thd, MYSQL_TIME *ltime, interval_type int_type, - const INTERVAL &interval) + const INTERVAL &interval, bool push_warn) { long period, sign; @@ -1027,6 +1027,7 @@ bool date_add_interval(THD *thd, MYSQL_TIME *ltime, interval_type int_type, return 0; // Ok invalid_date: + if (push_warn) { push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_DATETIME_FUNCTION_OVERFLOW, diff --git a/sql/sql_time.h b/sql/sql_time.h index 25980d6417c..fe9697adf67 100644 --- a/sql/sql_time.h +++ b/sql/sql_time.h @@ -92,7 +92,7 @@ bool my_TIME_to_str(const MYSQL_TIME *ltime, String *str, uint dec); /* MYSQL_TIME operations */ bool date_add_interval(THD *thd, MYSQL_TIME *ltime, interval_type int_type, - const INTERVAL &interval); + const INTERVAL &interval, bool push_warn= true); bool calc_time_diff(const MYSQL_TIME *l_time1, const MYSQL_TIME *l_time2, int l_sign, ulonglong *seconds_out, ulong *microseconds_out); int append_interval(String *str, interval_type int_type, diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 6653b8b1a3f..8b382773f7a 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -953,10 +953,21 @@ bool Temporal::datetime_add_nanoseconds_or_invalidate(THD *thd, int *warn, ulong INTERVAL interval; memset(&interval, 0, sizeof(interval)); interval.hour= 1; - /* date_add_interval cannot handle bad dates */ - if (check_date(TIME_NO_ZERO_IN_DATE | TIME_NO_ZERO_DATE, warn) || - date_add_interval(thd, this, INTERVAL_HOUR, interval)) + /* + date_add_interval cannot handle bad dates with zero YYYY or MM. + Note, check_date(NO_ZERO_XX) does not check YYYY against zero, + so let's additionally check it. + */ + if (year == 0 || + check_date(TIME_NO_ZERO_IN_DATE | TIME_NO_ZERO_DATE, warn) || + date_add_interval(thd, this, INTERVAL_HOUR, interval, false/*no warn*/)) { + char buf[MAX_DATE_STRING_REP_LENGTH]; + my_date_to_str(this, buf); + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_WRONG_VALUE_FOR_TYPE, + ER_THD(thd, ER_WRONG_VALUE_FOR_TYPE), + "date", buf, "round(datetime)"); make_from_out_of_range(warn); return true; } @@ -5620,6 +5631,30 @@ bool Type_handler_temporal_result:: } +bool Type_handler_time_common:: + Item_func_round_fix_length_and_dec(Item_func_round *item) const +{ + item->fix_arg_time(); + return false; +} + + +bool Type_handler_datetime_common:: + Item_func_round_fix_length_and_dec(Item_func_round *item) const +{ + item->fix_arg_datetime(); + return false; +} + + +bool Type_handler_timestamp_common:: + Item_func_round_fix_length_and_dec(Item_func_round *item) const +{ + item->fix_arg_datetime(); + return false; +} + + bool Type_handler_string_result:: Item_func_round_fix_length_and_dec(Item_func_round *item) const { diff --git a/sql/sql_type.h b/sql/sql_type.h index 0f270ce9d5d..4b87d6cc989 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -5281,6 +5281,7 @@ public: bool Item_func_min_max_get_date(THD *thd, Item_func_min_max*, MYSQL_TIME *, date_mode_t fuzzydate) const; longlong Item_func_between_val_int(Item_func_between *func) const; + bool Item_func_round_fix_length_and_dec(Item_func_round *) const; Item *make_const_item_for_comparison(THD *, Item *src, const Item *cmp) const; bool set_comparator_func(Arg_comparator *cmp) const; cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const; @@ -5507,6 +5508,7 @@ public: longlong Item_func_min_max_val_int(Item_func_min_max *) const; my_decimal *Item_func_min_max_val_decimal(Item_func_min_max *, my_decimal *) const; + bool Item_func_round_fix_length_and_dec(Item_func_round *) const; bool Item_hybrid_func_fix_attributes(THD *thd, const char *name, Type_handler_hybrid_field_type *, @@ -5608,6 +5610,7 @@ public: bool Item_param_val_native(THD *thd, Item_param *item, Native *to) const; int cmp_native(const Native &a, const Native &b) const; longlong Item_func_between_val_int(Item_func_between *func) const; + bool Item_func_round_fix_length_and_dec(Item_func_round *) const; cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const; in_vector *make_in_vector(THD *thd, const Item_func_in *f, uint nargs) const; void make_sort_key(uchar *to, Item *item, const SORT_FIELD_ATTR *sort_field, |