Commit 235cf969 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-20397 Support TIMESTAMP, DATETIME, TIME in ROUND() and TRUNCATE()

parent 7b4de104
......@@ -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;
......
......@@ -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,
......
......@@ -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
#
......@@ -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
......
This diff is collapsed.
......@@ -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 #
......@@ -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;
......@@ -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;
This diff is collapsed.
......@@ -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 #
......@@ -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)
{
/*
......
......@@ -1700,21 +1700,36 @@ class Item_func_floor :public Item_func_int_val
/* 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);
......
......@@ -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,
......
......@@ -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,
......
......@@ -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
{
......
......@@ -5281,6 +5281,7 @@ class Type_handler_time_common: public Type_handler_temporal_result
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 @@ class Type_handler_datetime_common: public Type_handler_temporal_with_date
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 @@ class Type_handler_timestamp_common: public Type_handler_temporal_with_date
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,
......
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