MDEV-15751 CURRENT_TIMESTAMP should return a TIMESTAMP [WITH TIME ZONE?]

Changing the return type of the following functions:
  - CURRENT_TIMESTAMP, CURRENT_TIMESTAMP(), NOW()
  - SYSDATE()
  - FROM_UNIXTIME()
from DATETIME to TIMESTAMP.

Note, the old function NOW() returning DATETIME is still available
as LOCALTIMESTAMP or LOCALTIMESTAMP(), e.g.:

  SELECT
    LOCALTIMESTAMP,     -- DATETIME
    CURRENT_TIMESTAMP;  -- TIMESTAMP

The change in the functions return data type fixes some problems
that occurred near a DST change:

- Problem #1

INSERT INTO t1 (timestamp_field) VALUES (CURRENT_TIMESTAMP);
INSERT INTO t1 (timestamp_field) VALUES (COALESCE(CURRENT_TIMESTAMP));

could result into two different values inserted.

- Problem #2

INSERT INTO t1 (timestamp_field) VALUES (FROM_UNIXTIME(1288477526));
INSERT INTO t1 (timestamp_field) VALUES (FROM_UNIXTIME(1288477526+3600));

could result into two equal TIMESTAMP values near a DST change.

Additional changes:

- FROM_UNIXTIME(0) now returns SQL NULL instead of '1970-01-01 00:00:00'
  (assuming time_zone='+00:00')

- UNIX_TIMESTAMP('1970-01-01 00:00:00') now returns SQL NULL instead of 0
  (assuming time_zone='+00:00'

These additional changes are needed for consistency with TIMESTAMP fields,
which cannot store '1970-01-01 00:00:00 +00:00'
This commit is contained in:
Alexander Barkov 2024-08-26 13:24:59 +04:00 committed by Sergei Golubchik
commit dfaf7e2eb4
31 changed files with 770 additions and 185 deletions

View file

@ -128,7 +128,7 @@ drop table t2;
create table t2 select now() as a , curtime() as b, curdate() as c , 1+1 as d , 1.0 + 1 as e , 33333333333333333 + 3 as f; create table t2 select now() as a , curtime() as b, curdate() as c , 1+1 as d , 1.0 + 1 as e , 33333333333333333 + 3 as f;
describe t2; describe t2;
Field Type Null Key Default Extra Field Type Null Key Default Extra
a datetime NO NULL a timestamp NO NULL
b time NO NULL b time NO NULL
c date NO NULL c date NO NULL
d int(3) NO NULL d int(3) NO NULL

View file

@ -781,12 +781,12 @@ insert into t1 values (now());
create table t2 select f2 from (select max(now()) f2 from t1) a; create table t2 select f2 from (select max(now()) f2 from t1) a;
show columns from t2; show columns from t2;
Field Type Null Key Default Extra Field Type Null Key Default Extra
f2 datetime YES NULL f2 timestamp YES NULL
drop table t2; drop table t2;
create table t2 select f2 from (select now() f2 from t1) a; create table t2 select f2 from (select now() f2 from t1) a;
show columns from t2; show columns from t2;
Field Type Null Key Default Extra Field Type Null Key Default Extra
f2 datetime NO NULL f2 timestamp NO NULL
drop table t2, t1; drop table t2, t1;
CREATE TABLE t1( CREATE TABLE t1(
id int PRIMARY KEY, id int PRIMARY KEY,

View file

@ -583,7 +583,9 @@ from_unixtime(2147483647)
2038-01-19 06:14:07 2038-01-19 06:14:07
select from_unixtime(0); select from_unixtime(0);
from_unixtime(0) from_unixtime(0)
1970-01-01 03:00:00 NULL
Warnings:
Warning 1292 Truncated incorrect unixtime value: '0.0'
select unix_timestamp(from_unixtime(2147483647)); select unix_timestamp(from_unixtime(2147483647));
unix_timestamp(from_unixtime(2147483647)) unix_timestamp(from_unixtime(2147483647))
2147483647 2147483647
@ -6323,10 +6325,12 @@ TIME('- 01:00:00') TIME('- 1 01:00:00')
SET time_zone='+00:00'; SET time_zone='+00:00';
SELECT NULLIF(FROM_UNIXTIME('foo'), '2012-12-12 21:10:14'); SELECT NULLIF(FROM_UNIXTIME('foo'), '2012-12-12 21:10:14');
NULLIF(FROM_UNIXTIME('foo'), '2012-12-12 21:10:14') NULLIF(FROM_UNIXTIME('foo'), '2012-12-12 21:10:14')
1970-01-01 00:00:00 NULL
Warnings: Warnings:
Warning 1292 Truncated incorrect DECIMAL value: 'foo' Warning 1292 Truncated incorrect DECIMAL value: 'foo'
Warning 1292 Truncated incorrect unixtime value: '0.0'
Warning 1292 Truncated incorrect DECIMAL value: 'foo' Warning 1292 Truncated incorrect DECIMAL value: 'foo'
Warning 1292 Truncated incorrect unixtime value: '0.0'
SET time_zone=DEFAULT; SET time_zone=DEFAULT;
# #
# MDEV-18402 Assertion `sec.sec() <= 59' failed in Item_func_maketime::get_date # MDEV-18402 Assertion `sec.sec() <= 59' failed in Item_func_maketime::get_date
@ -6437,3 +6441,120 @@ SET timestamp=DEFAULT;
# #
# End of 11.6 tests # End of 11.6 tests
# #
#
# Start of 11.7 tests
#
#
# MDEV-15751 CURRENT_TIMESTAMP should return a TIMESTAMP [WITH TIME ZONE?]
#
CREATE TABLE t1 (localtimestamp TIMESTAMP);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'localtimestamp TIMESTAMP)' at line 1
CREATE TABLE t1 (current_timestamp TIMESTAMP);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'current_timestamp TIMESTAMP)' at line 1
CREATE TABLE t1 AS
SELECT
localtimestamp,
localtimestamp(),
localtimestamp(0),
localtimestamp(1),
localtimestamp(2),
localtimestamp(3),
localtimestamp(4),
localtimestamp(5),
localtimestamp(6);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`localtimestamp` datetime NOT NULL,
`localtimestamp()` datetime NOT NULL,
`localtimestamp(0)` datetime NOT NULL,
`localtimestamp(1)` datetime(1) NOT NULL,
`localtimestamp(2)` datetime(2) NOT NULL,
`localtimestamp(3)` datetime(3) NOT NULL,
`localtimestamp(4)` datetime(4) NOT NULL,
`localtimestamp(5)` datetime(5) NOT NULL,
`localtimestamp(6)` datetime(6) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
DROP TABLE t1;
CREATE TABLE t1 AS
SELECT
current_timestamp(),
current_timestamp(0),
current_timestamp(1),
current_timestamp(2),
current_timestamp(3),
current_timestamp(4),
current_timestamp(5),
current_timestamp(6);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`current_timestamp()` timestamp NOT NULL,
`current_timestamp(0)` timestamp NOT NULL,
`current_timestamp(1)` timestamp(1) NOT NULL,
`current_timestamp(2)` timestamp(2) NOT NULL,
`current_timestamp(3)` timestamp(3) NOT NULL,
`current_timestamp(4)` timestamp(4) NOT NULL,
`current_timestamp(5)` timestamp(5) NOT NULL,
`current_timestamp(6)` timestamp(6) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
DROP TABLE t1;
CREATE TABLE t1 AS
SELECT
sysdate(),
sysdate(0),
sysdate(1),
sysdate(2),
sysdate(3),
sysdate(4),
sysdate(5),
sysdate(6);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`sysdate()` timestamp NOT NULL,
`sysdate(0)` timestamp NOT NULL,
`sysdate(1)` timestamp(1) NOT NULL,
`sysdate(2)` timestamp(2) NOT NULL,
`sysdate(3)` timestamp(3) NOT NULL,
`sysdate(4)` timestamp(4) NOT NULL,
`sysdate(5)` timestamp(5) NOT NULL,
`sysdate(6)` timestamp(6) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
DROP TABLE t1;
CREATE TABLE t1 AS
SELECT
from_unixtime(1000000e0),
from_unixtime(1000000),
from_unixtime(1000000.1),
from_unixtime(1000000.12),
from_unixtime(1000000.123),
from_unixtime(1000000.1234),
from_unixtime(1000000.12345),
from_unixtime(1000000.123456),
from_unixtime(1000000.1234567),
from_unixtime(1000000.12345678),
from_unixtime(1000000.123456789),
from_unixtime(1000000.1234567891),
from_unixtime(1000000.12345678912);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`from_unixtime(1000000e0)` timestamp(6) NULL DEFAULT NULL,
`from_unixtime(1000000)` timestamp NULL DEFAULT NULL,
`from_unixtime(1000000.1)` timestamp(1) NULL DEFAULT NULL,
`from_unixtime(1000000.12)` timestamp(2) NULL DEFAULT NULL,
`from_unixtime(1000000.123)` timestamp(3) NULL DEFAULT NULL,
`from_unixtime(1000000.1234)` timestamp(4) NULL DEFAULT NULL,
`from_unixtime(1000000.12345)` timestamp(5) NULL DEFAULT NULL,
`from_unixtime(1000000.123456)` timestamp(6) NULL DEFAULT NULL,
`from_unixtime(1000000.1234567)` timestamp(6) NULL DEFAULT NULL,
`from_unixtime(1000000.12345678)` timestamp(6) NULL DEFAULT NULL,
`from_unixtime(1000000.123456789)` timestamp(6) NULL DEFAULT NULL,
`from_unixtime(1000000.1234567891)` timestamp(6) NULL DEFAULT NULL,
`from_unixtime(1000000.12345678912)` timestamp(6) NULL DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
DROP TABLE t1;
#
# End of 11.7 tests
#

View file

@ -3293,3 +3293,79 @@ SET timestamp=DEFAULT;
--echo # --echo #
--echo # End of 11.6 tests --echo # End of 11.6 tests
--echo # --echo #
--echo #
--echo # Start of 11.7 tests
--echo #
--echo #
--echo # MDEV-15751 CURRENT_TIMESTAMP should return a TIMESTAMP [WITH TIME ZONE?]
--echo #
--error ER_PARSE_ERROR
CREATE TABLE t1 (localtimestamp TIMESTAMP);
--error ER_PARSE_ERROR
CREATE TABLE t1 (current_timestamp TIMESTAMP);
CREATE TABLE t1 AS
SELECT
localtimestamp,
localtimestamp(),
localtimestamp(0),
localtimestamp(1),
localtimestamp(2),
localtimestamp(3),
localtimestamp(4),
localtimestamp(5),
localtimestamp(6);
SHOW CREATE TABLE t1;
DROP TABLE t1;
CREATE TABLE t1 AS
SELECT
current_timestamp(),
current_timestamp(0),
current_timestamp(1),
current_timestamp(2),
current_timestamp(3),
current_timestamp(4),
current_timestamp(5),
current_timestamp(6);
SHOW CREATE TABLE t1;
DROP TABLE t1;
CREATE TABLE t1 AS
SELECT
sysdate(),
sysdate(0),
sysdate(1),
sysdate(2),
sysdate(3),
sysdate(4),
sysdate(5),
sysdate(6);
SHOW CREATE TABLE t1;
DROP TABLE t1;
CREATE TABLE t1 AS
SELECT
from_unixtime(1000000e0),
from_unixtime(1000000),
from_unixtime(1000000.1),
from_unixtime(1000000.12),
from_unixtime(1000000.123),
from_unixtime(1000000.1234),
from_unixtime(1000000.12345),
from_unixtime(1000000.123456),
from_unixtime(1000000.1234567),
from_unixtime(1000000.12345678),
from_unixtime(1000000.123456789),
from_unixtime(1000000.1234567891),
from_unixtime(1000000.12345678912);
SHOW CREATE TABLE t1;
DROP TABLE t1;
--echo #
--echo # End of 11.7 tests
--echo #

View file

@ -39,12 +39,12 @@ t1 CREATE TABLE `t1` (
`sec_to_time(12345)` time DEFAULT NULL, `sec_to_time(12345)` time DEFAULT NULL,
`sec_to_time(12345.6789)` time(4) DEFAULT NULL, `sec_to_time(12345.6789)` time(4) DEFAULT NULL,
`sec_to_time(1234567e-2)` time(6) DEFAULT NULL, `sec_to_time(1234567e-2)` time(6) DEFAULT NULL,
`now()` datetime NOT NULL, `now()` timestamp NOT NULL,
`curtime(0)` time NOT NULL, `curtime(0)` time NOT NULL,
`utc_timestamp(1)` datetime(1) NOT NULL, `utc_timestamp(1)` datetime(1) NOT NULL,
`utc_time(2)` time(2) NOT NULL, `utc_time(2)` time(2) NOT NULL,
`current_time(3)` time(3) NOT NULL, `current_time(3)` time(3) NOT NULL,
`current_timestamp(4)` datetime(4) NOT NULL, `current_timestamp(4)` timestamp(4) NOT NULL,
`localtime(5)` time(5) NOT NULL, `localtime(5)` time(5) NOT NULL,
`localtimestamp(6)` datetime(6) NOT NULL, `localtimestamp(6)` datetime(6) NOT NULL,
`time_to_sec(123456)` bigint(17) DEFAULT NULL, `time_to_sec(123456)` bigint(17) DEFAULT NULL,

View file

@ -4574,21 +4574,21 @@ EXECUTE stmt USING CURRENT_TIMESTAMP;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`c1` datetime NOT NULL `c1` timestamp NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
DROP TABLE t1; DROP TABLE t1;
EXECUTE stmt USING CURRENT_TIMESTAMP(3); EXECUTE stmt USING CURRENT_TIMESTAMP(3);
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`c1` datetime(3) NOT NULL `c1` timestamp(3) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
DROP TABLE t1; DROP TABLE t1;
EXECUTE stmt USING CURRENT_TIMESTAMP(6); EXECUTE stmt USING CURRENT_TIMESTAMP(6);
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`c1` datetime(6) NOT NULL `c1` timestamp(6) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
DROP TABLE t1; DROP TABLE t1;
EXECUTE stmt USING CURRENT_TIME; EXECUTE stmt USING CURRENT_TIME;

View file

@ -53,7 +53,7 @@ DROP TABLE t1;
select unix_timestamp('1970-01-01 01:00:00'), select unix_timestamp('1970-01-01 01:00:00'),
unix_timestamp('1970-01-01 01:00:01'); unix_timestamp('1970-01-01 01:00:01');
unix_timestamp('1970-01-01 01:00:00') unix_timestamp('1970-01-01 01:00:01') unix_timestamp('1970-01-01 01:00:00') unix_timestamp('1970-01-01 01:00:01')
0 1 NULL 1
select unix_timestamp('1969-12-31 23:59:59'), unix_timestamp('1970-01-01 00:00:00'), unix_timestamp('1970-01-01 00:59:59'); select unix_timestamp('1969-12-31 23:59:59'), unix_timestamp('1970-01-01 00:00:00'), unix_timestamp('1970-01-01 00:59:59');
unix_timestamp('1969-12-31 23:59:59') unix_timestamp('1970-01-01 00:00:00') unix_timestamp('1970-01-01 00:59:59') unix_timestamp('1969-12-31 23:59:59') unix_timestamp('1970-01-01 00:00:00') unix_timestamp('1970-01-01 00:59:59')
NULL NULL NULL NULL NULL NULL

View file

@ -680,10 +680,10 @@ INSERT INTO t1 VALUES ('2001-01-01 10:20:30'),('2001-01-01 10:20:31');
# Optimized (more than 24 hours before the DST fall back) # Optimized (more than 24 hours before the DST fall back)
# #
SET timestamp=@first_second_after_dst_fall_back-24*3600-1; SET timestamp=@first_second_after_dst_fall_back-24*3600-1;
SELECT UNIX_TIMESTAMP(), NOW(); SELECT UNIX_TIMESTAMP(), LOCALTIMESTAMP();
UNIX_TIMESTAMP() NOW() UNIX_TIMESTAMP() LOCALTIMESTAMP()
1288393199 2010-10-30 02:59:59 1288393199 2010-10-30 02:59:59
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=now(); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=LOCALTIMESTAMP();
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings: Warnings:
@ -692,34 +692,34 @@ Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` =
# Not optimized (24 hours before the DST fall back) # Not optimized (24 hours before the DST fall back)
# #
SET timestamp=@first_second_after_dst_fall_back-24*3600; SET timestamp=@first_second_after_dst_fall_back-24*3600;
SELECT UNIX_TIMESTAMP(), NOW(); SELECT UNIX_TIMESTAMP(), LOCALTIMESTAMP();
UNIX_TIMESTAMP() NOW() UNIX_TIMESTAMP() LOCALTIMESTAMP()
1288393200 2010-10-30 03:00:00 1288393200 2010-10-30 03:00:00
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=now(); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=LOCALTIMESTAMP();
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings: Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = <cache>(current_timestamp()) Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = <cache>(localtimestamp())
# #
# Not optimized (less than 24 hours after the DST fall back) # Not optimized (less than 24 hours after the DST fall back)
# #
SET timestamp=@first_second_after_dst_fall_back+24*3600-1; SET timestamp=@first_second_after_dst_fall_back+24*3600-1;
SELECT UNIX_TIMESTAMP(), NOW(); SELECT UNIX_TIMESTAMP(), LOCALTIMESTAMP();
UNIX_TIMESTAMP() NOW() UNIX_TIMESTAMP() LOCALTIMESTAMP()
1288565999 2010-11-01 01:59:59 1288565999 2010-11-01 01:59:59
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=now(); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=LOCALTIMESTAMP();
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings: Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = <cache>(current_timestamp()) Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = <cache>(localtimestamp())
# #
# Optimized (24 hours after the DST fall back) # Optimized (24 hours after the DST fall back)
# #
SET timestamp=@first_second_after_dst_fall_back+24*3600; SET timestamp=@first_second_after_dst_fall_back+24*3600;
SELECT UNIX_TIMESTAMP(), NOW(); SELECT UNIX_TIMESTAMP(), LOCALTIMESTAMP();
UNIX_TIMESTAMP() NOW() UNIX_TIMESTAMP() LOCALTIMESTAMP()
1288566000 2010-11-01 02:00:00 1288566000 2010-11-01 02:00:00
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=now(); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=LOCALTIMESTAMP();
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings: Warnings:
@ -737,10 +737,10 @@ INSERT INTO t1 VALUES ('2001-01-01 10:20:30'),('2001-01-01 10:20:31');
# Optimized (more than 24 hours before the DST sprint forward) # Optimized (more than 24 hours before the DST sprint forward)
# #
SET timestamp=@first_second_after_dst_spring_forward-24*3600-1; SET timestamp=@first_second_after_dst_spring_forward-24*3600-1;
SELECT UNIX_TIMESTAMP(), NOW(); SELECT UNIX_TIMESTAMP(), LOCALTIMESTAMP();
UNIX_TIMESTAMP() NOW() UNIX_TIMESTAMP() LOCALTIMESTAMP()
1301093999 2011-03-26 01:59:59 1301093999 2011-03-26 01:59:59
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=now(); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=LOCALTIMESTAMP();
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings: Warnings:
@ -749,34 +749,34 @@ Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` =
# Not optimized (24 hours before the DST sprint forward) # Not optimized (24 hours before the DST sprint forward)
# #
SET timestamp=@first_second_after_dst_spring_forward-24*3600; SET timestamp=@first_second_after_dst_spring_forward-24*3600;
SELECT UNIX_TIMESTAMP(), NOW(); SELECT UNIX_TIMESTAMP(), LOCALTIMESTAMP();
UNIX_TIMESTAMP() NOW() UNIX_TIMESTAMP() LOCALTIMESTAMP()
1301094000 2011-03-26 02:00:00 1301094000 2011-03-26 02:00:00
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=now(); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=LOCALTIMESTAMP();
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings: Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = <cache>(current_timestamp()) Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = <cache>(localtimestamp())
# #
# Not optimized (less than 24 hours after the DST sprint forward) # Not optimized (less than 24 hours after the DST sprint forward)
# #
SET timestamp=@first_second_after_dst_spring_forward+24*3600-1; SET timestamp=@first_second_after_dst_spring_forward+24*3600-1;
SELECT UNIX_TIMESTAMP(), NOW(); SELECT UNIX_TIMESTAMP(), LOCALTIMESTAMP();
UNIX_TIMESTAMP() NOW() UNIX_TIMESTAMP() LOCALTIMESTAMP()
1301266799 2011-03-28 02:59:59 1301266799 2011-03-28 02:59:59
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=now(); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=LOCALTIMESTAMP();
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings: Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = <cache>(current_timestamp()) Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = <cache>(localtimestamp())
# #
# Optimized (24 hours after the DST sprint forward) # Optimized (24 hours after the DST sprint forward)
# #
SET timestamp=@first_second_after_dst_spring_forward+24*3600; SET timestamp=@first_second_after_dst_spring_forward+24*3600;
SELECT UNIX_TIMESTAMP(), NOW(); SELECT UNIX_TIMESTAMP(), LOCALTIMESTAMP();
UNIX_TIMESTAMP() NOW() UNIX_TIMESTAMP() LOCALTIMESTAMP()
1301266800 2011-03-28 03:00:00 1301266800 2011-03-28 03:00:00
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=now(); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=LOCALTIMESTAMP();
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings: Warnings:
@ -805,10 +805,10 @@ INSERT INTO t1 VALUES ('2001-01-01 10:20:30');
# Optimized (more than 24 hours before the leap second) # Optimized (more than 24 hours before the leap second)
# #
SET timestamp=@leap_second-24*3600-1; SET timestamp=@leap_second-24*3600-1;
SELECT UNIX_TIMESTAMP(), NOW(); SELECT UNIX_TIMESTAMP(), LOCALTIMESTAMP();
UNIX_TIMESTAMP() NOW() UNIX_TIMESTAMP() LOCALTIMESTAMP()
362707208 1981-06-30 03:59:59 362707208 1981-06-30 03:59:59
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=now(); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=LOCALTIMESTAMP();
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00 Using where
Warnings: Warnings:
@ -817,37 +817,79 @@ Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` =
# Not optimized (24 hours before the leap second) # Not optimized (24 hours before the leap second)
# #
SET timestamp=@leap_second-24*3600; SET timestamp=@leap_second-24*3600;
SELECT UNIX_TIMESTAMP(), NOW(); SELECT UNIX_TIMESTAMP(), LOCALTIMESTAMP();
UNIX_TIMESTAMP() NOW() UNIX_TIMESTAMP() LOCALTIMESTAMP()
362707209 1981-06-30 04:00:00 362707209 1981-06-30 04:00:00
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=now(); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=LOCALTIMESTAMP();
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00 Using where
Warnings: Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = <cache>(current_timestamp()) Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = <cache>(localtimestamp())
# #
# Not optimized (less than 24 hours after the leap second) # Not optimized (less than 24 hours after the leap second)
# #
SET timestamp=@leap_second+24*3600-1; SET timestamp=@leap_second+24*3600-1;
SELECT UNIX_TIMESTAMP(), NOW(); SELECT UNIX_TIMESTAMP(), LOCALTIMESTAMP();
UNIX_TIMESTAMP() NOW() UNIX_TIMESTAMP() LOCALTIMESTAMP()
362880008 1981-07-02 03:59:58 362880008 1981-07-02 03:59:58
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=now(); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=LOCALTIMESTAMP();
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00 Using where
Warnings: Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = <cache>(current_timestamp()) Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = <cache>(localtimestamp())
# #
# Not optimized (24 hours after the leap second) # Not optimized (24 hours after the leap second)
# #
SET timestamp=@leap_second+24*3600; SET timestamp=@leap_second+24*3600;
SELECT UNIX_TIMESTAMP(), NOW(); SELECT UNIX_TIMESTAMP(), LOCALTIMESTAMP();
UNIX_TIMESTAMP() NOW() UNIX_TIMESTAMP() LOCALTIMESTAMP()
362880009 1981-07-02 03:59:59 362880009 1981-07-02 03:59:59
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=now(); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=LOCALTIMESTAMP();
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00 Using where
Warnings: Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP/*WITH LOCAL TIME ZONE*/'1981-07-02 03:59:59' Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP/*WITH LOCAL TIME ZONE*/'1981-07-02 03:59:59'
DROP TABLE t1; DROP TABLE t1;
SET time_zone=DEFAULT; SET time_zone=DEFAULT;
#
# End of 11.3 tests
#
#
# Start of 11.7 tests
#
#
# MDEV-15751 CURRENT_TIMESTAMP should return a TIMESTAMP [WITH TIME ZONE?]
#
SET time_zone='Europe/Moscow';
CREATE TABLE t1 (a TIMESTAMP);
SET timestamp=1288477526 /*summer time*/;
INSERT INTO t1 VALUES (CURRENT_TIMESTAMP()), (COALESCE(CURRENT_TIMESTAMP()));
SET timestamp=1288477526+3600 /*winter time*/;
INSERT INTO t1 VALUES (CURRENT_TIMESTAMP()), (COALESCE(CURRENT_TIMESTAMP()));
# The two INSERTs produce equal "a" but different UNIX_TIMESTAMP(a)
SELECT a, UNIX_TIMESTAMP(a) FROM t1;
a UNIX_TIMESTAMP(a)
2010-10-31 02:25:26 1288477526
2010-10-31 02:25:26 1288477526
2010-10-31 02:25:26 1288481126
2010-10-31 02:25:26 1288481126
DROP TABLE t1;
SET time_zone=DEFAULT;
SET time_zone='Europe/Moscow';
CREATE TABLE t1 (a TIMESTAMP);
SET timestamp=1288477526 /*summer time*/;
INSERT INTO t1 VALUES (LOCALTIMESTAMP()), (COALESCE(LOCALTIMESTAMP()));
SET timestamp=1288477526+3600 /*winter time*/;
INSERT INTO t1 VALUES (LOCALTIMESTAMP()), (COALESCE(LOCALTIMESTAMP()));
# The two INSERTs produce equal "a" and equal (summer) UNIX_TIMESTAMP(a)
SELECT a, UNIX_TIMESTAMP(a) FROM t1;
a UNIX_TIMESTAMP(a)
2010-10-31 02:25:26 1288477526
2010-10-31 02:25:26 1288477526
2010-10-31 02:25:26 1288477526
2010-10-31 02:25:26 1288477526
DROP TABLE t1;
SET time_zone=DEFAULT;
#
# End of 11.7 tests
#

View file

@ -636,32 +636,32 @@ INSERT INTO t1 VALUES ('2001-01-01 10:20:30'),('2001-01-01 10:20:31');
--echo # --echo #
SET timestamp=@first_second_after_dst_fall_back-24*3600-1; SET timestamp=@first_second_after_dst_fall_back-24*3600-1;
SELECT UNIX_TIMESTAMP(), NOW(); SELECT UNIX_TIMESTAMP(), LOCALTIMESTAMP();
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=now(); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=LOCALTIMESTAMP();
--echo # --echo #
--echo # Not optimized (24 hours before the DST fall back) --echo # Not optimized (24 hours before the DST fall back)
--echo # --echo #
SET timestamp=@first_second_after_dst_fall_back-24*3600; SET timestamp=@first_second_after_dst_fall_back-24*3600;
SELECT UNIX_TIMESTAMP(), NOW(); SELECT UNIX_TIMESTAMP(), LOCALTIMESTAMP();
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=now(); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=LOCALTIMESTAMP();
--echo # --echo #
--echo # Not optimized (less than 24 hours after the DST fall back) --echo # Not optimized (less than 24 hours after the DST fall back)
--echo # --echo #
SET timestamp=@first_second_after_dst_fall_back+24*3600-1; SET timestamp=@first_second_after_dst_fall_back+24*3600-1;
SELECT UNIX_TIMESTAMP(), NOW(); SELECT UNIX_TIMESTAMP(), LOCALTIMESTAMP();
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=now(); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=LOCALTIMESTAMP();
--echo # --echo #
--echo # Optimized (24 hours after the DST fall back) --echo # Optimized (24 hours after the DST fall back)
--echo # --echo #
SET timestamp=@first_second_after_dst_fall_back+24*3600; SET timestamp=@first_second_after_dst_fall_back+24*3600;
SELECT UNIX_TIMESTAMP(), NOW(); SELECT UNIX_TIMESTAMP(), LOCALTIMESTAMP();
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=now(); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=LOCALTIMESTAMP();
DROP TABLE t1; DROP TABLE t1;
SET time_zone=DEFAULT; SET time_zone=DEFAULT;
@ -684,32 +684,32 @@ INSERT INTO t1 VALUES ('2001-01-01 10:20:30'),('2001-01-01 10:20:31');
--echo # --echo #
SET timestamp=@first_second_after_dst_spring_forward-24*3600-1; SET timestamp=@first_second_after_dst_spring_forward-24*3600-1;
SELECT UNIX_TIMESTAMP(), NOW(); SELECT UNIX_TIMESTAMP(), LOCALTIMESTAMP();
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=now(); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=LOCALTIMESTAMP();
--echo # --echo #
--echo # Not optimized (24 hours before the DST sprint forward) --echo # Not optimized (24 hours before the DST sprint forward)
--echo # --echo #
SET timestamp=@first_second_after_dst_spring_forward-24*3600; SET timestamp=@first_second_after_dst_spring_forward-24*3600;
SELECT UNIX_TIMESTAMP(), NOW(); SELECT UNIX_TIMESTAMP(), LOCALTIMESTAMP();
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=now(); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=LOCALTIMESTAMP();
--echo # --echo #
--echo # Not optimized (less than 24 hours after the DST sprint forward) --echo # Not optimized (less than 24 hours after the DST sprint forward)
--echo # --echo #
SET timestamp=@first_second_after_dst_spring_forward+24*3600-1; SET timestamp=@first_second_after_dst_spring_forward+24*3600-1;
SELECT UNIX_TIMESTAMP(), NOW(); SELECT UNIX_TIMESTAMP(), LOCALTIMESTAMP();
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=now(); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=LOCALTIMESTAMP();
--echo # --echo #
--echo # Optimized (24 hours after the DST sprint forward) --echo # Optimized (24 hours after the DST sprint forward)
--echo # --echo #
SET timestamp=@first_second_after_dst_spring_forward+24*3600; SET timestamp=@first_second_after_dst_spring_forward+24*3600;
SELECT UNIX_TIMESTAMP(), NOW(); SELECT UNIX_TIMESTAMP(), LOCALTIMESTAMP();
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=now(); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=LOCALTIMESTAMP();
DROP TABLE t1; DROP TABLE t1;
@ -735,33 +735,72 @@ INSERT INTO t1 VALUES ('2001-01-01 10:20:30');
--echo # --echo #
SET timestamp=@leap_second-24*3600-1; SET timestamp=@leap_second-24*3600-1;
SELECT UNIX_TIMESTAMP(), NOW(); SELECT UNIX_TIMESTAMP(), LOCALTIMESTAMP();
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=now(); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=LOCALTIMESTAMP();
--echo # --echo #
--echo # Not optimized (24 hours before the leap second) --echo # Not optimized (24 hours before the leap second)
--echo # --echo #
SET timestamp=@leap_second-24*3600; SET timestamp=@leap_second-24*3600;
SELECT UNIX_TIMESTAMP(), NOW(); SELECT UNIX_TIMESTAMP(), LOCALTIMESTAMP();
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=now(); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=LOCALTIMESTAMP();
--echo # --echo #
--echo # Not optimized (less than 24 hours after the leap second) --echo # Not optimized (less than 24 hours after the leap second)
--echo # --echo #
SET timestamp=@leap_second+24*3600-1; SET timestamp=@leap_second+24*3600-1;
SELECT UNIX_TIMESTAMP(), NOW(); SELECT UNIX_TIMESTAMP(), LOCALTIMESTAMP();
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=now(); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=LOCALTIMESTAMP();
--echo # --echo #
--echo # Not optimized (24 hours after the leap second) --echo # Not optimized (24 hours after the leap second)
--echo # --echo #
SET timestamp=@leap_second+24*3600; SET timestamp=@leap_second+24*3600;
SELECT UNIX_TIMESTAMP(), NOW(); SELECT UNIX_TIMESTAMP(), LOCALTIMESTAMP();
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=now(); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=LOCALTIMESTAMP();
DROP TABLE t1; DROP TABLE t1;
SET time_zone=DEFAULT; SET time_zone=DEFAULT;
--echo #
--echo # End of 11.3 tests
--echo #
--echo #
--echo # Start of 11.7 tests
--echo #
--echo #
--echo # MDEV-15751 CURRENT_TIMESTAMP should return a TIMESTAMP [WITH TIME ZONE?]
--echo #
SET time_zone='Europe/Moscow';
CREATE TABLE t1 (a TIMESTAMP);
SET timestamp=1288477526 /*summer time*/;
INSERT INTO t1 VALUES (CURRENT_TIMESTAMP()), (COALESCE(CURRENT_TIMESTAMP()));
SET timestamp=1288477526+3600 /*winter time*/;
INSERT INTO t1 VALUES (CURRENT_TIMESTAMP()), (COALESCE(CURRENT_TIMESTAMP()));
--echo # The two INSERTs produce equal "a" but different UNIX_TIMESTAMP(a)
SELECT a, UNIX_TIMESTAMP(a) FROM t1;
DROP TABLE t1;
SET time_zone=DEFAULT;
SET time_zone='Europe/Moscow';
CREATE TABLE t1 (a TIMESTAMP);
SET timestamp=1288477526 /*summer time*/;
INSERT INTO t1 VALUES (LOCALTIMESTAMP()), (COALESCE(LOCALTIMESTAMP()));
SET timestamp=1288477526+3600 /*winter time*/;
INSERT INTO t1 VALUES (LOCALTIMESTAMP()), (COALESCE(LOCALTIMESTAMP()));
--echo # The two INSERTs produce equal "a" and equal (summer) UNIX_TIMESTAMP(a)
SELECT a, UNIX_TIMESTAMP(a) FROM t1;
DROP TABLE t1;
SET time_zone=DEFAULT;
--echo #
--echo # End of 11.7 tests
--echo #

View file

@ -1,6 +1,20 @@
select from_unixtime(0); select from_unixtime(0);
from_unixtime(0) from_unixtime(0)
1969-12-31 14:00:00 NULL
Warnings:
Warning 1292 Truncated incorrect unixtime value: '0.0'
select from_unixtime(0.000001);
from_unixtime(0.000001)
1969-12-31 14:00:00.000001
select from_unixtime(1);
from_unixtime(1)
1969-12-31 14:00:01
select unix_timestamp('1969-12-31 14:00:00');
unix_timestamp('1969-12-31 14:00:00')
NULL
select unix_timestamp('1969-12-31 14:00:00.000001');
unix_timestamp('1969-12-31 14:00:00.000001')
0.000001
select unix_timestamp('1969-12-31 14:00:01'); select unix_timestamp('1969-12-31 14:00:01');
unix_timestamp('1969-12-31 14:00:01') unix_timestamp('1969-12-31 14:00:01')
1 1

View file

@ -8,6 +8,12 @@
# #
select from_unixtime(0); select from_unixtime(0);
select from_unixtime(0.000001);
select from_unixtime(1);
# check 0 boundary # check 0 boundary
select unix_timestamp('1969-12-31 14:00:00');
select unix_timestamp('1969-12-31 14:00:00.000001');
select unix_timestamp('1969-12-31 14:00:01'); select unix_timestamp('1969-12-31 14:00:01');

View file

@ -2472,6 +2472,7 @@ SELECT 1 FROM t1 GROUP BY v1 ORDER BY AVG ( from_unixtime ( '' ) ) ;
1 1
Warnings: Warnings:
Warning 1292 Truncated incorrect DECIMAL value: '' Warning 1292 Truncated incorrect DECIMAL value: ''
Warning 1292 Truncated incorrect unixtime value: '0.0'
DROP TABLE t1; DROP TABLE t1;
SELECT SUM(DISTINCT 0.000000000000000000000000000000000000001); SELECT SUM(DISTINCT 0.000000000000000000000000000000000000001);
SUM(DISTINCT 0.000000000000000000000000000000000000001) SUM(DISTINCT 0.000000000000000000000000000000000000001)

View file

@ -1,11 +1,6 @@
--- main/type_timestamp.result --- type_timestamp.result 2024-09-17 11:32:07.799634536 +0400
+++ main/type_timestamp.reject +++ type_timestamp.reject 2024-09-17 14:10:30.223789268 +0400
@@ -1,4 +1,3 @@ @@ -1372,7 +1372,7 @@
-drop table if exists t1,t2;
set time_zone="+03:00";
CREATE TABLE t1 (a int, t timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);
CREATE TABLE t2 (a int, t datetime);
@@ -1373,7 +1372,7 @@
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings: Warnings:
@ -14,7 +9,7 @@
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='1001-01-01 10:20:30'; EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='1001-01-01 10:20:30';
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
@@ -1389,7 +1388,7 @@ @@ -1388,7 +1388,7 @@
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings: Warnings:
@ -23,7 +18,7 @@
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=10010101102030; EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=10010101102030;
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
@@ -1404,7 +1403,7 @@ @@ -1403,7 +1403,7 @@
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings: Warnings:
@ -32,7 +27,7 @@
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=10010101102030e0; EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=10010101102030e0;
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
@@ -1419,7 +1418,7 @@ @@ -1418,7 +1418,7 @@
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings: Warnings:
@ -41,7 +36,7 @@
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=10010101102030.0; EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=10010101102030.0;
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
@@ -1434,17 +1433,17 @@ @@ -1433,17 +1433,17 @@
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings: Warnings:
@ -62,12 +57,12 @@
# #
# Comparison predicates: Good TIMESTAMP values switch to TIMESTAMP comparison # Comparison predicates: Good TIMESTAMP values switch to TIMESTAMP comparison
# #
@@ -1570,22 +1569,22 @@ @@ -1569,22 +1569,22 @@
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings: Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP/*WITH LOCAL TIME ZONE*/'2038-01-18 03:14:08' -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP/*WITH LOCAL TIME ZONE*/'2038-01-18 03:14:08'
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = <cache>(from_unixtime(0x7fffffff - 24 * 3600 + 1)) +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = <cache>(cast(from_unixtime(0x7fffffff - 24 * 3600 + 1) as datetime))
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=TIMESTAMP'2038-01-18 03:14:08'; EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=TIMESTAMP'2038-01-18 03:14:08';
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
@ -80,16 +75,16 @@
Warnings: Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP/*WITH LOCAL TIME ZONE*/'2038-01-19 03:14:07' -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP/*WITH LOCAL TIME ZONE*/'2038-01-19 03:14:07'
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2038-01-19 03:14:07' +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2038-01-19 03:14:07'
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=FROM_UNIXTIME(0x7FFFFFFF); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=CAST(FROM_UNIXTIME(0x7FFFFFFF) AS DATETIME);
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings: Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP/*WITH LOCAL TIME ZONE*/'2038-01-19 03:14:07' -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP/*WITH LOCAL TIME ZONE*/'2038-01-19 03:14:07'
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = <cache>(from_unixtime(0x7fffffff)) +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = <cache>(cast(from_unixtime(0x7fffffff) as datetime))
# #
# Corner cases: rounding # Corner cases: rounding
# #
@@ -1620,7 +1619,7 @@ @@ -1619,7 +1619,7 @@
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings: Warnings:
Note 1292 Truncated incorrect DATETIME value: '2038-01-18 03:14:07.9999999' Note 1292 Truncated incorrect DATETIME value: '2038-01-18 03:14:07.9999999'
@ -98,7 +93,7 @@
SET sql_mode=DEFAULT; SET sql_mode=DEFAULT;
# #
# NULLIF: Bad TIMESTAMP values preserve DATETIME comparison # NULLIF: Bad TIMESTAMP values preserve DATETIME comparison
@@ -1639,7 +1638,7 @@ @@ -1638,7 +1638,7 @@
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings: Warnings:
@ -107,7 +102,7 @@
EXPLAIN EXTENDED SELECT * FROM t1 WHERE NULLIF(a,'1001-01-01 10:20:30'); EXPLAIN EXTENDED SELECT * FROM t1 WHERE NULLIF(a,'1001-01-01 10:20:30');
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
@@ -1654,7 +1653,7 @@ @@ -1653,7 +1653,7 @@
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings: Warnings:
@ -116,7 +111,7 @@
EXPLAIN EXTENDED SELECT * FROM t1 WHERE NULLIF(a,10010101102030); EXPLAIN EXTENDED SELECT * FROM t1 WHERE NULLIF(a,10010101102030);
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
@@ -1669,7 +1668,7 @@ @@ -1668,7 +1668,7 @@
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings: Warnings:
@ -125,7 +120,7 @@
EXPLAIN EXTENDED SELECT * FROM t1 WHERE NULLIF(a,10010101102030e0); EXPLAIN EXTENDED SELECT * FROM t1 WHERE NULLIF(a,10010101102030e0);
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
@@ -1684,7 +1683,7 @@ @@ -1683,7 +1683,7 @@
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings: Warnings:
@ -134,7 +129,7 @@
EXPLAIN EXTENDED SELECT * FROM t1 WHERE NULLIF(a,10010101102030.0); EXPLAIN EXTENDED SELECT * FROM t1 WHERE NULLIF(a,10010101102030.0);
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
@@ -1699,7 +1698,7 @@ @@ -1698,7 +1698,7 @@
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings: Warnings:

View file

@ -1541,7 +1541,7 @@ Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` =
# Corner cases: DATETIME values inside the supported optimization range: # Corner cases: DATETIME values inside the supported optimization range:
# FROM_UNIXTIME(24*3600) .. FROM_UNIXTIME(0x7FFFFFFF-24*3600) # FROM_UNIXTIME(24*3600) .. FROM_UNIXTIME(0x7FFFFFFF-24*3600)
# #
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=FROM_UNIXTIME(24*3600); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=CAST(FROM_UNIXTIME(24*3600) AS DATETIME);
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings: Warnings:
@ -1556,7 +1556,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings: Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP/*WITH LOCAL TIME ZONE*/'2038-01-18 03:14:07' Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP/*WITH LOCAL TIME ZONE*/'2038-01-18 03:14:07'
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=FROM_UNIXTIME(0x7FFFFFFF-24*3600); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=CAST(FROM_UNIXTIME(0x7FFFFFFF-24*3600) AS DATETIME);
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings: Warnings:
@ -1565,7 +1565,7 @@ Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` =
# Corner cases: DATETIME values after the supported optimization range # Corner cases: DATETIME values after the supported optimization range
# FROM_UNIXTIME(0x7FFFFFFF-24*3600+1) .. FROM_UNIXTIME(0x7FFFFFFF) # FROM_UNIXTIME(0x7FFFFFFF-24*3600+1) .. FROM_UNIXTIME(0x7FFFFFFF)
# #
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=FROM_UNIXTIME(0x7FFFFFFF-24*3600+1); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=CAST(FROM_UNIXTIME(0x7FFFFFFF-24*3600+1) AS DATETIME);
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings: Warnings:
@ -1580,7 +1580,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings: Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP/*WITH LOCAL TIME ZONE*/'2038-01-19 03:14:07' Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP/*WITH LOCAL TIME ZONE*/'2038-01-19 03:14:07'
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=FROM_UNIXTIME(0x7FFFFFFF); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=CAST(FROM_UNIXTIME(0x7FFFFFFF) AS DATETIME);
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings: Warnings:

View file

@ -992,20 +992,20 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=FROM_UNIXTIME(24*3600-1);
--echo # FROM_UNIXTIME(24*3600) .. FROM_UNIXTIME(0x7FFFFFFF-24*3600) --echo # FROM_UNIXTIME(24*3600) .. FROM_UNIXTIME(0x7FFFFFFF-24*3600)
--echo # --echo #
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=FROM_UNIXTIME(24*3600); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=CAST(FROM_UNIXTIME(24*3600) AS DATETIME);
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=TIMESTAMP'1970-01-02 00:00:00'; EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=TIMESTAMP'1970-01-02 00:00:00';
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=TIMESTAMP'2038-01-18 03:14:07'; EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=TIMESTAMP'2038-01-18 03:14:07';
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=FROM_UNIXTIME(0x7FFFFFFF-24*3600); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=CAST(FROM_UNIXTIME(0x7FFFFFFF-24*3600) AS DATETIME);
--echo # --echo #
--echo # Corner cases: DATETIME values after the supported optimization range --echo # Corner cases: DATETIME values after the supported optimization range
--echo # FROM_UNIXTIME(0x7FFFFFFF-24*3600+1) .. FROM_UNIXTIME(0x7FFFFFFF) --echo # FROM_UNIXTIME(0x7FFFFFFF-24*3600+1) .. FROM_UNIXTIME(0x7FFFFFFF)
--echo # --echo #
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=FROM_UNIXTIME(0x7FFFFFFF-24*3600+1); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=CAST(FROM_UNIXTIME(0x7FFFFFFF-24*3600+1) AS DATETIME);
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=TIMESTAMP'2038-01-18 03:14:08'; EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=TIMESTAMP'2038-01-18 03:14:08';
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=TIMESTAMP'2038-01-19 03:14:07'; EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=TIMESTAMP'2038-01-19 03:14:07';
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=FROM_UNIXTIME(0x7FFFFFFF); EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=CAST(FROM_UNIXTIME(0x7FFFFFFF) AS DATETIME);
--echo # --echo #
--echo # Corner cases: rounding --echo # Corner cases: rounding

View file

@ -0,0 +1,55 @@
SET time_zone='+02:00';
SET timestamp=100000000;
#
# This test makes sure binlog has SET time_zone
# for "TIMESTAMP function to DATETIME column" conversion.
#
CREATE TABLE t1 (a DATETIME);
INSERT INTO t1 VALUES (CURRENT_TIMESTAMP());
INSERT INTO t1 VALUES (COALESCE(CURRENT_TIMESTAMP()));
DROP TABLE t1;
FLUSH LOGS;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
ROLLBACK/*!*/;
use `test`/*!*/;
SET TIMESTAMP=100000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1, @@session.check_constraint_checks=1, @@session.sql_if_exists=0, @@session.explicit_defaults_for_timestamp=1, @@session.system_versioning_insert_history=0/*!*/;
SET @@session.sql_mode=#/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=latin1,@@session.collation_connection=8,@@session.collation_server=#/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
CREATE TABLE t1 (a DATETIME)
/*!*/;
START TRANSACTION
/*!*/;
SET TIMESTAMP=100000000/*!*/;
SET @@session.time_zone='+02:00'/*!*/;
INSERT INTO t1 VALUES (CURRENT_TIMESTAMP())
/*!*/;
SET TIMESTAMP=100000000/*!*/;
COMMIT
/*!*/;
START TRANSACTION
/*!*/;
SET TIMESTAMP=100000000/*!*/;
INSERT INTO t1 VALUES (COALESCE(CURRENT_TIMESTAMP()))
/*!*/;
SET TIMESTAMP=100000000/*!*/;
COMMIT
/*!*/;
SET TIMESTAMP=100000000/*!*/;
DROP TABLE `t1` /* generated by server */
/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
SET time_zone=DEFAULT;
SET Timestamp=DEFAULT;

View file

@ -0,0 +1,53 @@
SET time_zone='+02:00';
SET timestamp=100000000;
#
# This test makes sure binlog does not have SET time_zone
#
CREATE TABLE t1 (a TIMESTAMP);
INSERT INTO t1 VALUES (CURRENT_TIMESTAMP());
INSERT INTO t1 VALUES (COALESCE(CURRENT_TIMESTAMP()));
DROP TABLE t1;
FLUSH LOGS;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
ROLLBACK/*!*/;
use `test`/*!*/;
SET TIMESTAMP=100000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1, @@session.check_constraint_checks=1, @@session.sql_if_exists=0, @@session.explicit_defaults_for_timestamp=1, @@session.system_versioning_insert_history=0/*!*/;
SET @@session.sql_mode=#/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=latin1,@@session.collation_connection=8,@@session.collation_server=#/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
CREATE TABLE t1 (a TIMESTAMP)
/*!*/;
START TRANSACTION
/*!*/;
SET TIMESTAMP=100000000/*!*/;
INSERT INTO t1 VALUES (CURRENT_TIMESTAMP())
/*!*/;
SET TIMESTAMP=100000000/*!*/;
COMMIT
/*!*/;
START TRANSACTION
/*!*/;
SET TIMESTAMP=100000000/*!*/;
INSERT INTO t1 VALUES (COALESCE(CURRENT_TIMESTAMP()))
/*!*/;
SET TIMESTAMP=100000000/*!*/;
COMMIT
/*!*/;
SET TIMESTAMP=100000000/*!*/;
DROP TABLE `t1` /* generated by server */
/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
SET time_zone=DEFAULT;
SET Timestamp=DEFAULT;

View file

@ -0,0 +1,29 @@
--source include/not_embedded.inc
--source include/have_binlog_format_statement.inc
-- source include/have_log_bin.inc
let $MYSQLD_DATADIR= `select @@datadir`;
--disable_query_log
reset master; # get rid of previous tests binlog
--enable_query_log
SET time_zone='+02:00';
SET timestamp=100000000;
--echo #
--echo # This test makes sure binlog has SET time_zone
--echo # for "TIMESTAMP function to DATETIME column" conversion.
--echo #
CREATE TABLE t1 (a DATETIME);
INSERT INTO t1 VALUES (CURRENT_TIMESTAMP());
INSERT INTO t1 VALUES (COALESCE(CURRENT_TIMESTAMP()));
DROP TABLE t1;
FLUSH LOGS;
--replace_regex /@@session.sql_mode=\d+/@@session.sql_mode=#/ /collation_server=\d+/collation_server=#/
--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --short-form
SET time_zone=DEFAULT;
SET Timestamp=DEFAULT;

View file

@ -0,0 +1,28 @@
--source include/not_embedded.inc
--source include/have_binlog_format_statement.inc
-- source include/have_log_bin.inc
let $MYSQLD_DATADIR= `select @@datadir`;
--disable_query_log
reset master; # get rid of previous tests binlog
--enable_query_log
SET time_zone='+02:00';
SET timestamp=100000000;
--echo #
--echo # This test makes sure binlog does not have SET time_zone
--echo #
CREATE TABLE t1 (a TIMESTAMP);
INSERT INTO t1 VALUES (CURRENT_TIMESTAMP());
INSERT INTO t1 VALUES (COALESCE(CURRENT_TIMESTAMP()));
DROP TABLE t1;
FLUSH LOGS;
--replace_regex /@@session.sql_mode=\d+/@@session.sql_mode=#/ /collation_server=\d+/collation_server=#/
--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --short-form
SET time_zone=DEFAULT;
SET Timestamp=DEFAULT;

View file

@ -43,9 +43,9 @@ create or replace table t1 (a datetime, b varchar(10) as (localtime) PERSISTENT)
ERROR HY000: Function or expression 'curtime()' cannot be used in the GENERATED ALWAYS AS clause of `b` ERROR HY000: Function or expression 'curtime()' cannot be used in the GENERATED ALWAYS AS clause of `b`
# LOCALTIMESTAMP, LOCALTIMESTAMP()(v4.0.6) # LOCALTIMESTAMP, LOCALTIMESTAMP()(v4.0.6)
create or replace table t1 (a datetime, b varchar(10) as (localtimestamp()) PERSISTENT); create or replace table t1 (a datetime, b varchar(10) as (localtimestamp()) PERSISTENT);
ERROR HY000: Function or expression 'current_timestamp()' cannot be used in the GENERATED ALWAYS AS clause of `b` ERROR HY000: Function or expression 'localtimestamp()' cannot be used in the GENERATED ALWAYS AS clause of `b`
create or replace table t1 (a datetime, b varchar(10) as (localtimestamp) PERSISTENT); create or replace table t1 (a datetime, b varchar(10) as (localtimestamp) PERSISTENT);
ERROR HY000: Function or expression 'current_timestamp()' cannot be used in the GENERATED ALWAYS AS clause of `b` ERROR HY000: Function or expression 'localtimestamp()' cannot be used in the GENERATED ALWAYS AS clause of `b`
# NOW() # NOW()
create or replace table t1 (a datetime, b varchar(10) as (now()) PERSISTENT); create or replace table t1 (a datetime, b varchar(10) as (now()) PERSISTENT);
ERROR HY000: Function or expression 'current_timestamp()' cannot be used in the GENERATED ALWAYS AS clause of `b` ERROR HY000: Function or expression 'current_timestamp()' cannot be used in the GENERATED ALWAYS AS clause of `b`

View file

@ -211,12 +211,12 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
Query A: Query A:
Note 1003 select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t1` FOR SYSTEM_TIME AS OF TIMESTAMP current_timestamp(6) join `test`.`t2` FOR SYSTEM_TIME AS OF TIMESTAMP current_timestamp(6) where `test`.`t1`.`x` = `test`.`t2`.`x` and `test`.`t2`.`row_end` > TIMESTAMP/*WITH LOCAL TIME ZONE*/'YYYY-MM-DD hh:ss:mm:.uuuuuu' and `test`.`t2`.`row_start` <= TIMESTAMP/*WITH LOCAL TIME ZONE*/'YYYY-MM-DD hh:ss:mm:.uuuuuu' and `test`.`t1`.`row_end` > TIMESTAMP/*WITH LOCAL TIME ZONE*/'YYYY-MM-DD hh:ss:mm:.uuuuuu' and `test`.`t1`.`row_start` <= TIMESTAMP/*WITH LOCAL TIME ZONE*/'YYYY-MM-DD hh:ss:mm:.uuuuuu' Note 1003 select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t1` FOR SYSTEM_TIME AS OF TIMESTAMP current_timestamp(6) join `test`.`t2` FOR SYSTEM_TIME AS OF TIMESTAMP current_timestamp(6) where `test`.`t1`.`x` = `test`.`t2`.`x` and `test`.`t2`.`row_end` > <cache>(current_timestamp(6)) and `test`.`t2`.`row_start` <= <cache>(current_timestamp(6)) and `test`.`t1`.`row_end` > <cache>(current_timestamp(6)) and `test`.`t1`.`row_start` <= <cache>(current_timestamp(6))
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
Query B: Query B:
Note 1003 select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t1` FOR SYSTEM_TIME AS OF TIMESTAMP current_timestamp(6) join `test`.`t2` FOR SYSTEM_TIME AS OF TIMESTAMP current_timestamp(6) where `test`.`t1`.`x` = `test`.`t2`.`x` and `test`.`t2`.`row_end` > TIMESTAMP/*WITH LOCAL TIME ZONE*/'YYYY-MM-DD hh:ss:mm:.uuuuuu' and `test`.`t2`.`row_start` <= TIMESTAMP/*WITH LOCAL TIME ZONE*/'YYYY-MM-DD hh:ss:mm:.uuuuuu' and `test`.`t1`.`row_end` > TIMESTAMP/*WITH LOCAL TIME ZONE*/'YYYY-MM-DD hh:ss:mm:.uuuuuu' and `test`.`t1`.`row_start` <= TIMESTAMP/*WITH LOCAL TIME ZONE*/'YYYY-MM-DD hh:ss:mm:.uuuuuu' Note 1003 select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t1` FOR SYSTEM_TIME AS OF TIMESTAMP current_timestamp(6) join `test`.`t2` FOR SYSTEM_TIME AS OF TIMESTAMP current_timestamp(6) where `test`.`t1`.`x` = `test`.`t2`.`x` and `test`.`t2`.`row_end` > <cache>(current_timestamp(6)) and `test`.`t2`.`row_start` <= <cache>(current_timestamp(6)) and `test`.`t1`.`row_end` > <cache>(current_timestamp(6)) and `test`.`t1`.`row_start` <= <cache>(current_timestamp(6))
Fine result: queries A and B are equal. Fine result: queries A and B are equal.
## LEFT JOIN: t1, t2 versioned ## LEFT JOIN: t1, t2 versioned
select * from ( select * from (

View file

@ -3272,7 +3272,7 @@ public:
bool zero_pack() const override { return false; } bool zero_pack() const override { return false; }
/* /*
This method is used by storage/perfschema and This method is used by storage/perfschema and
Item_func_now_local::save_in_field(). thd_get_query_start_data().
*/ */
void store_TIME(my_time_t ts, ulong sec_part) void store_TIME(my_time_t ts, ulong sec_part)
{ {

View file

@ -2752,6 +2752,26 @@ bool Type_std_attributes::agg_item_set_converter(const DTCollation &coll,
} }
bool
Item_func_or_sum
::check_fsp_or_error() const
{
if (decimals > TIME_SECOND_PART_DIGITS)
{
/*
Historically MariaDB raises ER_TOO_BIG_PRECISION
instead of ER_TOO_BIG_SCALE when checking fractional digits
of an SQL function. Perhaps should be fixed eventually.
*/
my_error(ER_TOO_BIG_PRECISION, MYF(0),
func_name(), TIME_SECOND_PART_DIGITS);
return true;
}
return false;
}
/** /**
@brief @brief
Building clone for Item_func_or_sum Building clone for Item_func_or_sum

View file

@ -5601,6 +5601,8 @@ class Item_func_or_sum: public Item_result_field,
public Used_tables_and_const_cache public Used_tables_and_const_cache
{ {
protected: protected:
bool check_fsp_or_error() const;
bool agg_arg_charsets(DTCollation &c, Item **items, uint nitems, bool agg_arg_charsets(DTCollation &c, Item **items, uint nitems,
uint flags, int item_sep) uint flags, int item_sep)
{ {

View file

@ -1255,6 +1255,15 @@ bool Item_func_unix_timestamp::get_timestamp_value(my_time_t *seconds,
Timestamp tm(native); Timestamp tm(native);
*seconds= (my_time_t) tm.tv_sec; *seconds= (my_time_t) tm.tv_sec;
*second_part= tm.tv_usec; *second_part= tm.tv_usec;
if ((null_value= (tm.tv_sec == 0 && tm.tv_usec == 0)))
{
/*
The value {0,0}='1970-01-01 00:00:00.000000 GMT' cannot be
stored in a TIMESTAMP field. Return SQL NULL.
Simmetrically, UNIX_TIMESTAMP(0) also returns SQL NULL.
*/
return true;
}
return false; return false;
} }
@ -1536,6 +1545,17 @@ bool Item_func_from_days::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzz
} }
bool Item_func_current_timestamp::val_native(THD *thd, Native *to)
{
Timestamp ts(Timeval(thd->query_start(), thd->query_start_sec_part()));
/*
to_native() can fail in case of EOM. Don't set null_value on EOM,
because CURRENT_TIMESTAMP is NOT NULL. The statement will fail anyway.
*/
return ts.trunc(decimals).to_native(to, decimals);
}
/** /**
Converts current time in my_time_t to MYSQL_TIME representation for local Converts current time in my_time_t to MYSQL_TIME representation for local
time zone. Defines time zone (local) used for whole CURDATE function. time zone. Defines time zone (local) used for whole CURDATE function.
@ -1581,13 +1601,8 @@ bool Item_func_curdate::get_date(THD *thd, MYSQL_TIME *res,
bool Item_func_curtime::fix_fields(THD *thd, Item **items) bool Item_func_curtime::fix_fields(THD *thd, Item **items)
{ {
if (decimals > TIME_SECOND_PART_DIGITS) return check_fsp_or_error() ||
{ Item_timefunc::fix_fields(thd, items);
my_error(ER_TOO_BIG_PRECISION, MYF(0),
func_name(), TIME_SECOND_PART_DIGITS);
return 1;
}
return Item_timefunc::fix_fields(thd, items);
} }
bool Item_func_curtime::get_date(THD *thd, MYSQL_TIME *res, bool Item_func_curtime::get_date(THD *thd, MYSQL_TIME *res,
@ -1657,13 +1672,8 @@ void Item_func_curtime_utc::store_now_in_TIME(THD *thd, MYSQL_TIME *now_time)
bool Item_func_now::fix_fields(THD *thd, Item **items) bool Item_func_now::fix_fields(THD *thd, Item **items)
{ {
if (decimals > TIME_SECOND_PART_DIGITS) return check_fsp_or_error() ||
{ Item_datetimefunc::fix_fields(thd, items);
my_error(ER_TOO_BIG_PRECISION, MYF(0),
func_name(), TIME_SECOND_PART_DIGITS);
return 1;
}
return Item_datetimefunc::fix_fields(thd, items);
} }
void Item_func_now::print(String *str, enum_query_type query_type) void Item_func_now::print(String *str, enum_query_type query_type)
@ -1676,23 +1686,6 @@ void Item_func_now::print(String *str, enum_query_type query_type)
} }
int Item_func_now_local::save_in_field(Field *field, bool no_conversions)
{
if (field->type() == MYSQL_TYPE_TIMESTAMP)
{
THD *thd= field->get_thd();
my_time_t ts= thd->query_start();
ulong sec_part= decimals ? thd->query_start_sec_part() : 0;
sec_part-= my_time_fraction_remainder(sec_part, decimals);
field->set_notnull();
field->store_timestamp(ts, sec_part);
return 0;
}
else
return Item_datetimefunc::save_in_field(field, no_conversions);
}
/** /**
Converts current time in my_time_t to MYSQL_TIME representation for local Converts current time in my_time_t to MYSQL_TIME representation for local
time zone. Defines time zone (local) used for whole NOW function. time zone. Defines time zone (local) used for whole NOW function.
@ -1739,22 +1732,18 @@ bool Item_func_now::get_date(THD *thd, MYSQL_TIME *res,
Converts current time in my_time_t to MYSQL_TIME representation for local Converts current time in my_time_t to MYSQL_TIME representation for local
time zone. Defines time zone (local) used for whole SYSDATE function. time zone. Defines time zone (local) used for whole SYSDATE function.
*/ */
void Item_func_sysdate_local::store_now_in_TIME(THD *thd, MYSQL_TIME *now_time) bool Item_func_sysdate_local::val_native(THD *thd, Native *to)
{ {
my_hrtime_t now= my_hrtime(); my_hrtime_t now= my_hrtime();
thd->variables.time_zone->gmt_sec_to_TIME(now_time, hrtime_to_my_time(now)); Timestamp ts(hrtime_to_my_time(now), hrtime_sec_part(now));
set_sec_part(hrtime_sec_part(now), now_time, this); /*
thd->used|= THD::TIME_ZONE_USED; to_native() can fail on EOM. Don't set null_value here,
because SYSDATE is NOT NULL. The statement will fail anyway.
*/
return ts.trunc(decimals).to_native(to, decimals);
} }
bool Item_func_sysdate_local::get_date(THD *thd, MYSQL_TIME *res,
date_mode_t fuzzydate __attribute__((unused)))
{
store_now_in_TIME(thd, res);
return 0;
}
bool Item_func_sec_to_time::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate) bool Item_func_sec_to_time::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
{ {
DBUG_ASSERT(fixed()); DBUG_ASSERT(fixed());
@ -2766,7 +2755,6 @@ null_date:
bool Item_func_from_unixtime::fix_length_and_dec(THD *thd) bool Item_func_from_unixtime::fix_length_and_dec(THD *thd)
{ {
thd->used|= THD::TIME_ZONE_USED;
tz= thd->variables.time_zone; tz= thd->variables.time_zone;
Type_std_attributes::set( Type_std_attributes::set(
Type_temporal_attributes_not_fixed_dec(MAX_DATETIME_WIDTH, Type_temporal_attributes_not_fixed_dec(MAX_DATETIME_WIDTH,
@ -2777,26 +2765,36 @@ bool Item_func_from_unixtime::fix_length_and_dec(THD *thd)
} }
bool Item_func_from_unixtime::get_date(THD *thd, MYSQL_TIME *ltime, bool Item_func_from_unixtime::val_native(THD *thd, Native *to)
date_mode_t fuzzydate __attribute__((unused)))
{ {
bzero((char *)ltime, sizeof(*ltime));
ltime->time_type= MYSQL_TIMESTAMP_TIME;
VSec9 sec(thd, args[0], "unixtime", TIMESTAMP_MAX_VALUE); VSec9 sec(thd, args[0], "unixtime", TIMESTAMP_MAX_VALUE);
DBUG_ASSERT(sec.is_null() || sec.sec() <= TIMESTAMP_MAX_VALUE); DBUG_ASSERT(sec.is_null() || sec.sec() <= TIMESTAMP_MAX_VALUE);
if (sec.is_null() || sec.truncated() || sec.neg()) if (sec.is_null() || sec.truncated() || sec.neg())
return (null_value= 1); return (null_value= 1);
sec.round(MY_MIN(decimals, TIME_SECOND_PART_DIGITS), thd->temporal_round_mode()); // decimals can be NOT_FIXED_DEC
decimal_digits_t fixed_decimals= MY_MIN(decimals, TIME_SECOND_PART_DIGITS);
sec.round(fixed_decimals, thd->temporal_round_mode());
if (sec.sec() == 0 && sec.usec() == 0)
{
/*
The value {0,0}='1970-01-01 00:00:00.000000 GMT' cannot be
stored in a TIMESTAMP field. Return SQL NULL.
Simmetrically, UNIX_TIMESTAMP('1970-01-01 00:00:00')
also returns SQL NULL (assuming time_zone='+00:00').
*/
thd->push_warning_truncated_wrong_value("unixtime", "0.0");
return (null_value= true); // 0.0 after rounding
}
if (sec.sec() > TIMESTAMP_MAX_VALUE) if (sec.sec() > TIMESTAMP_MAX_VALUE)
return (null_value= true); // Went out of range after rounding return (null_value= true); // Went out of range after rounding
tz->gmt_sec_to_TIME(ltime, (my_time_t) sec.sec()); const Timestamp ts(Timeval(sec.sec(), sec.usec()));
ltime->second_part= sec.usec(); return null_value= ts.to_native(to, fixed_decimals);
return (null_value= 0);
} }

View file

@ -708,6 +708,50 @@ public:
}; };
class Item_timestampfunc: public Item_func
{
protected:
Datetime to_datetime(THD *thd)
{
return Timestamp_or_zero_datetime_native_null(thd, this).to_datetime(thd);
}
public:
Item_timestampfunc(THD *thd) :Item_func(thd) {}
Item_timestampfunc(THD *thd, uint dec) :Item_func(thd) { decimals= dec; }
Item_timestampfunc(THD *thd, Item *a) :Item_func(thd, a) {}
const Type_handler *type_handler() const override
{ return &type_handler_timestamp2; }
bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate) override
{
return null_value= to_datetime(thd).copy_to_mysql_time(ltime);
}
double val_real() override
{
const Datetime dt= to_datetime(current_thd);
null_value= !dt.is_valid_datetime();
return dt.to_double();
}
longlong val_int() override
{
const Datetime dt= to_datetime(current_thd);
null_value= !dt.is_valid_datetime();
return dt.to_longlong();
}
my_decimal *val_decimal(my_decimal *to) override
{
const Datetime dt= to_datetime(current_thd);
null_value= !dt.is_valid_datetime();
return dt.to_decimal(to);
}
String *val_str(String *to) override
{
const Datetime dt= to_datetime(current_thd);
null_value= !dt.is_valid_datetime();
return dt.to_string(to, decimals);
}
};
/* Abstract CURTIME function. Children should define what time zone is used */ /* Abstract CURTIME function. Children should define what time zone is used */
class Item_func_curtime :public Item_timefunc class Item_func_curtime :public Item_timefunc
@ -838,18 +882,53 @@ public:
}; };
class Item_func_current_timestamp: public Item_timestampfunc
{
public:
Item_func_current_timestamp(THD *thd, uint dec)
:Item_timestampfunc(thd, dec)
{ }
LEX_CSTRING func_name_cstring() const override
{
static LEX_CSTRING name= {STRING_WITH_LEN("current_timestamp") };
return name;
}
void print(String *str, enum_query_type query_type) override
{
str->append(func_name_cstring());
str->append('(');
if (decimals)
str->append_ulonglong(decimals);
str->append(')');
}
bool fix_length_and_dec(THD *thd) override
{
if (check_fsp_or_error())
return true;
fix_attributes_datetime(decimals);
return false;
}
bool val_native(THD *thd, Native *to) override;
bool check_vcol_func_processor(void *arg) override
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_TIME_FUNC);
}
enum Functype functype() const override { return NOW_FUNC; }
Item *do_get_copy(THD *thd) const override
{ return get_item_copy<Item_func_current_timestamp>(thd, this); }
};
class Item_func_now_local :public Item_func_now class Item_func_now_local :public Item_func_now
{ {
public: public:
Item_func_now_local(THD *thd, uint dec): Item_func_now(thd, dec) {} Item_func_now_local(THD *thd, uint dec): Item_func_now(thd, dec) {}
LEX_CSTRING func_name_cstring() const override LEX_CSTRING func_name_cstring() const override
{ {
static LEX_CSTRING name= {STRING_WITH_LEN("current_timestamp") }; static LEX_CSTRING name= {STRING_WITH_LEN("localtimestamp") };
return name; return name;
} }
int save_in_field(Field *field, bool no_conversions) override;
void store_now_in_TIME(THD *thd, MYSQL_TIME *now_time) override; void store_now_in_TIME(THD *thd, MYSQL_TIME *now_time) override;
enum Functype functype() const override { return NOW_FUNC; }
Item *do_get_copy(THD *thd) const override Item *do_get_copy(THD *thd) const override
{ return get_item_copy<Item_func_now_local>(thd, this); } { return get_item_copy<Item_func_now_local>(thd, this); }
}; };
@ -880,18 +959,34 @@ public:
This is like NOW(), but always uses the real current time, not the This is like NOW(), but always uses the real current time, not the
query_start(). This matches the Oracle behavior. query_start(). This matches the Oracle behavior.
*/ */
class Item_func_sysdate_local :public Item_func_now class Item_func_sysdate_local :public Item_timestampfunc
{ {
public: public:
Item_func_sysdate_local(THD *thd, uint dec): Item_func_now(thd, dec) {} Item_func_sysdate_local(THD *thd, uint dec)
:Item_timestampfunc(thd, dec)
{ }
bool const_item() const override { return 0; } bool const_item() const override { return 0; }
LEX_CSTRING func_name_cstring() const override LEX_CSTRING func_name_cstring() const override
{ {
static LEX_CSTRING name= {STRING_WITH_LEN("sysdate") }; static LEX_CSTRING name= {STRING_WITH_LEN("sysdate") };
return name; return name;
} }
void store_now_in_TIME(THD *thd, MYSQL_TIME *now_time) override; void print(String *str, enum_query_type query_type) override
bool get_date(THD *thd, MYSQL_TIME *res, date_mode_t fuzzydate) override; {
str->append(func_name_cstring());
str->append('(');
if (decimals)
str->append_ulonglong(decimals);
str->append(')');
}
bool fix_length_and_dec(THD *thd) override
{
if (check_fsp_or_error())
return true;
fix_attributes_datetime(decimals);
return false;
}
bool val_native(THD *thd, Native *to) override;
table_map used_tables() const override { return RAND_TABLE_BIT; } table_map used_tables() const override { return RAND_TABLE_BIT; }
bool check_vcol_func_processor(void *arg) override bool check_vcol_func_processor(void *arg) override
{ {
@ -1033,20 +1128,20 @@ public:
}; };
class Item_func_from_unixtime :public Item_datetimefunc class Item_func_from_unixtime :public Item_timestampfunc
{ {
bool check_arguments() const override bool check_arguments() const override
{ return args[0]->check_type_can_return_decimal(func_name_cstring()); } { return args[0]->check_type_can_return_decimal(func_name_cstring()); }
Time_zone *tz; Time_zone *tz;
public: public:
Item_func_from_unixtime(THD *thd, Item *a): Item_datetimefunc(thd, a) {} Item_func_from_unixtime(THD *thd, Item *a): Item_timestampfunc(thd, a) {}
LEX_CSTRING func_name_cstring() const override LEX_CSTRING func_name_cstring() const override
{ {
static LEX_CSTRING name= {STRING_WITH_LEN("from_unixtime") }; static LEX_CSTRING name= {STRING_WITH_LEN("from_unixtime") };
return name; return name;
} }
bool fix_length_and_dec(THD *thd) override; bool fix_length_and_dec(THD *thd) override;
bool get_date(THD *thd, MYSQL_TIME *res, date_mode_t fuzzydate) override; bool val_native(THD *thd, Native *to) override;
bool check_vcol_func_processor(void *arg) override bool check_vcol_func_processor(void *arg) override
{ {
return mark_unsupported_function(func_name(), "()", arg, VCOL_SESSION_FUNC); return mark_unsupported_function(func_name(), "()", arg, VCOL_SESSION_FUNC);

View file

@ -353,7 +353,7 @@ SYMBOL symbols[] = {
{ "LOAD", SYM(LOAD)}, { "LOAD", SYM(LOAD)},
{ "LOCAL", SYM(LOCAL_SYM)}, { "LOCAL", SYM(LOCAL_SYM)},
{ "LOCALTIME", SYM(CURTIME)}, { "LOCALTIME", SYM(CURTIME)},
{ "LOCALTIMESTAMP", SYM(NOW_SYM)}, { "LOCALTIMESTAMP", SYM(LOCALTIMESTAMP)},
{ "LOCK", SYM(LOCK_SYM)}, { "LOCK", SYM(LOCK_SYM)},
{ "LOCKED", SYM(LOCKED_SYM)}, { "LOCKED", SYM(LOCKED_SYM)},
{ "LOCKS", SYM(LOCKS_SYM)}, { "LOCKS", SYM(LOCKS_SYM)},

View file

@ -9613,7 +9613,7 @@ Item *LEX::make_item_func_sysdate(THD *thd, uint fsp)
set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION); set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION);
Item *item= global_system_variables.sysdate_is_now == 0 ? Item *item= global_system_variables.sysdate_is_now == 0 ?
(Item *) new (thd->mem_root) Item_func_sysdate_local(thd, fsp) : (Item *) new (thd->mem_root) Item_func_sysdate_local(thd, fsp) :
(Item *) new (thd->mem_root) Item_func_now_local(thd, fsp); (Item *) new (thd->mem_root) Item_func_current_timestamp(thd, fsp);
if (unlikely(item == NULL)) if (unlikely(item == NULL))
return NULL; return NULL;
safe_to_cache_query=0; safe_to_cache_query=0;

View file

@ -468,7 +468,10 @@ bool Timestamp::to_native(Native *to, uint decimals) const
{ {
uint len= my_timestamp_binary_length(decimals); uint len= my_timestamp_binary_length(decimals);
if (to->reserve(len)) if (to->reserve(len))
{
to->length(0); // Safety: set to '0000-00-00 00:00:00' on falures
return true; return true;
}
my_timestamp_to_binary(this, (uchar *) to->ptr(), decimals); my_timestamp_to_binary(this, (uchar *) to->ptr(), decimals);
to->length(len); to->length(len);
return false; return false;

View file

@ -1340,7 +1340,7 @@ public:
{ {
return is_valid_temporal() ? TIME_to_double(this) : 0; return is_valid_temporal() ? TIME_to_double(this) : 0;
} }
my_decimal *to_decimal(my_decimal *to) my_decimal *to_decimal(my_decimal *to) const
{ {
return is_valid_temporal() ? Temporal::to_decimal(to) : bad_to_decimal(to); return is_valid_temporal() ? Temporal::to_decimal(to) : bad_to_decimal(to);
} }
@ -1987,7 +1987,7 @@ public:
str->length(my_time_to_str(this, const_cast<char*>(str->ptr()), dec)); str->length(my_time_to_str(this, const_cast<char*>(str->ptr()), dec));
return str; return str;
} }
my_decimal *to_decimal(my_decimal *to) my_decimal *to_decimal(my_decimal *to) const
{ {
return is_valid_time() ? Temporal::to_decimal(to) : bad_to_decimal(to); return is_valid_time() ? Temporal::to_decimal(to) : bad_to_decimal(to);
} }
@ -2342,7 +2342,7 @@ public:
str->length(my_date_to_str(this, const_cast<char*>(str->ptr()))); str->length(my_date_to_str(this, const_cast<char*>(str->ptr())));
return str; return str;
} }
my_decimal *to_decimal(my_decimal *to) my_decimal *to_decimal(my_decimal *to) const
{ {
return is_valid_date() ? Temporal::to_decimal(to) : bad_to_decimal(to); return is_valid_date() ? Temporal::to_decimal(to) : bad_to_decimal(to);
} }
@ -2663,7 +2663,7 @@ public:
str->length(my_datetime_to_str(this, const_cast<char*>(str->ptr()), dec)); str->length(my_datetime_to_str(this, const_cast<char*>(str->ptr()), dec));
return str; return str;
} }
my_decimal *to_decimal(my_decimal *to) my_decimal *to_decimal(my_decimal *to) const
{ {
return is_valid_datetime() ? Temporal::to_decimal(to) : bad_to_decimal(to); return is_valid_datetime() ? Temporal::to_decimal(to) : bad_to_decimal(to);
} }

View file

@ -572,6 +572,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%token <kwd> LINEAR_SYM %token <kwd> LINEAR_SYM
%token <kwd> LINES %token <kwd> LINES
%token <kwd> LOAD %token <kwd> LOAD
%token <kwd> LOCALTIMESTAMP /* SQL-2003-R */
%token <kwd> LOCATOR_SYM /* SQL-2003-N */ %token <kwd> LOCATOR_SYM /* SQL-2003-N */
%token <kwd> LOCK_SYM %token <kwd> LOCK_SYM
%token <kwd> LONGBLOB %token <kwd> LONGBLOB
@ -3097,7 +3098,7 @@ opt_ev_status:
ev_starts: ev_starts:
/* empty */ /* empty */
{ {
Item *item= new (thd->mem_root) Item_func_now_local(thd, 0); Item *item= new (thd->mem_root) Item_func_current_timestamp(thd, 0);
if (unlikely(item == NULL)) if (unlikely(item == NULL))
MYSQL_YYABORT; MYSQL_YYABORT;
Lex->event_parse_data->item_starts= item; Lex->event_parse_data->item_starts= item;
@ -6678,7 +6679,7 @@ attribute:
} }
| ON UPDATE_SYM NOW_SYM opt_default_time_precision | ON UPDATE_SYM NOW_SYM opt_default_time_precision
{ {
Item *item= new (thd->mem_root) Item_func_now_local(thd, $4); Item *item= new (thd->mem_root) Item_func_current_timestamp(thd, $4);
if (unlikely(item == NULL)) if (unlikely(item == NULL))
MYSQL_YYABORT; MYSQL_YYABORT;
Lex->last_field->on_update= item; Lex->last_field->on_update= item;
@ -10500,9 +10501,16 @@ function_call_nonkeyword:
if (unlikely($$ == NULL)) if (unlikely($$ == NULL))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| NOW_SYM opt_time_precision | LOCALTIMESTAMP opt_time_precision
{ {
$$= new (thd->mem_root) Item_func_now_local(thd, $2); $$= new (thd->mem_root) Item_func_now_local(thd, $2);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
Lex->safe_to_cache_query= false;
}
| NOW_SYM opt_time_precision
{
$$= new (thd->mem_root) Item_func_current_timestamp(thd, $2);
if (unlikely($$ == NULL)) if (unlikely($$ == NULL))
MYSQL_YYABORT; MYSQL_YYABORT;
Lex->safe_to_cache_query=0; Lex->safe_to_cache_query=0;