From dfdedd46e4a48b7cf9ffdda5243828fa49e99352 Mon Sep 17 00:00:00 2001 From: Monty Date: Mon, 11 Sep 2023 17:58:22 +0300 Subject: [PATCH] MDEV-32188 make TIMESTAMP use whole 32-bit unsigned range This patch extends the timestamp from 2038-01-19 03:14:07.999999 to 2106-02-07 06:28:15.999999 for 64 bit hardware and OS where 'long' is 64 bits. This is true for 64 bit Linux but not for Windows. This is done by treating the 32 bit stored int as unsigned instead of signed. This is safe as MariaDB has never accepted dates before the epoch (1970). The benefit of this approach that for normal timestamp the storage is compatible with earlier version. However for tables using system versioning we before stored a timestamp with the year 2038 as the 'max timestamp', which is used to detect current values. This patch stores the new 2106 year max value as the max timestamp. This means that old tables using system versioning needs to be updated with mariadb-upgrade when moving them to 11.4. That will be done in a separate commit. --- extra/mariabackup/xtrabackup.cc | 2 +- include/my_global.h | 2 +- include/my_time.h | 22 ++- include/mysql_time.h | 5 +- libmysqld/libmysql.c | 4 +- mysql-test/include/grep.inc | 10 +- mysql-test/include/have_32bit_timestamp.inc | 7 + mysql-test/include/have_64bit_timestamp.inc | 7 + mysql-test/include/show_events.inc | 2 + mysql-test/main/alter_table_online_debug.test | 1 + mysql-test/main/func_time.result | 22 --- mysql-test/main/func_time.test | 8 - mysql-test/main/func_time_32.result | 120 ++++++++++++++ mysql-test/main/func_time_32.test | 90 ++++++++++ mysql-test/main/func_time_64.result | 156 ++++++++++++++++++ mysql-test/main/func_time_64.test | 108 ++++++++++++ mysql-test/main/func_time_round.result | 4 +- mysql-test/main/func_time_round.test | 3 +- mysql-test/main/partition_datatype.result | 82 ++++----- mysql-test/main/partition_datatype.test | 6 +- mysql-test/main/partition_datatype_32.result | 69 ++++++++ mysql-test/main/partition_datatype_32.test | 52 ++++++ mysql-test/main/partition_datatype_64.result | 84 ++++++++++ mysql-test/main/partition_datatype_64.test | 56 +++++++ mysql-test/main/timezone.result | 8 +- mysql-test/main/timezone.test | 4 +- mysql-test/main/timezone2.result | 18 +- mysql-test/main/timezone2.test | 8 +- mysql-test/main/type_timestamp,32bit.rdiff | 145 ++++++++++++++++ mysql-test/main/type_timestamp.result | 35 ++-- mysql-test/main/type_timestamp.test | 4 +- mysql-test/main/type_timestamp_round.result | 12 -- mysql-test/main/type_timestamp_round.test | 5 - mysql-test/main/variables.result | 6 +- mysql-test/main/variables.test | 4 +- .../suite/sys_vars/inc/sysvars_server.inc | 2 +- .../sys_vars/r/sysvars_server_embedded.result | 12 +- .../r/sysvars_server_notembedded.result | 12 +- .../suite/sys_vars/t/timestamp_basic.test | 1 + mysql-test/suite/versioning/common.inc | 4 +- mysql-test/suite/versioning/r/cte,32bit.rdiff | 11 ++ mysql-test/suite/versioning/r/cte.result | 2 +- mysql-test/suite/versioning/r/data.result | 4 +- .../versioning/r/delete_history,32bit.rdiff | 11 ++ .../suite/versioning/r/delete_history.result | 2 +- mysql-test/suite/versioning/r/insert.result | 14 +- mysql-test/suite/versioning/r/insert2.result | 4 +- mysql-test/suite/versioning/r/misc.result | 16 +- .../suite/versioning/r/partition.result | 6 +- mysql-test/suite/versioning/r/rpl_row.result | 4 +- mysql-test/suite/versioning/r/select.result | 6 +- mysql-test/suite/versioning/r/trx_id.result | 4 +- mysql-test/suite/versioning/sys_time.inc | 12 ++ mysql-test/suite/versioning/t/cte.test | 4 +- mysql-test/suite/versioning/t/data.test | 1 + .../suite/versioning/t/delete_history.test | 1 + mysql-test/suite/versioning/t/foreign.test | 1 + mysql-test/suite/versioning/t/insert.test | 14 +- mysql-test/suite/versioning/t/insert2.test | 8 +- mysql-test/suite/versioning/t/misc.test | 5 + mysql-test/suite/versioning/t/partition.test | 10 +- mysql-test/suite/versioning/t/rpl_row.test | 3 + mysql-test/suite/versioning/t/select.test | 6 +- mysql-test/suite/versioning/t/select2.test | 2 +- mysql-test/suite/versioning/t/trx_id.test | 4 +- mysql-test/suite/versioning/t/view.test | 2 +- sql-common/my_time.c | 44 +++-- sql/event_queue.cc | 2 +- sql/field.cc | 40 ++--- sql/item_strfunc.cc | 2 +- sql/item_timefunc.cc | 3 +- sql/mysqld.cc | 2 + sql/opt_histogram_json.cc | 3 +- sql/partition_info.cc | 6 +- sql/rpl_parallel.cc | 2 +- sql/rpl_rli.h | 4 +- sql/share/errmsg-utf8.txt | 6 +- sql/slave.cc | 7 +- sql/sql_acl.cc | 3 +- sql/sql_analyse.cc | 7 +- sql/sql_base.cc | 9 +- sql/sql_partition.cc | 10 +- sql/sql_type.cc | 2 +- sql/table.cc | 2 +- sql/tztime.cc | 42 ++--- storage/innobase/dict/dict0mem.cc | 2 +- storage/innobase/fts/fts0fts.cc | 7 +- storage/innobase/include/data0data.h | 2 +- storage/innobase/include/dict0types.h | 5 + storage/innobase/trx/trx0trx.cc | 10 +- 90 files changed, 1227 insertions(+), 354 deletions(-) create mode 100644 mysql-test/include/have_32bit_timestamp.inc create mode 100644 mysql-test/include/have_64bit_timestamp.inc create mode 100644 mysql-test/main/func_time_32.result create mode 100644 mysql-test/main/func_time_32.test create mode 100644 mysql-test/main/func_time_64.result create mode 100644 mysql-test/main/func_time_64.test create mode 100644 mysql-test/main/partition_datatype_32.result create mode 100644 mysql-test/main/partition_datatype_32.test create mode 100644 mysql-test/main/partition_datatype_64.result create mode 100644 mysql-test/main/partition_datatype_64.test create mode 100644 mysql-test/main/type_timestamp,32bit.rdiff create mode 100644 mysql-test/suite/versioning/r/cte,32bit.rdiff create mode 100644 mysql-test/suite/versioning/r/delete_history,32bit.rdiff create mode 100644 mysql-test/suite/versioning/sys_time.inc diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index c4cb0fa3cb2..6d784220e71 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -2404,7 +2404,7 @@ static bool innodb_init_param() /* Check that values don't overflow on 32-bit systems. */ if (sizeof(ulint) == 4) { - if (xtrabackup_use_memory > (longlong) UINT_MAX32) { + if (xtrabackup_use_memory > (longlong) UINT_MAX32) { msg("mariabackup: use-memory can't be over 4GB" " on 32-bit systems"); } diff --git a/include/my_global.h b/include/my_global.h index e6cbb933401..a7b8df7dc78 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -782,7 +782,7 @@ inline unsigned long long my_double2ulonglong(double d) #define INT_MAX64 0x7FFFFFFFFFFFFFFFLL #define INT_MIN32 (~0x7FFFFFFFL) #define INT_MAX32 0x7FFFFFFFL -#define UINT_MAX32 0xFFFFFFFFL +#define UINT_MAX32 0xFFFFFFFFUL #define INT_MIN24 (~0x007FFFFF) #define INT_MAX24 0x007FFFFF #define UINT_MAX24 0x00FFFFFF diff --git a/include/my_time.h b/include/my_time.h index 9f3e61b944f..0ad1b02bfd7 100644 --- a/include/my_time.h +++ b/include/my_time.h @@ -30,15 +30,26 @@ C_MODE_START extern MYSQL_PLUGIN_IMPORT ulonglong log_10_int[20]; extern uchar days_in_month[]; +#if SIZEOF_LONG == 4 #define MY_TIME_T_MAX LONG_MAX #define MY_TIME_T_MIN LONG_MIN - -/* Time handling defaults */ #define TIMESTAMP_MAX_YEAR 2038 -#define TIMESTAMP_MIN_YEAR (1900 + YY_PART_YEAR - 1) +#define TIMESTAMP_MAX_MONTH 1 +#define TIMESTAMP_MAX_DAY 19 #define TIMESTAMP_MAX_VALUE INT_MAX32 #define TIMESTAMP_MIN_VALUE 0 +#else +/* Use 4 byte unsigned timestamp */ +#define MY_TIME_T_MAX ((longlong) UINT_MAX32) +#define MY_TIME_T_MIN 0 +#define TIMESTAMP_MAX_YEAR 2106 +#define TIMESTAMP_MIN_VALUE 0 +#define TIMESTAMP_MAX_VALUE ((longlong) UINT_MAX32) +#define TIMESTAMP_MAX_MONTH 2 +#define TIMESTAMP_MAX_DAY 7 +#endif /* SIZEOF_LONG */ +#define TIMESTAMP_MIN_YEAR (1900 + YY_PART_YEAR - 1) /* two-digit years < this are 20..; >= this are 19.. */ #define YY_PART_YEAR 70 @@ -48,8 +59,8 @@ extern uchar days_in_month[]; */ #if SIZEOF_TIME_T > 4 || defined(TIME_T_UNSIGNED) # define IS_TIME_T_VALID_FOR_TIMESTAMP(x) \ - ((x) <= TIMESTAMP_MAX_VALUE && \ - (x) >= TIMESTAMP_MIN_VALUE) + ((ulonglong) (x) <= TIMESTAMP_MAX_VALUE && \ + ((x) >= TIMESTAMP_MIN_VALUE) #else # define IS_TIME_T_VALID_FOR_TIMESTAMP(x) \ ((x) >= TIMESTAMP_MIN_VALUE) @@ -181,7 +192,6 @@ void my_init_time(void); static inline my_bool validate_timestamp_range(const MYSQL_TIME *t) { if ((t->year > TIMESTAMP_MAX_YEAR || t->year < TIMESTAMP_MIN_YEAR) || - (t->year == TIMESTAMP_MAX_YEAR && (t->month > 1 || t->day > 19)) || (t->year == TIMESTAMP_MIN_YEAR && (t->month < 12 || t->day < 31))) return FALSE; diff --git a/include/mysql_time.h b/include/mysql_time.h index ef78441ba40..a5e04645c5c 100644 --- a/include/mysql_time.h +++ b/include/mysql_time.h @@ -19,15 +19,14 @@ /* Portable time_t replacement. - Should be signed and hold seconds for 1902 -- 2038-01-19 range - i.e at least a 32bit variable + For 32 bit systems holds seconds for 1970 - 2038-01-19 range + For 64 bit systems (where long is 64 bit) holds seconds for 1970 - 2106 Using the system built in time_t is not an option as we rely on the above requirements in the time functions */ typedef long my_time_t; - /* Time declarations shared between the server and client API: you should not add anything to this header unless it's used diff --git a/libmysqld/libmysql.c b/libmysqld/libmysql.c index da6f3a2d8fa..84b45e14435 100644 --- a/libmysqld/libmysql.c +++ b/libmysqld/libmysql.c @@ -1314,8 +1314,8 @@ static my_bool reset_stmt_handle(MYSQL_STMT *stmt, uint flags); /* A macro to check truncation errors */ #define IS_TRUNCATED(value, is_unsigned, min, max, umax) \ - ((is_unsigned) ? (((value) > (umax) || (value) < 0) ? 1 : 0) : \ - (((value) > (max) || (value) < (min)) ? 1 : 0)) + ((is_unsigned) ? (( (value) > (umax)) ? 1 : 0) : \ + (((value) > (max) || (value) < (min)) ? 1 : 0)) #define BIND_RESULT_DONE 1 /* diff --git a/mysql-test/include/grep.inc b/mysql-test/include/grep.inc index 9ce7cddb7b7..ea485bbfe22 100644 --- a/mysql-test/include/grep.inc +++ b/mysql-test/include/grep.inc @@ -3,14 +3,22 @@ # Usage: # --let $grep_file= /path/to/your/file # --let $grep_regex= your_regex_string +# --let $grep_filter= filter # --source include/grep.inc + --perl open (my $fh, "<", "$ENV{grep_file}") or die $!; while (<$fh>) { - /$ENV{grep_regex}/ && + if (/$ENV{grep_regex}/) + { + if ($ENV{grep_filter}) + { + eval($ENV{grep_filter}); + } print; + } } close $fh; EOF diff --git a/mysql-test/include/have_32bit_timestamp.inc b/mysql-test/include/have_32bit_timestamp.inc new file mode 100644 index 00000000000..523fb128280 --- /dev/null +++ b/mysql-test/include/have_32bit_timestamp.inc @@ -0,0 +1,7 @@ +disable_query_log; +disable_warnings; +if (`SELECT from_unixtime((1<<31)+24*3600) is not null`) { +--skip Need a 32 bit timestamps +} +enable_warnings; +enable_query_log; diff --git a/mysql-test/include/have_64bit_timestamp.inc b/mysql-test/include/have_64bit_timestamp.inc new file mode 100644 index 00000000000..d2593acc9b3 --- /dev/null +++ b/mysql-test/include/have_64bit_timestamp.inc @@ -0,0 +1,7 @@ +disable_query_log; +disable_warnings; +if (`SELECT from_unixtime((1<<31)+24*3600) is null`) { +--skip Need a 64 bit timestamps +} +enable_warnings; +enable_query_log; diff --git a/mysql-test/include/show_events.inc b/mysql-test/include/show_events.inc index 9df12b2304b..d0bc923dc02 100644 --- a/mysql-test/include/show_events.inc +++ b/mysql-test/include/show_events.inc @@ -117,6 +117,8 @@ let $script= s{SONAME ".*"}{SONAME "LIB"}; s{DOLLARmysqltest_vardir}{MYSQLTEST_VARDIR}g; s{$binlog_database}{database}; + s{2147483647.999999}{MAX_TIMESTAMP}; + s{4294967295.999999}{MAX_TIMESTAMP}; $modify_binlog_name || diff --git a/mysql-test/main/alter_table_online_debug.test b/mysql-test/main/alter_table_online_debug.test index 64b73157a2f..f3917c9018b 100644 --- a/mysql-test/main/alter_table_online_debug.test +++ b/mysql-test/main/alter_table_online_debug.test @@ -582,6 +582,7 @@ set debug_sync= 'now SIGNAL end'; --connection default --reap show create table t1; +--replace_result 4294967295 2147483647 select *, UNIX_TIMESTAMP(row_start), UNIX_TIMESTAMP(row_end) from t1 for system_time all; ## at the moment DROP SYSTEM VERSIONING cannot be done online diff --git a/mysql-test/main/func_time.result b/mysql-test/main/func_time.result index 2fb60e330ba..ad396806a27 100644 --- a/mysql-test/main/func_time.result +++ b/mysql-test/main/func_time.result @@ -581,37 +581,18 @@ NULL select from_unixtime(2147483647); from_unixtime(2147483647) 2038-01-19 06:14:07 -select from_unixtime(2147483648); -from_unixtime(2147483648) -NULL -Warnings: -Warning 1292 Truncated incorrect unixtime value: '2147483648' select from_unixtime(0); from_unixtime(0) 1970-01-01 03:00:00 select unix_timestamp(from_unixtime(2147483647)); unix_timestamp(from_unixtime(2147483647)) 2147483647 -select unix_timestamp(from_unixtime(2147483648)); -unix_timestamp(from_unixtime(2147483648)) -NULL -Warnings: -Warning 1292 Truncated incorrect unixtime value: '2147483648' -select unix_timestamp('2039-01-20 01:00:00'); -unix_timestamp('2039-01-20 01:00:00') -NULL select unix_timestamp('1968-01-20 01:00:00'); unix_timestamp('1968-01-20 01:00:00') NULL -select unix_timestamp('2038-02-10 01:00:00'); -unix_timestamp('2038-02-10 01:00:00') -NULL select unix_timestamp('1969-11-20 01:00:00'); unix_timestamp('1969-11-20 01:00:00') NULL -select unix_timestamp('2038-01-20 01:00:00'); -unix_timestamp('2038-01-20 01:00:00') -NULL select unix_timestamp('1969-12-30 01:00:00'); unix_timestamp('1969-12-30 01:00:00') NULL @@ -621,9 +602,6 @@ unix_timestamp('2038-01-17 12:00:00') select unix_timestamp('1970-01-01 03:00:01'); unix_timestamp('1970-01-01 03:00:01') 1 -select unix_timestamp('2038-01-19 07:14:07'); -unix_timestamp('2038-01-19 07:14:07') -NULL SELECT CHARSET(DAYNAME(19700101)); CHARSET(DAYNAME(19700101)) latin1 diff --git a/mysql-test/main/func_time.test b/mysql-test/main/func_time.test index caf6ec1c6cf..757dafb55c8 100644 --- a/mysql-test/main/func_time.test +++ b/mysql-test/main/func_time.test @@ -276,7 +276,6 @@ select unix_timestamp('1969-12-01 19:00:01'); select from_unixtime(-1); # check for from_unixtime(2^31-1) and from_unixtime(2^31) select from_unixtime(2147483647); -select from_unixtime(2147483648); select from_unixtime(0); # @@ -285,18 +284,14 @@ select from_unixtime(0); # unix_timestamp are consistent, when working with boundary dates. # select unix_timestamp(from_unixtime(2147483647)); -select unix_timestamp(from_unixtime(2147483648)); # check for invalid dates # bad year -select unix_timestamp('2039-01-20 01:00:00'); select unix_timestamp('1968-01-20 01:00:00'); # bad month -select unix_timestamp('2038-02-10 01:00:00'); select unix_timestamp('1969-11-20 01:00:00'); # bad day -select unix_timestamp('2038-01-20 01:00:00'); select unix_timestamp('1969-12-30 01:00:00'); # @@ -310,9 +305,6 @@ select unix_timestamp('2038-01-17 12:00:00'); # select unix_timestamp('1970-01-01 03:00:01'); -# check bad date, close to the boundary (we cut them off in the very end) -select unix_timestamp('2038-01-19 07:14:07'); - # # Bug #28759: DAYNAME() and MONTHNAME() return binary string # diff --git a/mysql-test/main/func_time_32.result b/mysql-test/main/func_time_32.result new file mode 100644 index 00000000000..8832a92df44 --- /dev/null +++ b/mysql-test/main/func_time_32.result @@ -0,0 +1,120 @@ +# +# Test dates close to upper range +# +set time_zone="+03:00"; +select from_unixtime(2147483648); +from_unixtime(2147483648) +NULL +Warnings: +Warning 1292 Truncated incorrect unixtime value: '2147483648' +select unix_timestamp(from_unixtime(2147483648)); +unix_timestamp(from_unixtime(2147483648)) +NULL +Warnings: +Warning 1292 Truncated incorrect unixtime value: '2147483648' +# bad year +select unix_timestamp('2039-01-20 01:00:00'); +unix_timestamp('2039-01-20 01:00:00') +NULL +# bad month +select unix_timestamp('2038-02-10 01:00:00'); +unix_timestamp('2038-02-10 01:00:00') +NULL +# bad day +select unix_timestamp('2038-01-20 01:00:00'); +unix_timestamp('2038-01-20 01:00:00') +NULL +# check bad date, close to the boundary (we cut them off in the very end) +select unix_timestamp('2038-01-19 07:14:07'); +unix_timestamp('2038-01-19 07:14:07') +NULL +set time_zone=MET; +select unix_timestamp('2038-01-19 04:14:07'), +unix_timestamp('2038-01-19 04:14:08'); +unix_timestamp('2038-01-19 04:14:07') unix_timestamp('2038-01-19 04:14:08') +2147483647 NULL +set time_zone= @@global.time_zone; +# +# Functions that construct DATETIME +# +SET time_zone='+00:00'; +SET sql_mode=IF(@@version LIKE '%MariaDB%', 'TIME_ROUND_FRACTIONAL', ''); +CREATE TABLE t1 (id SERIAL, a DECIMAL(30,10)); +INSERT INTO t1 (a) VALUES (2147483647.9999999); +SELECT a, FROM_UNIXTIME(a) FROM t1 ORDER BY id; +a FROM_UNIXTIME(a) +2147483647.9999999000 NULL +DROP TABLE t1; +set time_zone= @@global.time_zone; +set sql_mode=default; +# +# Corner case: +# ALTER TIMESTAMP to a shorter TIMESTAMP +# All values round, maximum possible value truncates. +# +SET time_zone='+00:00'; +SET sql_mode=IF(@@version LIKE '%MariaDB%', 'TIME_ROUND_FRACTIONAL', ''); +CREATE TABLE t1 (ID INT, a TIMESTAMP(6), comment VARCHAR(64)); +INSERT INTO t1 VALUES (0, '2038-01-18 23:59:59.999999', 'Should round'); +INSERT INTO t1 VALUES (1, '2038-01-19 03:14:06.999999', 'Should round'); +INSERT INTO t1 VALUES (2, '2038-01-19 03:14:07.999999', 'Should truncate'); +ALTER TABLE t1 MODIFY a TIMESTAMP(5); +Warnings: +Warning 1264 Out of range value for column 'a' at row 3 +SELECT * FROM t1; +ID a comment +0 2038-01-19 00:00:00.00000 Should round +1 2038-01-19 03:14:07.00000 Should round +2 2038-01-19 03:14:07.99999 Should truncate +DROP TABLE t1; +set time_zone= @@global.time_zone; +set sql_mode=default; + +# Let us test range for TIMESTAMP +# +create table t1 (ts timestamp); +set time_zone='UTC'; +insert into t1 values ('2038-01-19 03:14:07'),('2038-01-19 03:14:08'); +Warnings: +Warning 1264 Out of range value for column 'ts' at row 2 +select * from t1; +ts +2038-01-19 03:14:07 +0000-00-00 00:00:00 +truncate table t1; +set time_zone='MET'; +insert into t1 values ('2038-01-19 04:14:07'),('2038-01-19 04:14:08'); +Warnings: +Warning 1264 Out of range value for column 'ts' at row 2 +select * from t1; +ts +2038-01-19 04:14:07 +0000-00-00 00:00:00 +truncate table t1; +set time_zone='+01:30'; +insert into t1 values ('2038-01-19 04:44:07'),('2038-01-19 04:44:08'); +Warnings: +Warning 1264 Out of range value for column 'ts' at row 2 +select * from t1; +ts +2038-01-19 04:44:07 +0000-00-00 00:00:00 +drop table t1; +SET time_zone='+00:00'; +CREATE TABLE t1 (ts0 TIMESTAMP, ts1 TIMESTAMP(1)); +INSERT INTO t1 VALUES ('2001-01-01 10:20:30', '2001-01-01 10:20:30.9'); +# Corner case +UPDATE t1 SET ts1=FROM_UNIXTIME(2147483647.9); +UPDATE t1 SET ts0=COALESCE(ts1); +SELECT * FROM t1; +ts0 ts1 +2038-01-19 03:14:07 2038-01-19 03:14:07.9 +DROP TABLE t1; +SET time_zone=DEFAULT; +# Let us test CONVERT_TZ function +select convert_tz('2038-01-19 04:14:08', 'MET', 'UTC'); +convert_tz('2038-01-19 04:14:08', 'MET', 'UTC') +2038-01-19 04:14:08 +select convert_tz('2103-01-01 04:00:00', 'MET', 'UTC'); +convert_tz('2103-01-01 04:00:00', 'MET', 'UTC') +2103-01-01 04:00:00 diff --git a/mysql-test/main/func_time_32.test b/mysql-test/main/func_time_32.test new file mode 100644 index 00000000000..419ec972d2e --- /dev/null +++ b/mysql-test/main/func_time_32.test @@ -0,0 +1,90 @@ +--source include/have_32bit_timestamp.inc +--echo # +--echo # Test dates close to upper range +--echo # + +set time_zone="+03:00"; + +select from_unixtime(2147483648); +select unix_timestamp(from_unixtime(2147483648)); + +--echo # bad year +select unix_timestamp('2039-01-20 01:00:00'); +--echo # bad month +select unix_timestamp('2038-02-10 01:00:00'); +--echo # bad day +select unix_timestamp('2038-01-20 01:00:00'); + +--echo # check bad date, close to the boundary (we cut them off in the very end) +select unix_timestamp('2038-01-19 07:14:07'); + +set time_zone=MET; +select unix_timestamp('2038-01-19 04:14:07'), + unix_timestamp('2038-01-19 04:14:08'); +set time_zone= @@global.time_zone; + +--echo # +--echo # Functions that construct DATETIME +--echo # + +SET time_zone='+00:00'; +SET sql_mode=IF(@@version LIKE '%MariaDB%', 'TIME_ROUND_FRACTIONAL', ''); +CREATE TABLE t1 (id SERIAL, a DECIMAL(30,10)); +INSERT INTO t1 (a) VALUES (2147483647.9999999); +SELECT a, FROM_UNIXTIME(a) FROM t1 ORDER BY id; +DROP TABLE t1; +set time_zone= @@global.time_zone; +set sql_mode=default; + +--echo # +--echo # Corner case: +--echo # ALTER TIMESTAMP to a shorter TIMESTAMP +--echo # All values round, maximum possible value truncates. +--echo # + +SET time_zone='+00:00'; +SET sql_mode=IF(@@version LIKE '%MariaDB%', 'TIME_ROUND_FRACTIONAL', ''); +CREATE TABLE t1 (ID INT, a TIMESTAMP(6), comment VARCHAR(64)); +INSERT INTO t1 VALUES (0, '2038-01-18 23:59:59.999999', 'Should round'); +INSERT INTO t1 VALUES (1, '2038-01-19 03:14:06.999999', 'Should round'); +INSERT INTO t1 VALUES (2, '2038-01-19 03:14:07.999999', 'Should truncate'); +ALTER TABLE t1 MODIFY a TIMESTAMP(5); +SELECT * FROM t1; +DROP TABLE t1; +set time_zone= @@global.time_zone; +set sql_mode=default; + +--echo +--echo # Let us test range for TIMESTAMP +--echo # + +create table t1 (ts timestamp); +set time_zone='UTC'; +insert into t1 values ('2038-01-19 03:14:07'),('2038-01-19 03:14:08'); +select * from t1; +truncate table t1; +# MET time zone has range shifted by one hour +set time_zone='MET'; +insert into t1 values ('2038-01-19 04:14:07'),('2038-01-19 04:14:08'); +select * from t1; +truncate table t1; +# same for +01:30 time zone +set time_zone='+01:30'; +insert into t1 values ('2038-01-19 04:44:07'),('2038-01-19 04:44:08'); +select * from t1; +drop table t1; + +SET time_zone='+00:00'; +CREATE TABLE t1 (ts0 TIMESTAMP, ts1 TIMESTAMP(1)); +INSERT INTO t1 VALUES ('2001-01-01 10:20:30', '2001-01-01 10:20:30.9'); +--echo # Corner case +UPDATE t1 SET ts1=FROM_UNIXTIME(2147483647.9); +UPDATE t1 SET ts0=COALESCE(ts1); +SELECT * FROM t1; +DROP TABLE t1; +SET time_zone=DEFAULT; + +--echo # Let us test CONVERT_TZ function +select convert_tz('2038-01-19 04:14:08', 'MET', 'UTC'); +select convert_tz('2103-01-01 04:00:00', 'MET', 'UTC'); + diff --git a/mysql-test/main/func_time_64.result b/mysql-test/main/func_time_64.result new file mode 100644 index 00000000000..03598923547 --- /dev/null +++ b/mysql-test/main/func_time_64.result @@ -0,0 +1,156 @@ +# +# Test dates close to upper range +# +set time_zone="+03:00"; +select from_unixtime(2147483648); +from_unixtime(2147483648) +2038-01-19 06:14:08 +select unix_timestamp(from_unixtime(2147483648)); +unix_timestamp(from_unixtime(2147483648)) +2147483648 +select from_unixtime(4294967295); +from_unixtime(4294967295) +2106-02-07 09:28:15 +select unix_timestamp(from_unixtime(4294967295)); +unix_timestamp(from_unixtime(4294967295)) +4294967295 +# bad year +select unix_timestamp('2107-02-07 01:00:00'); +unix_timestamp('2107-02-07 01:00:00') +NULL +# bad month +select unix_timestamp('2106-03-07 01:00:00'); +unix_timestamp('2106-03-07 01:00:00') +NULL +# bad day +select unix_timestamp('2106-02-08 01:00:00'); +unix_timestamp('2106-02-08 01:00:00') +NULL +# check bad date, close to the boundary (we cut them off in the very end) +select unix_timestamp('2038-01-19 07:14:07'); +unix_timestamp('2038-01-19 07:14:07') +2147487247 +select unix_timestamp('2106-02-07 09:28:15'); +unix_timestamp('2106-02-07 09:28:15') +4294967295 +select unix_timestamp('2106-02-07 09:28:16'); +unix_timestamp('2106-02-07 09:28:16') +NULL +set time_zone=MET; +select unix_timestamp('2038-01-19 04:14:07'), +unix_timestamp('2038-01-19 04:14:08'), +unix_timestamp('2106-02-07 07:28:15'), +unix_timestamp('2106-02-07 07:28:16'); +unix_timestamp('2038-01-19 04:14:07') unix_timestamp('2038-01-19 04:14:08') unix_timestamp('2106-02-07 07:28:15') unix_timestamp('2106-02-07 07:28:16') +2147483647 2147483648 4294967295 NULL +set time_zone= @@global.time_zone; +# +# Functions that construct DATETIME +# +SET time_zone='+00:00'; +SET sql_mode=IF(@@version LIKE '%MariaDB%', 'TIME_ROUND_FRACTIONAL', ''); +CREATE TABLE t1 (id SERIAL, a DECIMAL(30,10)); +INSERT INTO t1 (a) VALUES +(2147483647.9999999), +(4294967295.999999), +(4294967295.9999999); +SELECT a, FROM_UNIXTIME(a) FROM t1 ORDER BY id; +a FROM_UNIXTIME(a) +2147483647.9999999000 2038-01-19 03:14:08.000000 +4294967295.9999990000 2106-02-07 06:28:15.999999 +4294967295.9999999000 NULL +DROP TABLE t1; +set time_zone= @@global.time_zone; +set sql_mode=default; +# +# Corner case: +# ALTER TIMESTAMP to a shorter TIMESTAMP +# All values round, maximum possible value truncates. +# +SET time_zone='+00:00'; +SET sql_mode=IF(@@version LIKE '%MariaDB%', 'TIME_ROUND_FRACTIONAL', ''); +CREATE TABLE t1 (ID INT, a TIMESTAMP(6), comment VARCHAR(64)); +INSERT INTO t1 VALUES (0, '2038-01-18 23:59:59.999999', 'Should round'); +INSERT INTO t1 VALUES (1, '2038-01-19 03:14:06.999999', 'Should round'); +INSERT INTO t1 VALUES (2, '2038-01-19 03:14:07.999999', 'Should round'); +INSERT INTO t1 VALUES (2, '2106-02-07 06:28:14.999999', 'Should round'); +INSERT INTO t1 VALUES (2, '2106-02-07 06:28:15.999999', 'Should truncate'); +ALTER TABLE t1 MODIFY a TIMESTAMP(5); +Warnings: +Warning 1264 Out of range value for column 'a' at row 5 +SELECT * FROM t1; +ID a comment +0 2038-01-19 00:00:00.00000 Should round +1 2038-01-19 03:14:07.00000 Should round +2 2038-01-19 03:14:08.00000 Should round +2 2106-02-07 06:28:15.00000 Should round +2 2106-02-07 06:28:15.99999 Should truncate +DROP TABLE t1; +set time_zone= @@global.time_zone; +set sql_mode=default; + +# Let us test range for TIMESTAMP +# +create table t1 (ts timestamp); +set time_zone='UTC'; +insert into t1 values ('2038-01-19 03:14:07'),('2038-01-19 03:14:08'); +insert into t1 values ('2106-02-07 06:28:15'),('2106-02-07 06:28:16'); +Warnings: +Warning 1264 Out of range value for column 'ts' at row 2 +select * from t1; +ts +2038-01-19 03:14:07 +2038-01-19 03:14:08 +2106-02-07 06:28:15 +0000-00-00 00:00:00 +truncate table t1; +set time_zone='MET'; +insert into t1 values ('2038-01-19 04:14:07'),('2038-01-19 04:14:08'); +insert ignore into t1 values ('2106-02-07 07:28:15'),('2106-02-07 07:28:16'); +Warnings: +Warning 1264 Out of range value for column 'ts' at row 2 +select * from t1; +ts +2038-01-19 04:14:07 +2038-01-19 04:14:08 +2106-02-07 07:28:15 +0000-00-00 00:00:00 +truncate table t1; +set time_zone='+01:30'; +insert into t1 values ('2038-01-19 04:44:07'),('2038-01-19 04:44:08'); +insert ignore into t1 values ('2106-02-07 07:58:15'),('2106-02-07 07:58:16'); +Warnings: +Warning 1264 Out of range value for column 'ts' at row 2 +select * from t1; +ts +2038-01-19 04:44:07 +2038-01-19 04:44:08 +2106-02-07 07:58:15 +0000-00-00 00:00:00 +drop table t1; +SET time_zone='+00:00'; +CREATE TABLE t1 (ts0 TIMESTAMP, ts1 TIMESTAMP(1)); +INSERT INTO t1 VALUES ('2001-01-01 10:20:30', '2001-01-01 10:20:30.9'); +# Corner case +UPDATE t1 SET ts1=FROM_UNIXTIME(2147483647.9); +UPDATE t1 SET ts0=COALESCE(ts1); +SELECT * FROM t1; +ts0 ts1 +2038-01-19 03:14:07 2038-01-19 03:14:07.9 +UPDATE t1 SET ts1=FROM_UNIXTIME(4294963695.9); +UPDATE t1 SET ts0=COALESCE(ts1); +SELECT * FROM t1; +ts0 ts1 +2106-02-07 05:28:15 2106-02-07 05:28:15.9 +DROP TABLE t1; +SET time_zone=DEFAULT; +# Let us test CONVERT_TZ function +select convert_tz('2038-01-19 04:14:08', 'MET', 'UTC'); +convert_tz('2038-01-19 04:14:08', 'MET', 'UTC') +2038-01-19 03:14:08 +select convert_tz('2103-01-01 04:00:00', 'MET', 'UTC'); +convert_tz('2103-01-01 04:00:00', 'MET', 'UTC') +2103-01-01 03:00:00 +select convert_tz('2106-02-07 07:28:15', 'MET', 'UTC'); +convert_tz('2106-02-07 07:28:15', 'MET', 'UTC') +2106-02-07 06:28:15 diff --git a/mysql-test/main/func_time_64.test b/mysql-test/main/func_time_64.test new file mode 100644 index 00000000000..0eaa4e4dcce --- /dev/null +++ b/mysql-test/main/func_time_64.test @@ -0,0 +1,108 @@ +--source include/have_64bit_timestamp.inc + +--echo # +--echo # Test dates close to upper range +--echo # + +set time_zone="+03:00"; + +select from_unixtime(2147483648); +select unix_timestamp(from_unixtime(2147483648)); +select from_unixtime(4294967295); +select unix_timestamp(from_unixtime(4294967295)); + +--echo # bad year +select unix_timestamp('2107-02-07 01:00:00'); +--echo # bad month +select unix_timestamp('2106-03-07 01:00:00'); +--echo # bad day +select unix_timestamp('2106-02-08 01:00:00'); + +--echo # check bad date, close to the boundary (we cut them off in the very end) +select unix_timestamp('2038-01-19 07:14:07'); +select unix_timestamp('2106-02-07 09:28:15'); +select unix_timestamp('2106-02-07 09:28:16'); + +set time_zone=MET; +select unix_timestamp('2038-01-19 04:14:07'), + unix_timestamp('2038-01-19 04:14:08'), + unix_timestamp('2106-02-07 07:28:15'), + unix_timestamp('2106-02-07 07:28:16'); +set time_zone= @@global.time_zone; + +--echo # +--echo # Functions that construct DATETIME +--echo # + +SET time_zone='+00:00'; +SET sql_mode=IF(@@version LIKE '%MariaDB%', 'TIME_ROUND_FRACTIONAL', ''); +CREATE TABLE t1 (id SERIAL, a DECIMAL(30,10)); +INSERT INTO t1 (a) VALUES +(2147483647.9999999), +(4294967295.999999), +(4294967295.9999999); +SELECT a, FROM_UNIXTIME(a) FROM t1 ORDER BY id; +DROP TABLE t1; +set time_zone= @@global.time_zone; +set sql_mode=default; + +--echo # +--echo # Corner case: +--echo # ALTER TIMESTAMP to a shorter TIMESTAMP +--echo # All values round, maximum possible value truncates. +--echo # + +SET time_zone='+00:00'; +SET sql_mode=IF(@@version LIKE '%MariaDB%', 'TIME_ROUND_FRACTIONAL', ''); +CREATE TABLE t1 (ID INT, a TIMESTAMP(6), comment VARCHAR(64)); +INSERT INTO t1 VALUES (0, '2038-01-18 23:59:59.999999', 'Should round'); +INSERT INTO t1 VALUES (1, '2038-01-19 03:14:06.999999', 'Should round'); +INSERT INTO t1 VALUES (2, '2038-01-19 03:14:07.999999', 'Should round'); +INSERT INTO t1 VALUES (2, '2106-02-07 06:28:14.999999', 'Should round'); +INSERT INTO t1 VALUES (2, '2106-02-07 06:28:15.999999', 'Should truncate'); +ALTER TABLE t1 MODIFY a TIMESTAMP(5); +SELECT * FROM t1; +DROP TABLE t1; +set time_zone= @@global.time_zone; +set sql_mode=default; + +--echo +--echo # Let us test range for TIMESTAMP +--echo # + +create table t1 (ts timestamp); +set time_zone='UTC'; +insert into t1 values ('2038-01-19 03:14:07'),('2038-01-19 03:14:08'); +insert into t1 values ('2106-02-07 06:28:15'),('2106-02-07 06:28:16'); +select * from t1; +truncate table t1; +# MET time zone has range shifted by one hour +set time_zone='MET'; +insert into t1 values ('2038-01-19 04:14:07'),('2038-01-19 04:14:08'); +insert ignore into t1 values ('2106-02-07 07:28:15'),('2106-02-07 07:28:16'); +select * from t1; +truncate table t1; +# same for +01:30 time zone +set time_zone='+01:30'; +insert into t1 values ('2038-01-19 04:44:07'),('2038-01-19 04:44:08'); +insert ignore into t1 values ('2106-02-07 07:58:15'),('2106-02-07 07:58:16'); +select * from t1; +drop table t1; + +SET time_zone='+00:00'; +CREATE TABLE t1 (ts0 TIMESTAMP, ts1 TIMESTAMP(1)); +INSERT INTO t1 VALUES ('2001-01-01 10:20:30', '2001-01-01 10:20:30.9'); +--echo # Corner case +UPDATE t1 SET ts1=FROM_UNIXTIME(2147483647.9); +UPDATE t1 SET ts0=COALESCE(ts1); +SELECT * FROM t1; +UPDATE t1 SET ts1=FROM_UNIXTIME(4294963695.9); +UPDATE t1 SET ts0=COALESCE(ts1); +SELECT * FROM t1; +DROP TABLE t1; +SET time_zone=DEFAULT; + +--echo # Let us test CONVERT_TZ function +select convert_tz('2038-01-19 04:14:08', 'MET', 'UTC'); +select convert_tz('2103-01-01 04:00:00', 'MET', 'UTC'); +select convert_tz('2106-02-07 07:28:15', 'MET', 'UTC'); diff --git a/mysql-test/main/func_time_round.result b/mysql-test/main/func_time_round.result index b335cf393ba..75c6c373291 100644 --- a/mysql-test/main/func_time_round.result +++ b/mysql-test/main/func_time_round.result @@ -917,8 +917,7 @@ INSERT INTO t1_unix_timestamp (a) VALUES (980639999.9999999), (2147483647), (2147483647.9), -(2147483647.999999), -(2147483647.9999999); +(2147483647.999999); SELECT a, FROM_UNIXTIME(a) FROM t1_unix_timestamp ORDER BY id; a FROM_UNIXTIME(a) 980639999.0000000000 2001-01-27 23:59:59.000000 @@ -928,7 +927,6 @@ a FROM_UNIXTIME(a) 2147483647.0000000000 2038-01-19 03:14:07.000000 2147483647.9000000000 2038-01-19 03:14:07.900000 2147483647.9999990000 2038-01-19 03:14:07.999999 -2147483647.9999999000 NULL DROP TABLE t1_unix_timestamp; SET time_zone=DEFAULT; # diff --git a/mysql-test/main/func_time_round.test b/mysql-test/main/func_time_round.test index 79f9ec289a0..4c3cb004000 100644 --- a/mysql-test/main/func_time_round.test +++ b/mysql-test/main/func_time_round.test @@ -269,8 +269,7 @@ INSERT INTO t1_unix_timestamp (a) VALUES (980639999.9999999), (2147483647), (2147483647.9), -(2147483647.999999), -(2147483647.9999999); +(2147483647.999999); SELECT a, FROM_UNIXTIME(a) FROM t1_unix_timestamp ORDER BY id; DROP TABLE t1_unix_timestamp; SET time_zone=DEFAULT; diff --git a/mysql-test/main/partition_datatype.result b/mysql-test/main/partition_datatype.result index fb2635ceda9..00ea4c3fe48 100644 --- a/mysql-test/main/partition_datatype.result +++ b/mysql-test/main/partition_datatype.result @@ -373,7 +373,7 @@ Warning 1264 Out of range value for column 'a' at row 1 INSERT IGNORE INTO t1 VALUES ('1969-12-31 23:59:59', 'UTCI'); Warnings: Warning 1264 Out of range value for column 'a' at row 1 -INSERT IGNORE INTO t1 VALUES ('2038-01-19 03:14:08', 'UTCI'); +INSERT IGNORE INTO t1 VALUES ('2107-01-19 03:14:08', 'UTCI'); Warnings: Warning 1264 Out of range value for column 'a' at row 1 INSERT IGNORE INTO t1 VALUES ('1970-01-01 00:00:00', 'UTCI'); @@ -384,7 +384,6 @@ INSERT INTO t1 VALUES ('1970-01-01 00:00:01', 'UTC'); INSERT INTO t1 VALUES ('1974-02-05 21:28:16', 'UTC'); # Test end range INSERT INTO t1 VALUES ('2038-01-19 03:14:06', 'UTC'); -INSERT INTO t1 VALUES ('2038-01-19 03:14:07', 'UTC'); # Test Daylight saving shift INSERT INTO t1 VALUES ('2011-03-26 22:59:59', 'UTC'); INSERT INTO t1 VALUES ('2011-03-26 23:00:00', 'UTC'); @@ -415,7 +414,7 @@ Warning 1264 Out of range value for column 'a' at row 1 INSERT IGNORE INTO t1 VALUES ('1970-01-01 02:29:29', 'MoscowI'); Warnings: Warning 1264 Out of range value for column 'a' at row 1 -INSERT IGNORE INTO t1 VALUES ('2038-01-19 06:14:08', 'MoscowI'); +INSERT IGNORE INTO t1 VALUES ('2107-01-19 06:14:08', 'MoscowI'); Warnings: Warning 1264 Out of range value for column 'a' at row 1 INSERT IGNORE INTO t1 VALUES ('1970-01-01 03:00:00', 'MoscowI'); @@ -436,7 +435,6 @@ INSERT INTO t1 VALUES ('1970-01-01 03:00:01', 'Moscow'); INSERT INTO t1 VALUES ('1974-02-05 21:28:16', 'Moscow'); # Test end range INSERT INTO t1 VALUES ('2038-01-19 06:14:06', 'Moscow'); -INSERT INTO t1 VALUES ('2038-01-19 06:14:07', 'Moscow'); # Test Daylight saving shift INSERT INTO t1 VALUES ('2011-03-27 01:59:59', 'Moscow'); INSERT INTO t1 VALUES ('2011-03-27 03:00:00', 'Moscow'); @@ -461,7 +459,7 @@ p-2011-MSD-2 6 p-2012-MSK-1 3 p-2012-MSK-2 4 pEnd 2 -pMax 2 +pMax 0 SELECT * FROM t1 ORDER BY a, tz; a tz NULL Moscow @@ -508,8 +506,6 @@ NULL UTC 2011-10-30 00:00:01 UTC 2038-01-19 03:14:06 Moscow 2038-01-19 03:14:06 UTC -2038-01-19 03:14:07 Moscow -2038-01-19 03:14:07 UTC SELECT * FROM t2 ORDER BY a, tz; a tz NULL Moscow @@ -556,8 +552,6 @@ NULL UTC 2011-10-30 00:00:01 UTC 2038-01-19 03:14:06 Moscow 2038-01-19 03:14:06 UTC -2038-01-19 03:14:07 Moscow -2038-01-19 03:14:07 UTC SELECT * FROM t2 WHERE a BETWEEN '2011-03-01 00:00:00' and '2011-03-26 23:00:00' ORDER BY a, tz; a tz @@ -687,7 +681,7 @@ Warnings: Warning 1264 Out of range value for column 'a' at row 1 SELECT COUNT(*) FROM t2; COUNT(*) -35 +33 SELECT COUNT(*) FROM t2 WHERE a = 0; COUNT(*) 1 @@ -698,28 +692,26 @@ NULL UTC 0000-00-00 00:00:00 UTC SELECT * FROM t2 ORDER BY a DESC, tz LIMIT 3; a tz -2038-01-19 03:14:07 Moscow -2038-01-19 03:14:07 UTC 2038-01-19 03:14:06 Moscow +2038-01-19 03:14:06 UTC +2011-10-30 00:00:01 Moscow UPDATE IGNORE t2 SET a = TIMESTAMPADD(SECOND, 1, a); Warnings: Warning 1292 Incorrect datetime value: '0000-00-00 00:00:00' -Warning 1264 Out of range value for column 'a' at row 34 -Warning 1264 Out of range value for column 'a' at row 35 SELECT MIN(a), MAX(a) FROM t2; MIN(a) MAX(a) -0000-00-00 00:00:00 2038-01-19 03:14:07 +1970-01-01 00:00:02 2038-01-19 03:14:07 SELECT COUNT(*) FROM t2; COUNT(*) -35 +33 SELECT COUNT(*) FROM t2 WHERE a = 0; COUNT(*) -2 +0 SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 't2'; PARTITION_NAME TABLE_ROWS p0 3 -p-2000 6 +p-2000 4 p-2011-MSK 0 p-2011-MSD-1 9 p-2011-MSD-2 6 @@ -732,8 +724,6 @@ a tz NULL Moscow NULL UTC NULL UTC -0000-00-00 00:00:00 Moscow -0000-00-00 00:00:00 UTC 1970-01-01 00:00:02 Moscow 1970-01-01 00:00:02 UTC 1974-02-05 18:28:17 Moscow @@ -770,10 +760,10 @@ Warnings: Warning 1264 Out of range value for column 'a' at row 1 SELECT COUNT(*) FROM t2; COUNT(*) -36 +34 SELECT COUNT(*) FROM t2 WHERE a = 0; COUNT(*) -3 +1 SELECT * FROM t2 ORDER BY a, tz LIMIT 3; a tz NULL Moscow @@ -787,21 +777,19 @@ a tz UPDATE IGNORE t2 SET a = TIMESTAMPADD(SECOND, -1, a); Warnings: Warning 1292 Incorrect datetime value: '0000-00-00 00:00:00' -Warning 1292 Incorrect datetime value: '0000-00-00 00:00:00' -Warning 1292 Incorrect datetime value: '0000-00-00 00:00:00' SELECT MIN(a), MAX(a) FROM t2; MIN(a) MAX(a) 1970-01-01 00:00:01 2038-01-19 03:14:06 SELECT COUNT(*) FROM t2; COUNT(*) -36 +34 SELECT COUNT(*) FROM t2 WHERE a = 0; COUNT(*) 0 SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 't2'; PARTITION_NAME TABLE_ROWS -p0 6 +p0 4 p-2000 4 p-2011-MSK 2 p-2011-MSD-1 9 @@ -813,8 +801,6 @@ pMax 0 SELECT * FROM t2 ORDER BY a, tz; a tz NULL Moscow -NULL Moscow -NULL UTC NULL UTC NULL UTC NULL UTC @@ -878,7 +864,7 @@ p-2011-MSD-2 6 p-2012-MSK-1 3 p-2012-MSK-2 4 pEnd 2 -pMax 2 +pMax 0 SELECT * FROM t1 ORDER BY a, tz; a tz NULL Moscow @@ -925,8 +911,6 @@ NULL UTC 2011-10-30 03:00:01 UTC 2038-01-19 06:14:06 Moscow 2038-01-19 06:14:06 UTC -2038-01-19 06:14:07 Moscow -2038-01-19 06:14:07 UTC SELECT * FROM t2 ORDER BY a, tz; a tz NULL Moscow @@ -973,8 +957,6 @@ NULL UTC 2011-10-30 03:00:01 UTC 2038-01-19 06:14:06 Moscow 2038-01-19 06:14:06 UTC -2038-01-19 06:14:07 Moscow -2038-01-19 06:14:07 UTC # Testing the leap from 01:59:59 to 03:00:00 SELECT * FROM t2 WHERE a BETWEEN '2011-03-01 00:00:00' and '2011-03-27 03:00:00' ORDER BY a, tz; @@ -1167,7 +1149,7 @@ Warnings: Warning 1264 Out of range value for column 'a' at row 1 SELECT COUNT(*) FROM t2; COUNT(*) -35 +33 SELECT COUNT(*) FROM t2 WHERE a = 0; COUNT(*) 1 @@ -1178,30 +1160,28 @@ NULL UTC 0000-00-00 00:00:00 Moscow SELECT * FROM t2 ORDER BY a DESC, tz LIMIT 3; a tz -2038-01-19 06:14:07 Moscow -2038-01-19 06:14:07 UTC 2038-01-19 06:14:06 Moscow +2038-01-19 06:14:06 UTC +2011-10-30 03:00:01 Moscow UPDATE IGNORE t2 SET a = TIMESTAMPADD(SECOND, 1, a); Warnings: Warning 1292 Incorrect datetime value: '0000-00-00 00:00:00' Warning 1299 Invalid TIMESTAMP value in column 'a' at row 8 Warning 1299 Invalid TIMESTAMP value in column 'a' at row 9 -Warning 1264 Out of range value for column 'a' at row 34 -Warning 1264 Out of range value for column 'a' at row 35 SELECT MIN(a), MAX(a) FROM t2; MIN(a) MAX(a) -0000-00-00 00:00:00 2038-01-19 06:14:07 +1970-01-01 03:00:02 2038-01-19 06:14:07 SELECT COUNT(*) FROM t2; COUNT(*) -35 +33 SELECT COUNT(*) FROM t2 WHERE a = 0; COUNT(*) -2 +0 SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 't2'; PARTITION_NAME TABLE_ROWS p0 3 -p-2000 6 +p-2000 4 p-2011-MSK 0 p-2011-MSD-1 9 p-2011-MSD-2 8 @@ -1214,8 +1194,6 @@ a tz NULL Moscow NULL Moscow NULL UTC -0000-00-00 00:00:00 Moscow -0000-00-00 00:00:00 UTC 1970-01-01 03:00:02 Moscow 1970-01-01 03:00:02 UTC 1974-02-05 21:28:17 Moscow @@ -1252,10 +1230,10 @@ Warnings: Warning 1264 Out of range value for column 'a' at row 1 SELECT COUNT(*) FROM t2; COUNT(*) -36 +34 SELECT COUNT(*) FROM t2 WHERE a = 0; COUNT(*) -3 +1 SELECT * FROM t2 ORDER BY a, tz LIMIT 3; a tz NULL Moscow @@ -1269,23 +1247,21 @@ a tz UPDATE IGNORE t2 SET a = TIMESTAMPADD(SECOND, -1, a); Warnings: Warning 1292 Incorrect datetime value: '0000-00-00 00:00:00' -Warning 1292 Incorrect datetime value: '0000-00-00 00:00:00' -Warning 1292 Incorrect datetime value: '0000-00-00 00:00:00' -Warning 1299 Invalid TIMESTAMP value in column 'a' at row 18 -Warning 1299 Invalid TIMESTAMP value in column 'a' at row 19 +Warning 1299 Invalid TIMESTAMP value in column 'a' at row 16 +Warning 1299 Invalid TIMESTAMP value in column 'a' at row 17 SELECT MIN(a), MAX(a) FROM t2; MIN(a) MAX(a) 1970-01-01 03:00:01 2038-01-19 06:14:06 SELECT COUNT(*) FROM t2; COUNT(*) -36 +34 SELECT COUNT(*) FROM t2 WHERE a = 0; COUNT(*) 0 SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 't2'; PARTITION_NAME TABLE_ROWS -p0 6 +p0 4 p-2000 4 p-2011-MSK 0 p-2011-MSD-1 11 @@ -1299,8 +1275,6 @@ a tz NULL Moscow NULL Moscow NULL Moscow -NULL Moscow -NULL UTC NULL UTC 1970-01-01 03:00:01 Moscow 1970-01-01 03:00:01 UTC diff --git a/mysql-test/main/partition_datatype.test b/mysql-test/main/partition_datatype.test index 9ab3bd4d5fa..474de3cd575 100644 --- a/mysql-test/main/partition_datatype.test +++ b/mysql-test/main/partition_datatype.test @@ -268,14 +268,13 @@ INSERT INTO t1 VALUES ('0000-00-00 00:00:00', 'UTC'); --echo # Test invalid values INSERT IGNORE INTO t1 VALUES ('1901-01-01 00:00:00', 'UTCI'); INSERT IGNORE INTO t1 VALUES ('1969-12-31 23:59:59', 'UTCI'); -INSERT IGNORE INTO t1 VALUES ('2038-01-19 03:14:08', 'UTCI'); +INSERT IGNORE INTO t1 VALUES ('2107-01-19 03:14:08', 'UTCI'); INSERT IGNORE INTO t1 VALUES ('1970-01-01 00:00:00', 'UTCI'); --echo # Test start range INSERT INTO t1 VALUES ('1970-01-01 00:00:01', 'UTC'); INSERT INTO t1 VALUES ('1974-02-05 21:28:16', 'UTC'); --echo # Test end range INSERT INTO t1 VALUES ('2038-01-19 03:14:06', 'UTC'); -INSERT INTO t1 VALUES ('2038-01-19 03:14:07', 'UTC'); --echo # Test Daylight saving shift INSERT INTO t1 VALUES ('2011-03-26 22:59:59', 'UTC'); INSERT INTO t1 VALUES ('2011-03-26 23:00:00', 'UTC'); @@ -300,7 +299,7 @@ INSERT IGNORE INTO t1 VALUES ('0000-00-00 03:00:00', 'MoscowI'); INSERT IGNORE INTO t1 VALUES ('1901-01-01 00:00:00', 'MoscowI'); INSERT IGNORE INTO t1 VALUES ('1969-12-31 23:59:59', 'MoscowI'); INSERT IGNORE INTO t1 VALUES ('1970-01-01 02:29:29', 'MoscowI'); -INSERT IGNORE INTO t1 VALUES ('2038-01-19 06:14:08', 'MoscowI'); +INSERT IGNORE INTO t1 VALUES ('2107-01-19 06:14:08', 'MoscowI'); INSERT IGNORE INTO t1 VALUES ('1970-01-01 03:00:00', 'MoscowI'); --echo # values truncated to 03:00:00 due to daylight saving shift INSERT IGNORE INTO t1 VALUES ('2011-03-27 02:00:00', 'MoscowI'); @@ -311,7 +310,6 @@ INSERT INTO t1 VALUES ('1970-01-01 03:00:01', 'Moscow'); INSERT INTO t1 VALUES ('1974-02-05 21:28:16', 'Moscow'); --echo # Test end range INSERT INTO t1 VALUES ('2038-01-19 06:14:06', 'Moscow'); -INSERT INTO t1 VALUES ('2038-01-19 06:14:07', 'Moscow'); --echo # Test Daylight saving shift INSERT INTO t1 VALUES ('2011-03-27 01:59:59', 'Moscow'); INSERT INTO t1 VALUES ('2011-03-27 03:00:00', 'Moscow'); diff --git a/mysql-test/main/partition_datatype_32.result b/mysql-test/main/partition_datatype_32.result new file mode 100644 index 00000000000..e6c42c37d64 --- /dev/null +++ b/mysql-test/main/partition_datatype_32.result @@ -0,0 +1,69 @@ +# +# Bug#28928: UNIX_TIMESTAMP() should be considered unary monotonic +# by partition pruning +# Testing end ranges +SET @old_time_zone= @@session.time_zone; +SET @@session.time_zone = 'UTC'; +# Using MyISAM to get stable values on TABLE_ROWS in I_S.PARTITIONS +CREATE TABLE t1 +(a TIMESTAMP NULL, +tz varchar(16)) +ENGINE = MyISAM; +CREATE TABLE t2 LIKE t1; +ALTER TABLE t2 PARTITION BY RANGE (UNIX_TIMESTAMP(a)) +(PARTITION `p0` VALUES LESS THAN (0), +PARTITION `p-2000` VALUES LESS THAN (UNIX_TIMESTAMP(20000101)), +PARTITION `p-2011-MSK` VALUES LESS THAN (UNIX_TIMESTAMP(20110326230000)), +PARTITION `p-2011-MSD-1` VALUES LESS THAN (UNIX_TIMESTAMP(20111029220000)), +PARTITION `p-2011-MSD-2` VALUES LESS THAN (UNIX_TIMESTAMP(20111029230000)), +PARTITION `p-2012-MSK-1` VALUES LESS THAN (UNIX_TIMESTAMP(20111030000000)), +PARTITION `p-2012-MSK-2` VALUES LESS THAN (UNIX_TIMESTAMP(20120324230000)), +PARTITION `pEnd` VALUES LESS THAN (UNIX_TIMESTAMP(20380119031407)), +PARTITION `pMax` VALUES LESS THAN MAXVALUE); +# Test invalid values +INSERT IGNORE INTO t1 VALUES ('2038-01-19 03:14:08', 'UTCI'); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +# Test end range +INSERT INTO t1 VALUES ('2038-01-19 03:14:07', 'UTCI'); +SET @@session.time_zone = 'Europe/Moscow'; +# Test invalid values +INSERT IGNORE INTO t1 VALUES ('2038-01-19 06:14:08', 'Moscow'); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +# Test end range +INSERT INTO t1 VALUES ('2038-01-19 06:14:07', 'Moscow'); +SELECT * FROM t1 ORDER BY a, tz; +a tz +0000-00-00 00:00:00 Moscow +0000-00-00 00:00:00 UTCI +2038-01-19 06:14:07 Moscow +2038-01-19 06:14:07 UTCI +SET @@session.time_zone = 'UTC'; +INSERT INTO t2 SELECT * FROM t1; +SELECT * FROM t2 ORDER BY a DESC,tz; +a tz +2038-01-19 03:14:07 Moscow +2038-01-19 03:14:07 UTCI +0000-00-00 00:00:00 Moscow +0000-00-00 00:00:00 UTCI +SELECT MIN(a), MAX(a) FROM t2; +MIN(a) MAX(a) +0000-00-00 00:00:00 2038-01-19 03:14:07 +UPDATE IGNORE t2 SET a = TIMESTAMPADD(SECOND, 1, a); +Warnings: +Warning 1292 Incorrect datetime value: '0000-00-00 00:00:00' +Warning 1292 Incorrect datetime value: '0000-00-00 00:00:00' +Warning 1264 Out of range value for column 'a' at row 3 +Warning 1264 Out of range value for column 'a' at row 4 +SELECT MIN(a), MAX(a) FROM t2; +MIN(a) MAX(a) +0000-00-00 00:00:00 0000-00-00 00:00:00 +SELECT * FROM t2 ORDER BY a, tz; +a tz +NULL Moscow +NULL UTCI +0000-00-00 00:00:00 Moscow +0000-00-00 00:00:00 UTCI +DROP TABLE t1,t2; +SET @@session.time_zone= @old_time_zone; diff --git a/mysql-test/main/partition_datatype_32.test b/mysql-test/main/partition_datatype_32.test new file mode 100644 index 00000000000..bf2aa424d5a --- /dev/null +++ b/mysql-test/main/partition_datatype_32.test @@ -0,0 +1,52 @@ +--source include/have_partition.inc +--source include/have_32bit_timestamp.inc + +--echo # +--echo # Bug#28928: UNIX_TIMESTAMP() should be considered unary monotonic +--echo # by partition pruning +--echo # Testing end ranges + +SET @old_time_zone= @@session.time_zone; +SET @@session.time_zone = 'UTC'; +--echo # Using MyISAM to get stable values on TABLE_ROWS in I_S.PARTITIONS +CREATE TABLE t1 +(a TIMESTAMP NULL, + tz varchar(16)) +ENGINE = MyISAM; +CREATE TABLE t2 LIKE t1; +ALTER TABLE t2 PARTITION BY RANGE (UNIX_TIMESTAMP(a)) +(PARTITION `p0` VALUES LESS THAN (0), + PARTITION `p-2000` VALUES LESS THAN (UNIX_TIMESTAMP(20000101)), + PARTITION `p-2011-MSK` VALUES LESS THAN (UNIX_TIMESTAMP(20110326230000)), + PARTITION `p-2011-MSD-1` VALUES LESS THAN (UNIX_TIMESTAMP(20111029220000)), + PARTITION `p-2011-MSD-2` VALUES LESS THAN (UNIX_TIMESTAMP(20111029230000)), + PARTITION `p-2012-MSK-1` VALUES LESS THAN (UNIX_TIMESTAMP(20111030000000)), + PARTITION `p-2012-MSK-2` VALUES LESS THAN (UNIX_TIMESTAMP(20120324230000)), + PARTITION `pEnd` VALUES LESS THAN (UNIX_TIMESTAMP(20380119031407)), + PARTITION `pMax` VALUES LESS THAN MAXVALUE); + +--echo # Test invalid values +INSERT IGNORE INTO t1 VALUES ('2038-01-19 03:14:08', 'UTCI'); +--echo # Test end range +INSERT INTO t1 VALUES ('2038-01-19 03:14:07', 'UTCI'); + +SET @@session.time_zone = 'Europe/Moscow'; + +--echo # Test invalid values +INSERT IGNORE INTO t1 VALUES ('2038-01-19 06:14:08', 'Moscow'); +--echo # Test end range +INSERT INTO t1 VALUES ('2038-01-19 06:14:07', 'Moscow'); + +SELECT * FROM t1 ORDER BY a, tz; + +SET @@session.time_zone = 'UTC'; +INSERT INTO t2 SELECT * FROM t1; +SELECT * FROM t2 ORDER BY a DESC,tz; + +SELECT MIN(a), MAX(a) FROM t2; +UPDATE IGNORE t2 SET a = TIMESTAMPADD(SECOND, 1, a); +SELECT MIN(a), MAX(a) FROM t2; +SELECT * FROM t2 ORDER BY a, tz; + +DROP TABLE t1,t2; +SET @@session.time_zone= @old_time_zone; diff --git a/mysql-test/main/partition_datatype_64.result b/mysql-test/main/partition_datatype_64.result new file mode 100644 index 00000000000..30cad4cb2a6 --- /dev/null +++ b/mysql-test/main/partition_datatype_64.result @@ -0,0 +1,84 @@ +# +# Bug#28928: UNIX_TIMESTAMP() should be considered unary monotonic +# by partition pruning +# Testing end ranges +SET @old_time_zone= @@session.time_zone; +SET @@session.time_zone = 'UTC'; +# Using MyISAM to get stable values on TABLE_ROWS in I_S.PARTITIONS +CREATE TABLE t1 +(a TIMESTAMP NULL, +tz varchar(16)) +ENGINE = MyISAM; +CREATE TABLE t2 LIKE t1; +ALTER TABLE t2 PARTITION BY RANGE (UNIX_TIMESTAMP(a)) +(PARTITION `p0` VALUES LESS THAN (0), +PARTITION `p-2000` VALUES LESS THAN (UNIX_TIMESTAMP(20000101)), +PARTITION `p-2011-MSK` VALUES LESS THAN (UNIX_TIMESTAMP(20110326230000)), +PARTITION `p-2011-MSD-1` VALUES LESS THAN (UNIX_TIMESTAMP(20111029220000)), +PARTITION `p-2011-MSD-2` VALUES LESS THAN (UNIX_TIMESTAMP(20111029230000)), +PARTITION `p-2012-MSK-1` VALUES LESS THAN (UNIX_TIMESTAMP(20111030000000)), +PARTITION `p-2012-MSK-2` VALUES LESS THAN (UNIX_TIMESTAMP(20120324230000)), +PARTITION `pEnd` VALUES LESS THAN (UNIX_TIMESTAMP(20380119031407)), +PARTITION `pMax` VALUES LESS THAN MAXVALUE); +# Test invalid values +INSERT IGNORE INTO t1 VALUES ('2038-01-19 03:14:08', 'UTCI'); +INSERT IGNORE INTO t1 VALUES ('2106-02-07 06:28:16', 'UTCI'); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +# Test end range +INSERT INTO t1 VALUES ('2038-01-19 03:14:07', 'UTCI'); +INSERT INTO t1 VALUES ('2106-02-07 06:28:15', 'UTCI'); +SET @@session.time_zone = 'Europe/Moscow'; +# Test invalid values +INSERT IGNORE INTO t1 VALUES ('2038-01-19 06:14:08', 'Moscow'); +INSERT IGNORE INTO t1 VALUES ('2106-02-07 09:28:16', 'Moscow'); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +# Test end range +INSERT INTO t1 VALUES ('2038-01-19 06:14:07', 'Moscow'); +INSERT INTO t1 VALUES ('2106-02-07 06:28:15', 'Moscow'); +SELECT * FROM t1 ORDER BY a, tz; +a tz +0000-00-00 00:00:00 Moscow +0000-00-00 00:00:00 UTCI +2038-01-19 06:14:07 Moscow +2038-01-19 06:14:07 UTCI +2038-01-19 06:14:08 Moscow +2038-01-19 06:14:08 UTCI +2106-02-07 06:28:15 Moscow +2106-02-07 09:28:15 UTCI +SET @@session.time_zone = 'UTC'; +INSERT INTO t2 SELECT * FROM t1; +SELECT * FROM t2 ORDER BY a DESC; +a tz +2106-02-07 06:28:15 UTCI +2106-02-07 03:28:15 Moscow +2038-01-19 03:14:08 UTCI +2038-01-19 03:14:08 Moscow +2038-01-19 03:14:07 UTCI +2038-01-19 03:14:07 Moscow +0000-00-00 00:00:00 UTCI +0000-00-00 00:00:00 Moscow +SELECT MIN(a), MAX(a) FROM t2; +MIN(a) MAX(a) +0000-00-00 00:00:00 2106-02-07 06:28:15 +UPDATE IGNORE t2 SET a = TIMESTAMPADD(SECOND, 1, a); +Warnings: +Warning 1292 Incorrect datetime value: '0000-00-00 00:00:00' +Warning 1292 Incorrect datetime value: '0000-00-00 00:00:00' +Warning 1264 Out of range value for column 'a' at row 5 +SELECT MIN(a), MAX(a) FROM t2; +MIN(a) MAX(a) +0000-00-00 00:00:00 2106-02-07 03:28:16 +SELECT * FROM t2 ORDER BY a, tz; +a tz +NULL Moscow +NULL UTCI +0000-00-00 00:00:00 UTCI +2038-01-19 03:14:08 Moscow +2038-01-19 03:14:08 UTCI +2038-01-19 03:14:09 Moscow +2038-01-19 03:14:09 UTCI +2106-02-07 03:28:16 Moscow +DROP TABLE t1,t2; +SET @@session.time_zone= @old_time_zone; diff --git a/mysql-test/main/partition_datatype_64.test b/mysql-test/main/partition_datatype_64.test new file mode 100644 index 00000000000..0c5a43aadb9 --- /dev/null +++ b/mysql-test/main/partition_datatype_64.test @@ -0,0 +1,56 @@ +--source include/have_partition.inc +--source include/have_64bit_timestamp.inc + +--echo # +--echo # Bug#28928: UNIX_TIMESTAMP() should be considered unary monotonic +--echo # by partition pruning +--echo # Testing end ranges + +SET @old_time_zone= @@session.time_zone; +SET @@session.time_zone = 'UTC'; +--echo # Using MyISAM to get stable values on TABLE_ROWS in I_S.PARTITIONS +CREATE TABLE t1 +(a TIMESTAMP NULL, + tz varchar(16)) +ENGINE = MyISAM; +CREATE TABLE t2 LIKE t1; +ALTER TABLE t2 PARTITION BY RANGE (UNIX_TIMESTAMP(a)) +(PARTITION `p0` VALUES LESS THAN (0), + PARTITION `p-2000` VALUES LESS THAN (UNIX_TIMESTAMP(20000101)), + PARTITION `p-2011-MSK` VALUES LESS THAN (UNIX_TIMESTAMP(20110326230000)), + PARTITION `p-2011-MSD-1` VALUES LESS THAN (UNIX_TIMESTAMP(20111029220000)), + PARTITION `p-2011-MSD-2` VALUES LESS THAN (UNIX_TIMESTAMP(20111029230000)), + PARTITION `p-2012-MSK-1` VALUES LESS THAN (UNIX_TIMESTAMP(20111030000000)), + PARTITION `p-2012-MSK-2` VALUES LESS THAN (UNIX_TIMESTAMP(20120324230000)), + PARTITION `pEnd` VALUES LESS THAN (UNIX_TIMESTAMP(20380119031407)), + PARTITION `pMax` VALUES LESS THAN MAXVALUE); + +--echo # Test invalid values +INSERT IGNORE INTO t1 VALUES ('2038-01-19 03:14:08', 'UTCI'); +INSERT IGNORE INTO t1 VALUES ('2106-02-07 06:28:16', 'UTCI'); +--echo # Test end range +INSERT INTO t1 VALUES ('2038-01-19 03:14:07', 'UTCI'); +INSERT INTO t1 VALUES ('2106-02-07 06:28:15', 'UTCI'); + +SET @@session.time_zone = 'Europe/Moscow'; + +--echo # Test invalid values +INSERT IGNORE INTO t1 VALUES ('2038-01-19 06:14:08', 'Moscow'); +INSERT IGNORE INTO t1 VALUES ('2106-02-07 09:28:16', 'Moscow'); +--echo # Test end range +INSERT INTO t1 VALUES ('2038-01-19 06:14:07', 'Moscow'); +INSERT INTO t1 VALUES ('2106-02-07 06:28:15', 'Moscow'); + +SELECT * FROM t1 ORDER BY a, tz; + +SET @@session.time_zone = 'UTC'; +INSERT INTO t2 SELECT * FROM t1; +SELECT * FROM t2 ORDER BY a DESC; + +SELECT MIN(a), MAX(a) FROM t2; +UPDATE IGNORE t2 SET a = TIMESTAMPADD(SECOND, 1, a); +SELECT MIN(a), MAX(a) FROM t2; +SELECT * FROM t2 ORDER BY a, tz; + +DROP TABLE t1,t2; +SET @@session.time_zone= @old_time_zone; diff --git a/mysql-test/main/timezone.result b/mysql-test/main/timezone.result index 2a099e90bad..7250cb21b00 100644 --- a/mysql-test/main/timezone.result +++ b/mysql-test/main/timezone.result @@ -51,11 +51,9 @@ DROP TABLE t1; # Test for fix for Bug#2523 Check that boundary dates are processed correctly. # select unix_timestamp('1970-01-01 01:00:00'), -unix_timestamp('1970-01-01 01:00:01'), -unix_timestamp('2038-01-19 04:14:07'), -unix_timestamp('2038-01-19 04:14:08'); -unix_timestamp('1970-01-01 01:00:00') unix_timestamp('1970-01-01 01:00:01') unix_timestamp('2038-01-19 04:14:07') unix_timestamp('2038-01-19 04:14:08') -0 1 2147483647 NULL +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 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') NULL NULL NULL diff --git a/mysql-test/main/timezone.test b/mysql-test/main/timezone.test index 50e062b45f1..3a45509d63c 100644 --- a/mysql-test/main/timezone.test +++ b/mysql-test/main/timezone.test @@ -50,9 +50,7 @@ DROP TABLE t1; --echo # Test for fix for Bug#2523 Check that boundary dates are processed correctly. --echo # select unix_timestamp('1970-01-01 01:00:00'), - unix_timestamp('1970-01-01 01:00:01'), - unix_timestamp('2038-01-19 04:14:07'), - unix_timestamp('2038-01-19 04:14:08'); + unix_timestamp('1970-01-01 01:00:01'); 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'); diff --git a/mysql-test/main/timezone2.result b/mysql-test/main/timezone2.result index 382ed447c92..795b83b5c1f 100644 --- a/mysql-test/main/timezone2.result +++ b/mysql-test/main/timezone2.result @@ -116,11 +116,10 @@ create table t1 (ts timestamp); set time_zone='UTC'; insert into t1 values ('0000-00-00 00:00:00'),('1969-12-31 23:59:59'), ('1970-01-01 00:00:00'),('1970-01-01 00:00:01'), -('2038-01-19 03:14:07'),('2038-01-19 03:14:08'); +('2038-01-19 03:14:07'); Warnings: Warning 1264 Out of range value for column 'ts' at row 2 Warning 1264 Out of range value for column 'ts' at row 3 -Warning 1264 Out of range value for column 'ts' at row 6 select * from t1; ts 0000-00-00 00:00:00 @@ -128,16 +127,14 @@ ts 0000-00-00 00:00:00 1970-01-01 00:00:01 2038-01-19 03:14:07 -0000-00-00 00:00:00 truncate table t1; set time_zone='MET'; insert into t1 values ('0000-00-00 00:00:00'),('1970-01-01 00:30:00'), ('1970-01-01 01:00:00'),('1970-01-01 01:00:01'), -('2038-01-19 04:14:07'),('2038-01-19 04:14:08'); +('2038-01-19 04:14:07'); Warnings: Warning 1264 Out of range value for column 'ts' at row 2 Warning 1264 Out of range value for column 'ts' at row 3 -Warning 1264 Out of range value for column 'ts' at row 6 select * from t1; ts 0000-00-00 00:00:00 @@ -145,16 +142,14 @@ ts 0000-00-00 00:00:00 1970-01-01 01:00:01 2038-01-19 04:14:07 -0000-00-00 00:00:00 truncate table t1; set time_zone='+01:30'; insert into t1 values ('0000-00-00 00:00:00'),('1970-01-01 01:00:00'), ('1970-01-01 01:30:00'),('1970-01-01 01:30:01'), -('2038-01-19 04:44:07'),('2038-01-19 04:44:08'); +('2038-01-19 04:44:07'); Warnings: Warning 1264 Out of range value for column 'ts' at row 2 Warning 1264 Out of range value for column 'ts' at row 3 -Warning 1264 Out of range value for column 'ts' at row 6 select * from t1; ts 0000-00-00 00:00:00 @@ -162,7 +157,6 @@ ts 0000-00-00 00:00:00 1970-01-01 01:30:01 2038-01-19 04:44:07 -0000-00-00 00:00:00 drop table t1; show variables like 'time_zone'; Variable_name Value @@ -226,12 +220,6 @@ convert_tz('2003-10-26 04:00:00', 'MET', 'UTC') select convert_tz('2038-01-19 04:14:07', 'MET', 'UTC'); convert_tz('2038-01-19 04:14:07', 'MET', 'UTC') 2038-01-19 03:14:07 -select convert_tz('2038-01-19 04:14:08', 'MET', 'UTC'); -convert_tz('2038-01-19 04:14:08', 'MET', 'UTC') -2038-01-19 04:14:08 -select convert_tz('2103-01-01 04:00:00', 'MET', 'UTC'); -convert_tz('2103-01-01 04:00:00', 'MET', 'UTC') -2103-01-01 04:00:00 create table t1 (tz varchar(3)); insert into t1 (tz) values ('MET'), ('UTC'); select tz, convert_tz('2003-12-31 00:00:00',tz,'UTC'), convert_tz('2003-12-31 00:00:00','UTC',tz) from t1 order by tz; diff --git a/mysql-test/main/timezone2.test b/mysql-test/main/timezone2.test index 09be74089ce..5a110e7c225 100644 --- a/mysql-test/main/timezone2.test +++ b/mysql-test/main/timezone2.test @@ -118,21 +118,21 @@ create table t1 (ts timestamp); set time_zone='UTC'; insert into t1 values ('0000-00-00 00:00:00'),('1969-12-31 23:59:59'), ('1970-01-01 00:00:00'),('1970-01-01 00:00:01'), - ('2038-01-19 03:14:07'),('2038-01-19 03:14:08'); + ('2038-01-19 03:14:07'); select * from t1; truncate table t1; # MET time zone has range shifted by one hour set time_zone='MET'; insert into t1 values ('0000-00-00 00:00:00'),('1970-01-01 00:30:00'), ('1970-01-01 01:00:00'),('1970-01-01 01:00:01'), - ('2038-01-19 04:14:07'),('2038-01-19 04:14:08'); + ('2038-01-19 04:14:07'); select * from t1; truncate table t1; # same for +01:30 time zone set time_zone='+01:30'; insert into t1 values ('0000-00-00 00:00:00'),('1970-01-01 01:00:00'), ('1970-01-01 01:30:00'),('1970-01-01 01:30:01'), - ('2038-01-19 04:44:07'),('2038-01-19 04:44:08'); + ('2038-01-19 04:44:07'); select * from t1; drop table t1; @@ -183,8 +183,6 @@ select convert_tz('2003-10-26 02:00:00', 'MET', 'UTC'); select convert_tz('2003-10-26 02:59:59', 'MET', 'UTC'); select convert_tz('2003-10-26 04:00:00', 'MET', 'UTC'); select convert_tz('2038-01-19 04:14:07', 'MET', 'UTC'); -select convert_tz('2038-01-19 04:14:08', 'MET', 'UTC'); -select convert_tz('2103-01-01 04:00:00', 'MET', 'UTC'); # Let us test variable time zone argument create table t1 (tz varchar(3)); diff --git a/mysql-test/main/type_timestamp,32bit.rdiff b/mysql-test/main/type_timestamp,32bit.rdiff new file mode 100644 index 00000000000..dd48488d66e --- /dev/null +++ b/mysql-test/main/type_timestamp,32bit.rdiff @@ -0,0 +1,145 @@ +--- main/type_timestamp.result ++++ main/type_timestamp.reject +@@ -1,4 +1,3 @@ +-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 + 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where + Warnings: +-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP/*WITH LOCAL TIME ZONE*/'2040-01-01 10:20:30' ++Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2040-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 + 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where +@@ -1389,7 +1388,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 + Warnings: +-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP/*WITH LOCAL TIME ZONE*/'2040-01-01 10:20:30' ++Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2040-01-01 10:20:30' + EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=10010101102030; + 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 +@@ -1404,7 +1403,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 + Warnings: +-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP/*WITH LOCAL TIME ZONE*/'2040-01-01 10:20:30' ++Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 20400101102030 + EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=10010101102030e0; + 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 +@@ -1419,7 +1418,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 + Warnings: +-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP/*WITH LOCAL TIME ZONE*/'2040-01-01 10:20:30.000000' ++Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 20400101102030e0 + EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=10010101102030.0; + 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 +@@ -1434,17 +1433,17 @@ + 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 + Warnings: +-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP/*WITH LOCAL TIME ZONE*/'2040-01-01 10:20:30.0' ++Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 20400101102030.0 + EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=DATE_ADD('2020-01-01 10:20:30', INTERVAL 30 YEAR); + 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 + Warnings: +-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP/*WITH LOCAL TIME ZONE*/'2050-01-01 10:20:30' ++Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2050-01-01 10:20:30' + EXPLAIN EXTENDED SELECT * FROM t1 WHERE COALESCE(NULL, a)=DATE_ADD('2020-01-01 10:20:30', INTERVAL 30 YEAR); + 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 + Warnings: +-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(NULL,`test`.`t1`.`a`) = TIMESTAMP/*WITH LOCAL TIME ZONE*/'2050-01-01 10:20:30' ++Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(NULL,`test`.`t1`.`a`) = ('2020-01-01 10:20:30' + interval 30 year) + # + # Comparison predicates: Good TIMESTAMP values switch to TIMESTAMP comparison + # +@@ -1570,22 +1569,22 @@ + 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 + 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` = (from_unixtime(0x7fffffff - 24 * 3600 + 1)) + 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 + 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where + 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'2038-01-18 03:14:08' + EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=TIMESTAMP'2038-01-19 03:14:07'; + 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 + 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'2038-01-19 03:14:07' + EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=FROM_UNIXTIME(0x7FFFFFFF); + 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 + 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` = (from_unixtime(0x7fffffff)) + # + # Corner cases: rounding + # +@@ -1620,7 +1619,7 @@ + 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where + Warnings: + Note 1292 Truncated incorrect DATETIME value: '2038-01-18 03:14:07.9999999' +-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.000000' ++Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2038-01-18 03:14:08.000000' + SET sql_mode=DEFAULT; + # + # NULLIF: Bad TIMESTAMP values preserve DATETIME comparison +@@ -1639,7 +1638,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 + Warnings: +-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where nullif(`test`.`t1`.`a`,TIMESTAMP/*WITH LOCAL TIME ZONE*/'2040-01-01 10:20:30') ++Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where nullif(`test`.`t1`.`a`,TIMESTAMP'2040-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 + 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where +@@ -1654,7 +1653,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 + Warnings: +-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where nullif(`test`.`t1`.`a`,TIMESTAMP/*WITH LOCAL TIME ZONE*/'2040-01-01 10:20:30') ++Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where nullif(`test`.`t1`.`a`,'2040-01-01 10:20:30') + EXPLAIN EXTENDED SELECT * FROM t1 WHERE NULLIF(a,10010101102030); + 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 +@@ -1669,7 +1668,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 + Warnings: +-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where nullif(`test`.`t1`.`a`,TIMESTAMP/*WITH LOCAL TIME ZONE*/'2040-01-01 10:20:30') ++Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where nullif(`test`.`t1`.`a`,20400101102030) + EXPLAIN EXTENDED SELECT * FROM t1 WHERE NULLIF(a,10010101102030e0); + 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 +@@ -1684,7 +1683,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 + Warnings: +-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where nullif(`test`.`t1`.`a`,TIMESTAMP/*WITH LOCAL TIME ZONE*/'2040-01-01 10:20:30.000000') ++Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where nullif(`test`.`t1`.`a`,20400101102030e0) + EXPLAIN EXTENDED SELECT * FROM t1 WHERE NULLIF(a,10010101102030.0); + 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 +@@ -1699,7 +1698,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 + Warnings: +-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where nullif(`test`.`t1`.`a`,TIMESTAMP/*WITH LOCAL TIME ZONE*/'2040-01-01 10:20:30.0') ++Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where nullif(`test`.`t1`.`a`,20400101102030.0) + # + # NULLIF: Good TIMESTAMP values switch to TIMESTAMP comparison + # diff --git a/mysql-test/main/type_timestamp.result b/mysql-test/main/type_timestamp.result index a378ab808d2..24cb5fdd507 100644 --- a/mysql-test/main/type_timestamp.result +++ b/mysql-test/main/type_timestamp.result @@ -1,4 +1,3 @@ -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 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=TIMESTAMP'2040-01-01 10:20:30'; 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 Warnings: -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2040-01-01 10:20:30' +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP/*WITH LOCAL TIME ZONE*/'2040-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 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where @@ -1389,7 +1388,7 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2040-01-01 10:20:30'; 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 Warnings: -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2040-01-01 10:20:30' +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP/*WITH LOCAL TIME ZONE*/'2040-01-01 10:20:30' EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=10010101102030; 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 @@ -1404,7 +1403,7 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=20400101102030; 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 Warnings: -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 20400101102030 +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP/*WITH LOCAL TIME ZONE*/'2040-01-01 10:20:30' EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=10010101102030e0; 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 @@ -1419,7 +1418,7 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=20400101102030e0; 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 Warnings: -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 20400101102030e0 +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP/*WITH LOCAL TIME ZONE*/'2040-01-01 10:20:30.000000' EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=10010101102030.0; 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 @@ -1434,17 +1433,17 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=20400101102030.0; 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 Warnings: -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 20400101102030.0 +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP/*WITH LOCAL TIME ZONE*/'2040-01-01 10:20:30.0' EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=DATE_ADD('2020-01-01 10:20:30', INTERVAL 30 YEAR); 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 Warnings: -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2050-01-01 10:20:30' +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP/*WITH LOCAL TIME ZONE*/'2050-01-01 10:20:30' EXPLAIN EXTENDED SELECT * FROM t1 WHERE COALESCE(NULL, a)=DATE_ADD('2020-01-01 10:20:30', INTERVAL 30 YEAR); 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 Warnings: -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(NULL,`test`.`t1`.`a`) = ('2020-01-01 10:20:30' + interval 30 year) +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(NULL,`test`.`t1`.`a`) = TIMESTAMP/*WITH LOCAL TIME ZONE*/'2050-01-01 10:20:30' # # Comparison predicates: Good TIMESTAMP values switch to TIMESTAMP comparison # @@ -1570,22 +1569,22 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=FROM_UNIXTIME(0x7FFFFFFF-24*3600+1); 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 Warnings: -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = (from_unixtime(0x7fffffff - 24 * 3600 + 1)) +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' 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 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where Warnings: -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'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' EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=TIMESTAMP'2038-01-19 03:14:07'; 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 Warnings: -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/*WITH LOCAL TIME ZONE*/'2038-01-19 03:14:07' EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=FROM_UNIXTIME(0x7FFFFFFF); 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 Warnings: -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = (from_unixtime(0x7fffffff)) +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' # # Corner cases: rounding # @@ -1620,7 +1619,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 Warnings: Note 1292 Truncated incorrect DATETIME value: '2038-01-18 03:14:07.9999999' -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2038-01-18 03:14:08.000000' +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.000000' SET sql_mode=DEFAULT; # # NULLIF: Bad TIMESTAMP values preserve DATETIME comparison @@ -1639,7 +1638,7 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE NULLIF(a,TIMESTAMP'2040-01-01 10:20:30') 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 Warnings: -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where nullif(`test`.`t1`.`a`,TIMESTAMP'2040-01-01 10:20:30') +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where nullif(`test`.`t1`.`a`,TIMESTAMP/*WITH LOCAL TIME ZONE*/'2040-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 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where @@ -1654,7 +1653,7 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE NULLIF(a,'2040-01-01 10:20:30'); 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 Warnings: -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where nullif(`test`.`t1`.`a`,'2040-01-01 10:20:30') +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where nullif(`test`.`t1`.`a`,TIMESTAMP/*WITH LOCAL TIME ZONE*/'2040-01-01 10:20:30') EXPLAIN EXTENDED SELECT * FROM t1 WHERE NULLIF(a,10010101102030); 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 @@ -1669,7 +1668,7 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE NULLIF(a,20400101102030); 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 Warnings: -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where nullif(`test`.`t1`.`a`,20400101102030) +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where nullif(`test`.`t1`.`a`,TIMESTAMP/*WITH LOCAL TIME ZONE*/'2040-01-01 10:20:30') EXPLAIN EXTENDED SELECT * FROM t1 WHERE NULLIF(a,10010101102030e0); 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 @@ -1684,7 +1683,7 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE NULLIF(a,20400101102030e0); 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 Warnings: -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where nullif(`test`.`t1`.`a`,20400101102030e0) +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where nullif(`test`.`t1`.`a`,TIMESTAMP/*WITH LOCAL TIME ZONE*/'2040-01-01 10:20:30.000000') EXPLAIN EXTENDED SELECT * FROM t1 WHERE NULLIF(a,10010101102030.0); 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 @@ -1699,7 +1698,7 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE NULLIF(a,20400101102030.0); 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 Warnings: -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where nullif(`test`.`t1`.`a`,20400101102030.0) +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where nullif(`test`.`t1`.`a`,TIMESTAMP/*WITH LOCAL TIME ZONE*/'2040-01-01 10:20:30.0') # # NULLIF: Good TIMESTAMP values switch to TIMESTAMP comparison # diff --git a/mysql-test/main/type_timestamp.test b/mysql-test/main/type_timestamp.test index 56f02c750d8..bee6614420c 100644 --- a/mysql-test/main/type_timestamp.test +++ b/mysql-test/main/type_timestamp.test @@ -2,9 +2,7 @@ # Test timestamp # ---disable_warnings -drop table if exists t1,t2; ---enable_warnings +--source include/word_size.inc # Set timezone to GMT-3, to make it possible to use "interval 3 hour" set time_zone="+03:00"; diff --git a/mysql-test/main/type_timestamp_round.result b/mysql-test/main/type_timestamp_round.result index 7931aa0ff5b..ff4ef28a23b 100644 --- a/mysql-test/main/type_timestamp_round.result +++ b/mysql-test/main/type_timestamp_round.result @@ -69,15 +69,11 @@ SET time_zone='+00:00'; CREATE TABLE t1 (ID INT, a TIMESTAMP(6), comment VARCHAR(64)); INSERT INTO t1 VALUES (0, '2038-01-18 23:59:59.999999', 'Should round'); INSERT INTO t1 VALUES (1, '2038-01-19 03:14:06.999999', 'Should round'); -INSERT INTO t1 VALUES (2, '2038-01-19 03:14:07.999999', 'Should truncate'); ALTER TABLE t1 MODIFY a TIMESTAMP(5); -Warnings: -Warning 1264 Out of range value for column 'a' at row 3 SELECT * FROM t1; ID a comment 0 2038-01-19 00:00:00.00000 Should round 1 2038-01-19 03:14:07.00000 Should round -2 2038-01-19 03:14:07.99999 Should truncate DROP TABLE t1; SET time_zone=DEFAULT; # @@ -179,13 +175,5 @@ UPDATE t1 SET ts0=COALESCE(ts1); SELECT * FROM t1; ts0 ts1 2001-01-01 10:20:31 2001-01-01 10:20:30.9 -# Corner case -UPDATE t1 SET ts1=FROM_UNIXTIME(2147483647.9); -UPDATE t1 SET ts0=COALESCE(ts1); -Warnings: -Warning 1264 Out of range value for column 'ts0' at row 1 -SELECT * FROM t1; -ts0 ts1 -2038-01-19 03:14:07 2038-01-19 03:14:07.9 DROP TABLE t1; SET time_zone=DEFAULT; diff --git a/mysql-test/main/type_timestamp_round.test b/mysql-test/main/type_timestamp_round.test index 19e0ea86da5..5ed4979961a 100644 --- a/mysql-test/main/type_timestamp_round.test +++ b/mysql-test/main/type_timestamp_round.test @@ -60,7 +60,6 @@ SET time_zone='+00:00'; CREATE TABLE t1 (ID INT, a TIMESTAMP(6), comment VARCHAR(64)); INSERT INTO t1 VALUES (0, '2038-01-18 23:59:59.999999', 'Should round'); INSERT INTO t1 VALUES (1, '2038-01-19 03:14:06.999999', 'Should round'); -INSERT INTO t1 VALUES (2, '2038-01-19 03:14:07.999999', 'Should truncate'); ALTER TABLE t1 MODIFY a TIMESTAMP(5); SELECT * FROM t1; DROP TABLE t1; @@ -152,9 +151,5 @@ SELECT * FROM t1; --echo # This should round UPDATE t1 SET ts0=COALESCE(ts1); SELECT * FROM t1; ---echo # Corner case -UPDATE t1 SET ts1=FROM_UNIXTIME(2147483647.9); -UPDATE t1 SET ts0=COALESCE(ts1); -SELECT * FROM t1; DROP TABLE t1; SET time_zone=DEFAULT; diff --git a/mysql-test/main/variables.result b/mysql-test/main/variables.result index 2230e5a35df..0d1f171f91f 100644 --- a/mysql-test/main/variables.result +++ b/mysql-test/main/variables.result @@ -1001,11 +1001,11 @@ hostname # SET @@myisam_mmap_size= 500M; ERROR HY000: Variable 'myisam_mmap_size' is a read only variable # -# Bug #52315: utc_date() crashes when system time > year 2037 +# Bug #52315: utc_date() crashes when system time > year 2106 # -SET TIMESTAMP=2*1024*1024*1024; +SET TIMESTAMP=5*1024*1024*1024; Warnings: -Warning 1292 Truncated incorrect timestamp value: '2147483648' +Warning 1292 Truncated incorrect timestamp value: '5368709120' #Should not crash SELECT UTC_DATE(); SET TIMESTAMP=DEFAULT; diff --git a/mysql-test/main/variables.test b/mysql-test/main/variables.test index 227f7704e9c..af89c1d0247 100644 --- a/mysql-test/main/variables.test +++ b/mysql-test/main/variables.test @@ -753,11 +753,11 @@ SET @@myisam_mmap_size= 500M; --echo # ---echo # Bug #52315: utc_date() crashes when system time > year 2037 +--echo # Bug #52315: utc_date() crashes when system time > year 2106 --echo # --error 0, ER_WRONG_VALUE_FOR_VAR -SET TIMESTAMP=2*1024*1024*1024; +SET TIMESTAMP=5*1024*1024*1024; --echo #Should not crash --disable_result_log SELECT UTC_DATE(); diff --git a/mysql-test/suite/sys_vars/inc/sysvars_server.inc b/mysql-test/suite/sys_vars/inc/sysvars_server.inc index 8fca98e0383..f8dd3dc4c30 100644 --- a/mysql-test/suite/sys_vars/inc/sysvars_server.inc +++ b/mysql-test/suite/sys_vars/inc/sysvars_server.inc @@ -24,7 +24,7 @@ select VARIABLE_NAME,VARIABLE_SCOPE,VARIABLE_TYPE,VARIABLE_COMMENT,NUMERIC_MIN_V variable_name not like 'wsrep%' and variable_name not like 's3%' and variable_name not in ( - 'log_tc_size','have_sanitizer' + 'log_tc_size','have_sanitizer','timestamp' ) order by variable_name; diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result index 6f8b1cf9fb2..59d1877107f 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result @@ -9,7 +9,7 @@ where variable_name not like 'debug%' and variable_name not like 'wsrep%' and variable_name not like 's3%' and variable_name not in ( -'log_tc_size','have_sanitizer' +'log_tc_size','have_sanitizer','timestamp' ) order by variable_name; VARIABLE_NAME ALLOW_SUSPICIOUS_UDFS @@ -3892,16 +3892,6 @@ NUMERIC_BLOCK_SIZE 1024 ENUM_VALUE_LIST NULL READ_ONLY YES COMMAND_LINE_ARGUMENT REQUIRED -VARIABLE_NAME TIMESTAMP -VARIABLE_SCOPE SESSION ONLY -VARIABLE_TYPE DOUBLE -VARIABLE_COMMENT Set the time for this client -NUMERIC_MIN_VALUE 0 -NUMERIC_MAX_VALUE 2147483647 -NUMERIC_BLOCK_SIZE NULL -ENUM_VALUE_LIST NULL -READ_ONLY NO -COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME TIME_ZONE VARIABLE_SCOPE SESSION VARIABLE_TYPE VARCHAR diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result index f55011307d4..5068fe422cb 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result @@ -9,7 +9,7 @@ where variable_name not like 'debug%' and variable_name not like 'wsrep%' and variable_name not like 's3%' and variable_name not in ( -'log_tc_size','have_sanitizer' +'log_tc_size','have_sanitizer','timestamp' ) order by variable_name; VARIABLE_NAME ALLOW_SUSPICIOUS_UDFS @@ -4752,16 +4752,6 @@ NUMERIC_BLOCK_SIZE 1024 ENUM_VALUE_LIST NULL READ_ONLY YES COMMAND_LINE_ARGUMENT REQUIRED -VARIABLE_NAME TIMESTAMP -VARIABLE_SCOPE SESSION ONLY -VARIABLE_TYPE DOUBLE -VARIABLE_COMMENT Set the time for this client -NUMERIC_MIN_VALUE 0 -NUMERIC_MAX_VALUE 2147483647 -NUMERIC_BLOCK_SIZE NULL -ENUM_VALUE_LIST NULL -READ_ONLY NO -COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME TIME_ZONE VARIABLE_SCOPE SESSION VARIABLE_TYPE VARCHAR diff --git a/mysql-test/suite/sys_vars/t/timestamp_basic.test b/mysql-test/suite/sys_vars/t/timestamp_basic.test index 5f780e7ab40..3cbee499429 100644 --- a/mysql-test/suite/sys_vars/t/timestamp_basic.test +++ b/mysql-test/suite/sys_vars/t/timestamp_basic.test @@ -73,6 +73,7 @@ SET @@timestamp = 1.1; SELECT @@timestamp; SET @@timestamp = 9999999999999999999999; +--replace_result 4294967295 2147483647 SELECT @@timestamp; --echo '#--------------------FN_DYNVARS_001_04-------------------------#' diff --git a/mysql-test/suite/versioning/common.inc b/mysql-test/suite/versioning/common.inc index 9b901846e9f..2e4342be54c 100644 --- a/mysql-test/suite/versioning/common.inc +++ b/mysql-test/suite/versioning/common.inc @@ -3,6 +3,7 @@ if (!$TEST_VERSIONING_SO) --skip needs test_versioning plugin } source include/have_innodb.inc; +source sys_time.inc; --disable_query_log set @@session.time_zone='+00:00'; @@ -45,7 +46,6 @@ let $default_engine= `select @@default_storage_engine`; let $non_default_engine= `select if(@@default_storage_engine = 'InnoDB', 'MyISAM', 'InnoDB')`; let $sys_datatype_expl= timestamp(6); let $sys_datatype_expl_uc= TIMESTAMP(6); -let $sys_datatype_max= TIMESTAMP'2038-01-19 03:14:07.999999'; if ($MTR_COMBINATION_MYISAM) { @@ -74,7 +74,7 @@ deterministic eval create or replace function current_row_ts(sys_trx_end timestamp(6)) returns int deterministic - return convert_tz(sys_trx_end, '+00:00', @@time_zone) = TIMESTAMP'2038-01-19 03:14:07.999999'; + return convert_tz(sys_trx_end, '+00:00', @@time_zone) = $sys_time_max; delimiter ~~; eval create or replace function check_row(row_start $sys_datatype_expl, row_end $sys_datatype_expl) diff --git a/mysql-test/suite/versioning/r/cte,32bit.rdiff b/mysql-test/suite/versioning/r/cte,32bit.rdiff new file mode 100644 index 00000000000..842d192ca26 --- /dev/null +++ b/mysql-test/suite/versioning/r/cte,32bit.rdiff @@ -0,0 +1,11 @@ +--- suite/versioning/r/cte.result ++++ suite/versioning/r/cte.reject +@@ -146,7 +146,7 @@ + 3 RECURSIVE UNION ref key0 key0 5 test.e.mgr 1 100.00 + NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL + Warnings: +-Note 1003 with recursive ancestors as (/* select#2 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` where `test`.`e`.`name` = 'bill' and `test`.`e`.`row_end` > TIMESTAMP/*WITH LOCAL TIME ZONE*/'YYYY-MM-DD hh:ss:mm:.uuuuuu' and `test`.`e`.`row_start` <= TIMESTAMP/*WITH LOCAL TIME ZONE*/'YYYY-MM-DD hh:ss:mm:.uuuuuu' union /* select#3 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` join `ancestors` `a` where `a`.`emp_id` = `test`.`e`.`mgr` and `test`.`e`.`row_end` > TIMESTAMP/*WITH LOCAL TIME ZONE*/'YYYY-MM-DD hh:ss:mm:.uuuuuu' and `test`.`e`.`row_start` <= TIMESTAMP/*WITH LOCAL TIME ZONE*/'YYYY-MM-DD hh:ss:mm:.uuuuuu')/* select#1 */ select `test`.`emp`.`name` AS `name` from `test`.`emp` semi join (`ancestors`) where `ancestors`.`emp_id` = `test`.`emp`.`emp_id` and `test`.`emp`.`row_end` = TIMESTAMP'2106-02-07 06:28:15.999999' ++Note 1003 with recursive ancestors as (/* select#2 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` where `test`.`e`.`name` = 'bill' and `test`.`e`.`row_end` > TIMESTAMP/*WITH LOCAL TIME ZONE*/'YYYY-MM-DD hh:ss:mm:.uuuuuu' and `test`.`e`.`row_start` <= TIMESTAMP/*WITH LOCAL TIME ZONE*/'YYYY-MM-DD hh:ss:mm:.uuuuuu' union /* select#3 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` join `ancestors` `a` where `a`.`emp_id` = `test`.`e`.`mgr` and `test`.`e`.`row_end` > TIMESTAMP/*WITH LOCAL TIME ZONE*/'YYYY-MM-DD hh:ss:mm:.uuuuuu' and `test`.`e`.`row_start` <= TIMESTAMP/*WITH LOCAL TIME ZONE*/'YYYY-MM-DD hh:ss:mm:.uuuuuu')/* select#1 */ select `test`.`emp`.`name` AS `name` from `test`.`emp` semi join (`ancestors`) where `ancestors`.`emp_id` = `test`.`emp`.`emp_id` and `test`.`emp`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999' + with recursive + ancestors + as diff --git a/mysql-test/suite/versioning/r/cte.result b/mysql-test/suite/versioning/r/cte.result index 4a9eba56006..ffda40f0ce0 100644 --- a/mysql-test/suite/versioning/r/cte.result +++ b/mysql-test/suite/versioning/r/cte.result @@ -146,7 +146,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 3 RECURSIVE UNION ref key0 key0 5 test.e.mgr 1 100.00 NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: -Note 1003 with recursive ancestors as (/* select#2 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` where `test`.`e`.`name` = 'bill' and `test`.`e`.`row_end` > TIMESTAMP/*WITH LOCAL TIME ZONE*/'YYYY-MM-DD hh:ss:mm:.uuuuuu' and `test`.`e`.`row_start` <= TIMESTAMP/*WITH LOCAL TIME ZONE*/'YYYY-MM-DD hh:ss:mm:.uuuuuu' union /* select#3 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` join `ancestors` `a` where `a`.`emp_id` = `test`.`e`.`mgr` and `test`.`e`.`row_end` > TIMESTAMP/*WITH LOCAL TIME ZONE*/'YYYY-MM-DD hh:ss:mm:.uuuuuu' and `test`.`e`.`row_start` <= TIMESTAMP/*WITH LOCAL TIME ZONE*/'YYYY-MM-DD hh:ss:mm:.uuuuuu')/* select#1 */ select `test`.`emp`.`name` AS `name` from `test`.`emp` semi join (`ancestors`) where `ancestors`.`emp_id` = `test`.`emp`.`emp_id` and `test`.`emp`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999' +Note 1003 with recursive ancestors as (/* select#2 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` where `test`.`e`.`name` = 'bill' and `test`.`e`.`row_end` > TIMESTAMP/*WITH LOCAL TIME ZONE*/'YYYY-MM-DD hh:ss:mm:.uuuuuu' and `test`.`e`.`row_start` <= TIMESTAMP/*WITH LOCAL TIME ZONE*/'YYYY-MM-DD hh:ss:mm:.uuuuuu' union /* select#3 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` join `ancestors` `a` where `a`.`emp_id` = `test`.`e`.`mgr` and `test`.`e`.`row_end` > TIMESTAMP/*WITH LOCAL TIME ZONE*/'YYYY-MM-DD hh:ss:mm:.uuuuuu' and `test`.`e`.`row_start` <= TIMESTAMP/*WITH LOCAL TIME ZONE*/'YYYY-MM-DD hh:ss:mm:.uuuuuu')/* select#1 */ select `test`.`emp`.`name` AS `name` from `test`.`emp` semi join (`ancestors`) where `ancestors`.`emp_id` = `test`.`emp`.`emp_id` and `test`.`emp`.`row_end` = TIMESTAMP'2106-02-07 06:28:15.999999' with recursive ancestors as diff --git a/mysql-test/suite/versioning/r/data.result b/mysql-test/suite/versioning/r/data.result index 08ab03ffcd4..504a008bef8 100644 --- a/mysql-test/suite/versioning/r/data.result +++ b/mysql-test/suite/versioning/r/data.result @@ -100,7 +100,7 @@ CREATE TABLE `t1` ( /*!40101 SET character_set_client = @saved_cs_client */; /*!101100 SET @old_system_versioning_insert_history=@@session.system_versioning_insert_history, @@session.system_versioning_insert_history=1 */; INSERT INTO `t1` (`x`, row_start, row_end) VALUES (1,'2010-10-10 10:10:10.101010','2011-11-11 11:11:11.111111'), -(2,'2010-10-10 10:10:10.101010','2038-01-19 03:14:07.999999'); +(2,'2010-10-10 10:10:10.101010','MAX_TIME'); /*!101100 SET system_versioning_insert_history=@old_system_versioning_insert_history */; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; @@ -113,7 +113,7 @@ CREATE TABLE `t2` ( /*!40101 SET character_set_client = @saved_cs_client */; /*!101100 SET @old_system_versioning_insert_history=@@session.system_versioning_insert_history, @@session.system_versioning_insert_history=1 */; INSERT INTO `t2` (`x`, `row_start`, `row_end`) VALUES (1,'2010-10-10 10:10:10.101010','2011-11-11 11:11:11.111111'), -(2,'2010-10-10 10:10:10.101010','2038-01-19 03:14:07.999999'); +(2,'2010-10-10 10:10:10.101010','MAX_TIME'); /*!101100 SET system_versioning_insert_history=@old_system_versioning_insert_history */; mariadb-dump: --dump-history can't be used with --as-of. mariadb-dump: --dump-history can't be used with --replace. diff --git a/mysql-test/suite/versioning/r/delete_history,32bit.rdiff b/mysql-test/suite/versioning/r/delete_history,32bit.rdiff new file mode 100644 index 00000000000..ded21820c1c --- /dev/null +++ b/mysql-test/suite/versioning/r/delete_history,32bit.rdiff @@ -0,0 +1,11 @@ +--- suite/versioning/r/delete_history.result ++++ suite/versioning/r/delete_history.reject +@@ -167,7 +167,7 @@ + id select_type table type possible_keys key key_len ref rows filtered Extra + 1 SIMPLE t1 ALL NULL NULL NULL NULL 1 100.00 Using where + Warnings: +-Note 1003 delete from `test`.`t1` FOR SYSTEM_TIME BEFORE TIMESTAMP '2039-01-01 23:00' using dual where `test`.`t1`.`row_end` < TIMESTAMP/*WITH LOCAL TIME ZONE*/'2039-01-01 23:00:00' and is_history(`test`.`t1`.`row_end`) ++Note 1003 delete from `test`.`t1` FOR SYSTEM_TIME BEFORE TIMESTAMP '2039-01-01 23:00' using dual where `test`.`t1`.`row_end` < '2039-01-01 23:00' and is_history(`test`.`t1`.`row_end`) + create or replace procedure p() delete history from t1 before system_time '2039-01-01 23:00'; + call p; + select * from t1; diff --git a/mysql-test/suite/versioning/r/delete_history.result b/mysql-test/suite/versioning/r/delete_history.result index 04483a864c1..dc614977374 100644 --- a/mysql-test/suite/versioning/r/delete_history.result +++ b/mysql-test/suite/versioning/r/delete_history.result @@ -167,7 +167,7 @@ explain extended delete history from t1 before system_time '2039-01-01 23:00'; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 1 100.00 Using where Warnings: -Note 1003 delete from `test`.`t1` FOR SYSTEM_TIME BEFORE TIMESTAMP '2039-01-01 23:00' using dual where `test`.`t1`.`row_end` < '2039-01-01 23:00' and is_history(`test`.`t1`.`row_end`) +Note 1003 delete from `test`.`t1` FOR SYSTEM_TIME BEFORE TIMESTAMP '2039-01-01 23:00' using dual where `test`.`t1`.`row_end` < TIMESTAMP/*WITH LOCAL TIME ZONE*/'2039-01-01 23:00:00' and is_history(`test`.`t1`.`row_end`) create or replace procedure p() delete history from t1 before system_time '2039-01-01 23:00'; call p; select * from t1; diff --git a/mysql-test/suite/versioning/r/insert.result b/mysql-test/suite/versioning/r/insert.result index fab71b9f1cc..42b9400efe4 100644 --- a/mysql-test/suite/versioning/r/insert.result +++ b/mysql-test/suite/versioning/r/insert.result @@ -140,7 +140,7 @@ insert into t1(x, row_start, row_end) values (3, '1980-01-01 00:00:00', '1980-01 insert into t2(y, row_start, row_end) values (4, '1980-01-01 00:00:00', '1980-01-01 00:00:01'); insert into t3 values (5, '1980-01-01 00:00:00', '1980-01-01 00:00:01'); insert into t3 values (5, '1980-01-02 00:00:00', '1980-01-01 00:00:01'); -ERROR HY000: Incorrect row_start value: '1980-01-02 00:00:00.000000' +ERROR HY000: Incorrect system-version range 'row_start' value: '1980-01-02 00:00:00.000000' and 'row_end' value: '1980-01-01 00:00:01.000000' select x, row_start, row_end from t1 for system_time all; x row_start row_end 3 1980-01-01 00:00:00.000000 1980-01-01 00:00:01.000000 @@ -166,13 +166,13 @@ ERROR HY000: The value specified for generated column 'row_end' in table 't2' ha insert into t1 values (4); insert into t1 set x= 5, row_start= '1980-01-01 00:00:00', row_end= '1980-01-01 00:00:01'; insert into t1(x, row_start, row_end) values (6, '1980-01-01 00:00:01', '1980-01-01 00:00:00'); -ERROR HY000: Incorrect row_start value: '1980-01-01 00:00:01.000000' +ERROR HY000: Incorrect system-version range 'row_start' value: '1980-01-01 00:00:01.000000' and 'row_end' value: '1980-01-01 00:00:00.000000' insert into t1(x, row_start, row_end) values (7, '1980-01-01 00:00:11', '1980-01-01 00:00:11'); -ERROR HY000: Incorrect row_start value: '1980-01-01 00:00:11.000000' +ERROR HY000: Incorrect system-version range 'row_start' value: '1980-01-01 00:00:11.000000' and 'row_end' value: '1980-01-01 00:00:11.000000' insert into t1(x, row_start) values (8, '1980-01-01 00:00:22'); insert into t1(x, row_end) values (9, '1980-01-01 00:00:33'); -ERROR HY000: Incorrect row_start value: 'now' -insert into t1(x, row_end) values (10, TIMESTAMP'2038-01-19 03:14:07.999999'); +ERROR HY000: Incorrect system-version range 'row_start' value: 'now' +insert into t1(x, row_end) values (10, MAX_TIMESTAMP); select x, check_row_ts(row_start, row_end) from t1 for system_time all order by x; x check_row_ts(row_start, row_end) 1 HISTORICAL ROW @@ -183,7 +183,7 @@ x check_row_ts(row_start, row_end) 8 CURRENT ROW 10 CURRENT ROW select x, row_start, row_end from t1 for system_time all -where x > 1 and row_end < TIMESTAMP'2038-01-19 03:14:07.999999' order by x, row_start, row_end; +where x > 1 and row_end < MAX_TIMESTAMP order by x, row_start, row_end; x row_start row_end 3 1980-01-01 00:00:00.000000 1980-01-01 00:00:01.000000 5 1980-01-01 00:00:00.000000 1980-01-01 00:00:01.000000 @@ -210,7 +210,7 @@ x check_row_ts(row_start, row_end) 8 CURRENT ROW 10 CURRENT ROW select x, row_start, row_end from t2 for system_time all -where x > 1 and row_end < TIMESTAMP'2038-01-19 03:14:07.999999' order by x, row_start, row_end; +where x > 1 and row_end < MAX_TIMESTAMP order by x, row_start, row_end; x row_start row_end 3 1980-01-01 00:00:00.000000 1980-01-01 00:00:01.000000 5 1980-01-01 00:00:00.000000 1980-01-01 00:00:01.000000 diff --git a/mysql-test/suite/versioning/r/insert2.result b/mysql-test/suite/versioning/r/insert2.result index f5c7b411cdf..e530309716f 100644 --- a/mysql-test/suite/versioning/r/insert2.result +++ b/mysql-test/suite/versioning/r/insert2.result @@ -1,3 +1,4 @@ +set @@time_zone='+00:00'; create table t1( x int unsigned, sys_start bigint unsigned as row start invisible, @@ -66,7 +67,7 @@ c varchar(8), period for system_time(s, e)) with system versioning; insert into t1 values (1, null, null, 'foo'); -select i, c, e>TIMESTAMP'2038-01-01 00:00:00' AS current_row from t1; +select i, c, e>LEFT(SYS_TIME_MAX, 10) AS current_row from t1;; i c current_row 1 foo 1 drop table t1; @@ -84,3 +85,4 @@ select pk,i,row_end > '2038-01-01' from t1 for system_time all; pk i row_end > '2038-01-01' 1 1000 1 drop table t1; +set @@time_zone=default; diff --git a/mysql-test/suite/versioning/r/misc.result b/mysql-test/suite/versioning/r/misc.result index fadc896d185..ceeb6de354b 100644 --- a/mysql-test/suite/versioning/r/misc.result +++ b/mysql-test/suite/versioning/r/misc.result @@ -16,10 +16,10 @@ create trigger tr before insert on t for each row set new.b=1, new.s = '2022-03- insert into t (a) values (3),(4); select * from t for system_time all; a b s e -1 2 2010-10-10 10:10:10.000000 2038-01-19 03:14:07.999999 -2 3 2010-10-10 10:10:10.000000 2038-01-19 03:14:07.999999 -3 4 2010-10-10 10:10:10.000000 2038-01-19 03:14:07.999999 -4 5 2010-10-10 10:10:10.000000 2038-01-19 03:14:07.999999 +1 2 2010-10-10 10:10:10.000000 SYS_TIME_MAX +2 3 2010-10-10 10:10:10.000000 SYS_TIME_MAX +3 4 2010-10-10 10:10:10.000000 SYS_TIME_MAX +4 5 2010-10-10 10:10:10.000000 SYS_TIME_MAX drop table t; set sql_mode=default, timestamp=default; # @@ -38,12 +38,12 @@ insert t1 values (5,'2020-01-01',default), (6,'2020-02-02',ignore),(7,default,'2 set timestamp=default; select * from t1 for system_time all; a s e -1 2020-01-01 00:00:00.000000 2038-01-19 03:14:07.999999 -2 2020-02-02 00:00:00.000000 2038-01-19 03:14:07.999999 +1 2020-01-01 00:00:00.000000 SYS_TIME_MAX +2 2020-02-02 00:00:00.000000 SYS_TIME_MAX 3 2010-10-10 10:10:10.000000 2020-03-03 00:00:00.000000 4 2010-10-10 10:10:10.000000 2020-04-04 00:00:00.000000 -5 2020-01-01 00:00:00.000000 2038-01-19 03:14:07.999999 -6 2020-02-02 00:00:00.000000 2038-01-19 03:14:07.999999 +5 2020-01-01 00:00:00.000000 SYS_TIME_MAX +6 2020-02-02 00:00:00.000000 SYS_TIME_MAX 7 2010-11-11 11:11:11.000000 2020-03-03 00:00:00.000000 8 2010-11-11 11:11:11.000000 2020-04-04 00:00:00.000000 drop table t1; diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result index 863a3c71d3e..fd3f5cbe714 100644 --- a/mysql-test/suite/versioning/r/partition.result +++ b/mysql-test/suite/versioning/r/partition.result @@ -169,7 +169,7 @@ set @now= now(6); insert into t1 values (1); set @str= concat('select x, row_start < @now as A, row_end > @now as B from t1 partition (p0)'); prepare select_p0 from @str; -set @str= concat('select x, row_start > @now as C, row_end = timestamp\'2038-01-19 03:14:07.999999\' as D from t1 partition (pn)'); +set @str= concat("select x, row_start > @now as C, row_end = SYS_TIME_MAX as D from t1 partition (pn)");; prepare select_pn from @str; execute select_p0; x A B @@ -302,7 +302,7 @@ create table t1 (i int) with system versioning partition by system_time interval 6 day limit 98; 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 'limit 98' at line 2 create or replace table t1 (pk int) with system versioning -partition by system_time interval 10 year partitions 3; +partition by system_time interval 60 year partitions 3; ERROR 22003: TIMESTAMP value is out of range in 'INTERVAL' # INTERVAL and ALTER TABLE create or replace table t1 (i int) with system versioning @@ -3409,7 +3409,7 @@ insert into t1 (a,row_start,row_end) values ('p0', '2021-09-30', '2021-09-30 10:00:00'), ('p1', '2021-09-30', '2021-10-01 10:00:00'), ('overflows, so also p1','2021-09-30', '2021-10-10 10:00:00'), -('pn, current', '2021-09-30', '2038-01-19 03:14:07.999999'); +('pn, current', '2021-09-30', SYS_TIME_MAX); select table_name,partition_name,partition_ordinal_position,partition_method,partition_description,table_rows from information_schema.partitions where table_schema='test'; table_name partition_name partition_ordinal_position partition_method partition_description table_rows diff --git a/mysql-test/suite/versioning/r/rpl_row.result b/mysql-test/suite/versioning/r/rpl_row.result index c161f68d0bd..f49cedc2508 100644 --- a/mysql-test/suite/versioning/r/rpl_row.result +++ b/mysql-test/suite/versioning/r/rpl_row.result @@ -35,14 +35,14 @@ set timestamp= 12345; insert t1 values (1, 1); select *, unix_timestamp(row_start) as row_start, unix_timestamp(row_end) as row_end from t1; x y row_start row_end -1 1 12345.000000 2147483647.999999 +1 1 12345.000000 TIMESTAMP_MAX.999999 set timestamp= default; ### INSERT INTO `test`.`t1` ### SET ### @1=1 ### @2=1 ### @3=12345.000000 -### @4=2147483647.999999 +### @4=MAX_TIMESTAMP.999999 connection slave; select * from t1; x y diff --git a/mysql-test/suite/versioning/r/select.result b/mysql-test/suite/versioning/r/select.result index c4e8df1a743..a84816327fd 100644 --- a/mysql-test/suite/versioning/r/select.result +++ b/mysql-test/suite/versioning/r/select.result @@ -265,6 +265,7 @@ drop view vt1; create or replace table t1(x int) with system versioning; select * from (t1 as r left join t1 as u using (x)), t1; x x +set @@time_zone="+00:00"; create or replace table t1 (a int) with system versioning; insert into t1 values (1); create trigger read_end after update on t1 @@ -273,6 +274,7 @@ update t1 set a=2; select @end; @end MAX_RESULT +set @@time_zone=default; create or replace table t1 (a int) with system versioning; create or replace table t2 (b int) with system versioning; insert into t1 values (1); @@ -329,7 +331,7 @@ 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; Using join buffer (flat, BNL join) 1 SIMPLE t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join) Warnings: -Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `a` from `test`.`t1` left join (`test`.`t1` `t2` left join `test`.`t1` `t3` on(`test`.`t3`.`a` = `test`.`t2`.`a` and `test`.`t3`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999')) on(`test`.`t2`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999' and `test`.`t1`.`a` > 1) where `test`.`t1`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999' +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `a` from `test`.`t1` left join (`test`.`t1` `t2` left join `test`.`t1` `t3` on(`test`.`t3`.`a` = `test`.`t2`.`a` and `test`.`t3`.`row_end` = SYS_TIME_MAX)) on(`test`.`t2`.`row_end` = SYS_TIME_MAX and `test`.`t1`.`a` > 1) where `test`.`t1`.`row_end` = SYS_TIME_MAX select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1; a a 2 1 @@ -558,7 +560,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join) 1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join) Warnings: -Note 1003 select `test`.`t1`.`f1` AS `f1` from `test`.`t1` join `test`.`t2` left join (`test`.`t3` left join `test`.`t4` on(`test`.`t4`.`f4` = `test`.`t2`.`f2` and `test`.`t4`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999')) on(`test`.`t3`.`f3` = `test`.`t2`.`f2`) where `test`.`t1`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999' +Note 1003 select `test`.`t1`.`f1` AS `f1` from `test`.`t1` join `test`.`t2` left join (`test`.`t3` left join `test`.`t4` on(`test`.`t4`.`f4` = `test`.`t2`.`f2` and `test`.`t4`.`row_end` = SYS_TIME_MAX)) on(`test`.`t3`.`f3` = `test`.`t2`.`f2`) where `test`.`t1`.`row_end` = SYS_TIME_MAX drop view v1; drop table t1, t2, t3, t4; # diff --git a/mysql-test/suite/versioning/r/trx_id.result b/mysql-test/suite/versioning/r/trx_id.result index d9abbe9cc54..4526d7fdf98 100644 --- a/mysql-test/suite/versioning/r/trx_id.result +++ b/mysql-test/suite/versioning/r/trx_id.result @@ -401,10 +401,10 @@ ERROR HY000: Transaction-precise system versioning for `t2` is not supported # # String literals resolve to TIMESTAMP # -SELECT * FROM t1 FOR SYSTEM_TIME AS OF '2038-12-30 00:00:00'; +SELECT * FROM t1 FOR SYSTEM_TIME AS OF '2107-12-30 00:00:00'; x 1 -SELECT * FROM t2 FOR SYSTEM_TIME AS OF '2038-12-30 00:00:00'; +SELECT * FROM t2 FOR SYSTEM_TIME AS OF '2107-12-30 00:00:00'; x DROP TABLE t1, t2; # diff --git a/mysql-test/suite/versioning/sys_time.inc b/mysql-test/suite/versioning/sys_time.inc new file mode 100644 index 00000000000..b3eca0a378e --- /dev/null +++ b/mysql-test/suite/versioning/sys_time.inc @@ -0,0 +1,12 @@ +--disable_query_log +if (`SELECT from_unixtime((1<<31)+24*3600) is null`) { + let $sys_time_max_replace= 2038-01-19 03:14:07.999999; + let $sys_timestamp_max=2147483647; +} +if (`SELECT from_unixtime((1<<31)+24*3600) is not null`) { + let $sys_time_max_replace= 2106-02-07 06:28:15.999999; + let $sys_timestamp_max=4294967295; +} +let $sys_time_max= TIMESTAMP'$sys_time_max_replace'; +let $sys_datatype_max= $sys_time_max; +--enable_query_log diff --git a/mysql-test/suite/versioning/t/cte.test b/mysql-test/suite/versioning/t/cte.test index f57f7d14cef..d38f52dcd7e 100644 --- a/mysql-test/suite/versioning/t/cte.test +++ b/mysql-test/suite/versioning/t/cte.test @@ -4,6 +4,8 @@ if (`SELECT $PS_PROTOCOL != 0`) } --source include/have_innodb.inc --source include/default_optimizer_switch.inc +--source include/word_size.inc +--source suite/versioning/sys_time.inc --let $replace_regex_tsltz6= /TIMESTAMP..WITH LOCAL TIME ZONE..'....-..-.. ..:..:..[.]......'/TIMESTAMP\/*WITH LOCAL TIME ZONE*\/'YYYY-MM-DD hh:ss:mm:.uuuuuu'/ @@ -109,7 +111,7 @@ as ) select name from emp where emp_id in (select emp_id from ancestors for system_time as of timestamp @ts_1); ---replace_regex $replace_regex_tsltz6 +--replace_regex $replace_regex_tsltz6 /$sys_time_max/SYS_TIME_MAX/ eval explain extended $q; eval $q; diff --git a/mysql-test/suite/versioning/t/data.test b/mysql-test/suite/versioning/t/data.test index fb996258124..c87a2368d11 100644 --- a/mysql-test/suite/versioning/t/data.test +++ b/mysql-test/suite/versioning/t/data.test @@ -67,6 +67,7 @@ select x, check_fields(x, row_start, row_end) from t2 for system_time all order --exec $MYSQL_DUMP --databases test > $TMP/dump_no_history.sql --exec $MYSQL_DUMP --dump-history --no-create-info --skip-comments --databases test > $TMP/dump_only_data.sql --exec $MYSQL_DUMP --dump-history --compact test 2>&1 > $TMP/dump_history_compact.sql +--replace_result $sys_time_max_replace MAX_TIME --cat_file $TMP/dump_history_compact.sql --replace_result mariadb-dump.exe mariadb-dump --error 1 diff --git a/mysql-test/suite/versioning/t/delete_history.test b/mysql-test/suite/versioning/t/delete_history.test index 66c28568b22..374650c0513 100644 --- a/mysql-test/suite/versioning/t/delete_history.test +++ b/mysql-test/suite/versioning/t/delete_history.test @@ -1,6 +1,7 @@ --source suite/versioning/common.inc --source include/have_partition.inc --source suite/versioning/engines.inc +--source include/word_size.inc call mtr.add_suppression("need more HISTORY partitions"); diff --git a/mysql-test/suite/versioning/t/foreign.test b/mysql-test/suite/versioning/t/foreign.test index 5f228747108..fe58a2b75ee 100644 --- a/mysql-test/suite/versioning/t/foreign.test +++ b/mysql-test/suite/versioning/t/foreign.test @@ -224,6 +224,7 @@ create or replace table child( insert into parent values(1); insert into child values(1); + -- error ER_ROW_IS_REFERENCED_2 delete from parent; -- error ER_ROW_IS_REFERENCED_2 diff --git a/mysql-test/suite/versioning/t/insert.test b/mysql-test/suite/versioning/t/insert.test index f4c54eb6cc4..45c0ddb1e37 100644 --- a/mysql-test/suite/versioning/t/insert.test +++ b/mysql-test/suite/versioning/t/insert.test @@ -85,7 +85,7 @@ drop table t2; --echo # MDEV-16546 System versioning setting to allow history modification --echo # set @@session.time_zone='+00:00'; -let $MAX_TIMESTAMP= TIMESTAMP'2038-01-19 03:14:07.999999'; +let $MAX_TIMESTAMP= $sys_time_max; create table t1(x int primary key) with system versioning; create table t2(y int primary key, @@ -108,7 +108,7 @@ show create table t1; insert into t1(x, row_start, row_end) values (3, '1980-01-01 00:00:00', '1980-01-01 00:00:01'); insert into t2(y, row_start, row_end) values (4, '1980-01-01 00:00:00', '1980-01-01 00:00:01'); insert into t3 values (5, '1980-01-01 00:00:00', '1980-01-01 00:00:01'); ---error ER_WRONG_VALUE +--error ER_WRONG_VERSIONING_RANGE insert into t3 values (5, '1980-01-02 00:00:00', '1980-01-01 00:00:01'); select x, row_start, row_end from t1 for system_time all; @@ -132,16 +132,19 @@ insert t2 (y,row_end) values (1, '1970-01-01 00:00:00') on duplicate key update # this should work, row_start/row_end must be mentioned explicitly: insert into t1 values (4); insert into t1 set x= 5, row_start= '1980-01-01 00:00:00', row_end= '1980-01-01 00:00:01'; ---error ER_WRONG_VALUE +--error ER_WRONG_VERSIONING_RANGE insert into t1(x, row_start, row_end) values (6, '1980-01-01 00:00:01', '1980-01-01 00:00:00'); ---error ER_WRONG_VALUE +--error ER_WRONG_VERSIONING_RANGE insert into t1(x, row_start, row_end) values (7, '1980-01-01 00:00:11', '1980-01-01 00:00:11'); insert into t1(x, row_start) values (8, '1980-01-01 00:00:22'); --replace_regex /'202\d-\d\d-\d\d .*'/'now'/ ---error ER_WRONG_VALUE +--error ER_WRONG_VERSIONING_RANGE insert into t1(x, row_end) values (9, '1980-01-01 00:00:33'); + +--replace_result $MAX_TIMESTAMP MAX_TIMESTAMP eval insert into t1(x, row_end) values (10, $MAX_TIMESTAMP); select x, check_row_ts(row_start, row_end) from t1 for system_time all order by x; +--replace_result $MAX_TIMESTAMP MAX_TIMESTAMP eval select x, row_start, row_end from t1 for system_time all where x > 1 and row_end < $MAX_TIMESTAMP order by x, row_start, row_end; --echo # Direct insert is not possible for TRX_ID versioning @@ -159,6 +162,7 @@ create or replace table t2 like t1; set @@system_versioning_insert_history= 1; insert into t2 (x, row_start, row_end) select x, row_start, row_end from t1 for system_time all; select x, check_row_ts(row_start, row_end) from t2 for system_time all order by x; +--replace_result $MAX_TIMESTAMP MAX_TIMESTAMP eval select x, row_start, row_end from t2 for system_time all where x > 1 and row_end < $MAX_TIMESTAMP order by x, row_start, row_end; set @@system_versioning_insert_history= 0; diff --git a/mysql-test/suite/versioning/t/insert2.test b/mysql-test/suite/versioning/t/insert2.test index 1e7d2166064..0a1968f91ef 100644 --- a/mysql-test/suite/versioning/t/insert2.test +++ b/mysql-test/suite/versioning/t/insert2.test @@ -1,4 +1,6 @@ --source include/have_innodb.inc +set @@time_zone='+00:00'; +--source suite/versioning/sys_time.inc # TRT test @@ -64,7 +66,8 @@ create or replace table t1 ( period for system_time(s, e)) with system versioning; insert into t1 values (1, null, null, 'foo'); -select i, c, e>TIMESTAMP'2038-01-01 00:00:00' AS current_row from t1; +--replace_result $sys_time_max SYS_TIME_MAX +--eval select i, c, e>LEFT($sys_time_max, 10) AS current_row from t1; drop table t1; drop table t2; @@ -84,3 +87,6 @@ create table t1 (pk int primary key, i int) with system versioning; replace into t1 values (1,10),(1,100),(1,1000); select pk,i,row_end > '2038-01-01' from t1 for system_time all; drop table t1; + +# Cleanup +set @@time_zone=default; \ No newline at end of file diff --git a/mysql-test/suite/versioning/t/misc.test b/mysql-test/suite/versioning/t/misc.test index fa5012b6efa..95d7eb6a2f9 100644 --- a/mysql-test/suite/versioning/t/misc.test +++ b/mysql-test/suite/versioning/t/misc.test @@ -1,8 +1,11 @@ +--source suite/versioning/sys_time.inc + # # simple tests that don't need to be run in multiple various combinations # set time_zone='+00:00'; + --echo # --echo # MDEV-29750 triggers can modify history --echo # @@ -11,6 +14,7 @@ create table t (a int, b int as (a+1), s timestamp(6) as row start, e timestamp( insert into t values (1,1, '2022-01-01','2023-01-01'),(2,2, '2022-02-02','2023-02-02'); create trigger tr before insert on t for each row set new.b=1, new.s = '2022-03-03', new.e = '2023-03-03'; insert into t (a) values (3),(4); +--replace_result $sys_time_max_replace SYS_TIME_MAX select * from t for system_time all; drop table t; set sql_mode=default, timestamp=default; @@ -33,6 +37,7 @@ insert t1 (a,s,e) values (1,'2020-01-01',default), (2,'2020-02-02',ignore),(3,de set timestamp=unix_timestamp('2010-11-11 11:11:11'); insert t1 values (5,'2020-01-01',default), (6,'2020-02-02',ignore),(7,default,'2020-03-03'), (8,ignore,'2020-04-04'); set timestamp=default; +--replace_result $sys_time_max_replace SYS_TIME_MAX select * from t1 for system_time all; drop table t1; diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test index 5707746f96c..e09431d8ab8 100644 --- a/mysql-test/suite/versioning/t/partition.test +++ b/mysql-test/suite/versioning/t/partition.test @@ -179,7 +179,8 @@ set @now= now(6); insert into t1 values (1); set @str= concat('select x, row_start < @now as A, row_end > @now as B from t1 partition (p0)'); prepare select_p0 from @str; -set @str= concat('select x, row_start > @now as C, row_end = timestamp\'2038-01-19 03:14:07.999999\' as D from t1 partition (pn)'); +--replace_result $sys_time_max SYS_TIME_MAX +--eval set @str= concat("select x, row_start > @now as C, row_end = $sys_time_max as D from t1 partition (pn)"); prepare select_pn from @str; execute select_p0; @@ -278,7 +279,7 @@ partition by system_time interval 6 day limit 98; --error ER_DATA_OUT_OF_RANGE create or replace table t1 (pk int) with system versioning -partition by system_time interval 10 year partitions 3; +partition by system_time interval 60 year partitions 3; --echo # INTERVAL and ALTER TABLE create or replace table t1 (i int) with system versioning @@ -2646,11 +2647,12 @@ create table t1 (a varchar(100)) with system versioning partition by system_time interval 1 day starts '2021-09-30 00:00:00' partitions 3; set system_versioning_insert_history=1; -insert into t1 (a,row_start,row_end) values +--replace_result $sys_time_max SYS_TIME_MAX +eval insert into t1 (a,row_start,row_end) values ('p0', '2021-09-30', '2021-09-30 10:00:00'), ('p1', '2021-09-30', '2021-10-01 10:00:00'), ('overflows, so also p1','2021-09-30', '2021-10-10 10:00:00'), -('pn, current', '2021-09-30', '2038-01-19 03:14:07.999999'); +('pn, current', '2021-09-30', $sys_time_max); select table_name,partition_name,partition_ordinal_position,partition_method,partition_description,table_rows from information_schema.partitions where table_schema='test'; drop table t1; diff --git a/mysql-test/suite/versioning/t/rpl_row.test b/mysql-test/suite/versioning/t/rpl_row.test index e36d77fc023..aa020fafa8e 100644 --- a/mysql-test/suite/versioning/t/rpl_row.test +++ b/mysql-test/suite/versioning/t/rpl_row.test @@ -1,6 +1,7 @@ --source include/have_binlog_format_row.inc --source include/master-slave.inc --source include/have_innodb.inc +--source suite/versioning/sys_time.inc --echo # MDEV-16252: MINIMAL binlog_row_image does not work for versioned tables set @old_row_image= @@binlog_row_image; @@ -39,6 +40,7 @@ show create table t1; set timestamp= 12345; --let $start_pos= query_get_value("SHOW MASTER STATUS", Position, 1) insert t1 values (1, 1); +--replace_result $sys_timestamp_max TIMESTAMP_MAX select *, unix_timestamp(row_start) as row_start, unix_timestamp(row_end) as row_end from t1; --let $stop_pos= query_get_value("SHOW MASTER STATUS", Position, 1) set timestamp= default; @@ -46,6 +48,7 @@ set timestamp= default; # NOTE: pipe grep is not Windows-compatible --let grep_file= $TMP/out.txt --let grep_regex= ^### +--let grep_filter=s{$sys_timestamp_max}{MAX_TIMESTAMP}; --exec $MYSQL_BINLOG -v -j $start_pos --stop-position=$stop_pos -o 3 $MYSQLD_DATADIR/master-bin.000001 > $grep_file --source include/grep.inc --sync_slave_with_master diff --git a/mysql-test/suite/versioning/t/select.test b/mysql-test/suite/versioning/t/select.test index b9a836f708e..7d5b6801d6f 100644 --- a/mysql-test/suite/versioning/t/select.test +++ b/mysql-test/suite/versioning/t/select.test @@ -186,13 +186,15 @@ create or replace table t1(x int) with system versioning; select * from (t1 as r left join t1 as u using (x)), t1; # @end should be max +set @@time_zone="+00:00"; create or replace table t1 (a int) with system versioning; insert into t1 values (1); create trigger read_end after update on t1 for each row set @end = old.row_end; update t1 set a=2; ---replace_result 18446744073709551615 MAX_RESULT "2038-01-19 03:14:07.999999" MAX_RESULT +--replace_result 18446744073709551615 MAX_RESULT $sys_time_max_replace MAX_RESULT select @end; +set @@time_zone=default; create or replace table t1 (a int) with system versioning; create or replace table t2 (b int) with system versioning; @@ -223,6 +225,7 @@ create or replace table t1 (a int) with system versioning; insert into t1 values (1); insert into t1 values (2); insert into t1 values (3); +--replace_result $sys_time_max SYS_TIME_MAX explain extended select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1; select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1; @@ -377,6 +380,7 @@ select f1 from t1 join t2 left join t3 left join t4 on f3 = f4 on f3 = f2; insert t2 values (1),(2); insert t3 values (1),(2); insert t4 values (1),(2); +--replace_result $sys_time_max SYS_TIME_MAX explain extended select f1 from t1 join t2 left join t3 left join t4 on f3 = f4 on f3 = f2; diff --git a/mysql-test/suite/versioning/t/select2.test b/mysql-test/suite/versioning/t/select2.test index 53840b390b6..54bcbc77429 100644 --- a/mysql-test/suite/versioning/t/select2.test +++ b/mysql-test/suite/versioning/t/select2.test @@ -160,7 +160,7 @@ insert into t1 values (1); create trigger read_end after update on t1 for each row set @end = old.row_end; update t1 set a=2; ---replace_result 18446744073709551615 MAX_RESULT "2038-01-19 03:14:07.999999" MAX_RESULT +--replace_result 18446744073709551615 MAX_RESULT $sys_time_max_replace MAX_RESULT select @end; create or replace table t1 (a int) with system versioning; diff --git a/mysql-test/suite/versioning/t/trx_id.test b/mysql-test/suite/versioning/t/trx_id.test index 60836279f52..fcb46832136 100644 --- a/mysql-test/suite/versioning/t/trx_id.test +++ b/mysql-test/suite/versioning/t/trx_id.test @@ -440,8 +440,8 @@ DELIMITER ;$$ --echo # String literals resolve to TIMESTAMP --echo # -SELECT * FROM t1 FOR SYSTEM_TIME AS OF '2038-12-30 00:00:00'; -SELECT * FROM t2 FOR SYSTEM_TIME AS OF '2038-12-30 00:00:00'; +SELECT * FROM t1 FOR SYSTEM_TIME AS OF '2107-12-30 00:00:00'; +SELECT * FROM t2 FOR SYSTEM_TIME AS OF '2107-12-30 00:00:00'; DROP TABLE t1, t2; diff --git a/mysql-test/suite/versioning/t/view.test b/mysql-test/suite/versioning/t/view.test index 9bb915f7b77..94079cbb549 100644 --- a/mysql-test/suite/versioning/t/view.test +++ b/mysql-test/suite/versioning/t/view.test @@ -56,7 +56,7 @@ select * from vt1; --echo # VIEW with parameters [tempesta-tech/mariadb#151] create or replace table t1 (x int) with system versioning; create or replace view vt1(c) as select x from t1; ---replace_result 18446744073709551615 MAX_RESULT "TIMESTAMP'2038-01-19 03:14:07.999999'" MAX_RESULT +--replace_result 18446744073709551615 MAX_RESULT $sys_time_max_replace MAX_RESULT show create view vt1; --echo # VIEW over JOIN of versioned tables [tempesta-tech/mariadb#153] diff --git a/sql-common/my_time.c b/sql-common/my_time.c index 96674723b34..6e9bac5e504 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -1251,7 +1251,8 @@ my_time_t my_system_gmt_sec(const MYSQL_TIME *t_src, long *my_timezone, uint *error_code) { uint loop; - time_t tmp= 0; + longlong tmp= 0; + time_t temporary_time; int shift= 0; MYSQL_TIME tmp_time; MYSQL_TIME *t= &tmp_time; @@ -1319,9 +1320,9 @@ my_system_gmt_sec(const MYSQL_TIME *t_src, long *my_timezone, uint *error_code) relevant to QNX. We are safe with shifts close to MAX_INT32, as there are no known - time switches on Jan 2038 yet :) + time switches on Febrary 2106 yet :) */ - if ((t->year == TIMESTAMP_MAX_YEAR) && (t->month == 1) && (t->day > 4)) + if ((t->year == TIMESTAMP_MAX_YEAR) && (t->month == 2) && (t->day > 17)) { /* Below we will pass (uint) (t->day - shift) to calc_daynr. @@ -1331,11 +1332,10 @@ my_system_gmt_sec(const MYSQL_TIME *t_src, long *my_timezone, uint *error_code) t->day-= 2; shift= 2; } -#ifdef TIME_T_UNSIGNED else { /* - We can get 0 in time_t representaion only on 1969, 31 of Dec or on + We can get 0 in time_t representation only on 1969, 31 of Dec or on 1970, 1 of Jan. For both dates we use shift, which is added to t->day in order to step out a bit from the border. This is required for platforms, where time_t is unsigned. @@ -1343,6 +1343,7 @@ my_system_gmt_sec(const MYSQL_TIME *t_src, long *my_timezone, uint *error_code) Note: the order of below if-statements is significant. */ + /* 1970 */ if ((t->year == TIMESTAMP_MIN_YEAR + 1) && (t->month == 1) && (t->day <= 10)) { @@ -1350,6 +1351,7 @@ my_system_gmt_sec(const MYSQL_TIME *t_src, long *my_timezone, uint *error_code) shift= -2; } + /* 1969 */ if ((t->year == TIMESTAMP_MIN_YEAR) && (t->month == 12) && (t->day == 31)) { @@ -1359,17 +1361,18 @@ my_system_gmt_sec(const MYSQL_TIME *t_src, long *my_timezone, uint *error_code) shift= -2; } } -#endif - tmp= (time_t) (((calc_daynr((uint) t->year, (uint) t->month, (uint) t->day) - - (long) days_at_timestart) * SECONDS_IN_24H + - (long) t->hour*3600L + - (long) (t->minute*60 + t->second)) + (time_t) my_time_zone - - 3600); + tmp= (((longlong) (calc_daynr((uint) t->year, (uint) t->month, + (uint) t->day) - + days_at_timestart) * SECONDS_IN_24H + + (long) t->hour*3600L + + (long) (t->minute*60 + t->second)) + + my_time_zone - 3600); current_timezone= my_time_zone; - localtime_r(&tmp,&tm_tmp); - l_time=&tm_tmp; + temporary_time= (time_t) tmp; + localtime_r(&temporary_time, &tm_tmp); + l_time= &tm_tmp; for (loop=0; loop < 2 && (t->hour != (uint) l_time->tm_hour || @@ -1387,10 +1390,11 @@ my_system_gmt_sec(const MYSQL_TIME *t_src, long *my_timezone, uint *error_code) (long) (60*((int) t->minute - (int) l_time->tm_min)) + (long) ((int) t->second - (int) l_time->tm_sec)); current_timezone+= diff+3600; /* Compensate for -3600 above */ - tmp+= (time_t) diff; - localtime_r(&tmp,&tm_tmp); - l_time=&tm_tmp; + tmp+= (longlong) diff; + temporary_time= (time_t) tmp; + localtime_r(&temporary_time, &tm_tmp); } + /* Fix that if we are in the non existing daylight saving time hour we move the start of the next real hour. @@ -1427,14 +1431,8 @@ my_system_gmt_sec(const MYSQL_TIME *t_src, long *my_timezone, uint *error_code) /* This is possible for dates, which slightly exceed boundaries. Conversion will pass ok for them, but we don't allow them. - First check will pass for platforms with signed time_t. - instruction above (tmp+= shift*86400L) could exceed - MAX_INT32 (== TIMESTAMP_MAX_VALUE) and overflow will happen. - So, tmp < TIMESTAMP_MIN_VALUE will be triggered. On platfroms - with unsigned time_t tmp+= shift*86400L might result in a number, - larger then TIMESTAMP_MAX_VALUE, so another check will work. */ - if (!IS_TIME_T_VALID_FOR_TIMESTAMP(tmp)) + if (tmp < 0 || (ulonglong) tmp > TIMESTAMP_MAX_VALUE) { tmp= 0; *error_code= ER_WARN_DATA_OUT_OF_RANGE; diff --git a/sql/event_queue.cc b/sql/event_queue.cc index 7ed4d8c61a1..679fdd21801 100644 --- a/sql/event_queue.cc +++ b/sql/event_queue.cc @@ -632,7 +632,7 @@ Event_queue::get_top_for_execution_if_time(THD *thd, Not yet time for top event, wait on condition with time or until signaled. Release LOCK_queue while waiting. */ - struct timespec top_time= { next_activation_at, 0 }; + struct timespec top_time= { (time_t) next_activation_at, 0 }; /* Release any held audit resources before waiting */ mysql_audit_release(thd); diff --git a/sql/field.cc b/sql/field.cc index d044817d962..9a906698bf5 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -5290,14 +5290,14 @@ my_time_t Field_timestamp0::get_timestamp(const uchar *pos, { DBUG_ASSERT(marked_for_read()); *sec_part= 0; - return sint4korr(pos); + return uint4korr(pos); } bool Field_timestamp0::val_native(Native *to) { DBUG_ASSERT(marked_for_read()); - my_time_t sec= (my_time_t) sint4korr(ptr); + my_time_t sec= (my_time_t) uint4korr(ptr); return Timestamp_or_zero_datetime(Timestamp(sec, 0), sec == 0). to_native(to, 0); } @@ -5493,7 +5493,7 @@ longlong Field_timestamp::val_int(void) String *Field_timestamp::val_str(String *val_buffer, String *val_ptr) { MYSQL_TIME ltime; - uint32 temp, temp2; + uint32 year, temp, temp2; uint dec; char *to; @@ -5508,17 +5508,14 @@ String *Field_timestamp::val_str(String *val_buffer, String *val_ptr) } val_buffer->set_charset(&my_charset_numeric); // Safety - temp= ltime.year % 100; - if (temp < YY_PART_YEAR - 1) - { - *to++= '2'; - *to++= '0'; - } - else - { - *to++= '1'; - *to++= '9'; - } + temp= ltime.year; + DBUG_ASSERT(temp >= 1969); + + year= temp/100; + temp-= year*100; + temp2= year/10; year= year-temp2*10; + *to++= (char) ('0'+(char) (temp2)); + *to++= (char) ('0'+(char) (year)); temp2=temp/10; temp=temp-temp2*10; *to++= (char) ('0'+(char) (temp2)); *to++= (char) ('0'+(char) (temp)); @@ -5591,10 +5588,10 @@ bool Field_timestamp0::send(Protocol *protocol) int Field_timestamp0::cmp(const uchar *a_ptr, const uchar *b_ptr) const { - int32 a,b; - a=sint4korr(a_ptr); - b=sint4korr(b_ptr); - return ((uint32) a < (uint32) b) ? -1 : ((uint32) a > (uint32) b) ? 1 : 0; + time_t a,b; + a= uint4korr(a_ptr); + b= uint4korr(b_ptr); + return (a < b ) ? -1 : (a > b) ? 1 : 0; } @@ -5793,11 +5790,14 @@ void Field_timestampf::set_max() bool Field_timestampf::is_max() { + longlong timestamp= mi_uint4korr(ptr); DBUG_ENTER("Field_timestampf::is_max"); DBUG_ASSERT(marked_for_read()); - DBUG_RETURN(mi_sint4korr(ptr) == TIMESTAMP_MAX_VALUE && - mi_sint3korr(ptr + 4) == TIME_MAX_SECOND_PART); + /* Allow old max value and new max value */ + DBUG_RETURN((timestamp == TIMESTAMP_MAX_VALUE || + timestamp == INT_MAX32) && + mi_uint3korr(ptr + 4) == TIME_MAX_SECOND_PART); } my_time_t Field_timestampf::get_timestamp(const uchar *pos, diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 9ef1aa709a3..2cbcc3794f0 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -3652,7 +3652,7 @@ String *Item_func_binlog_gtid_pos::val_str(String *str) if (args[0]->null_value || args[1]->null_value) goto err; - if (pos < 0 || pos > (longlong) UINT_MAX32) + if (pos < 0 || (ulonglong) pos > UINT_MAX32) goto err; if (gtid_state_from_binlog_pos(name->c_ptr_safe(), (uint32)pos, str)) diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index a6aebf33489..f30ce5e2243 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1280,8 +1280,7 @@ my_decimal *Item_func_unix_timestamp::decimal_op(my_decimal* buf) if (get_timestamp_value(&seconds, &second_part)) return 0; - return seconds2my_decimal(seconds < 0, seconds < 0 ? -seconds : seconds, - second_part, buf); + return seconds2my_decimal(0, seconds, second_part, buf); } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 395a95595b8..8e5e9f0e630 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3926,12 +3926,14 @@ static int init_common_variables() mysql_bin_log.init_pthread_objects(); Gtid_index_writer::gtid_index_init(); +#if LONG_SIZE == 4 /* TODO: remove this when my_time_t is 64 bit compatible */ if (!IS_TIME_T_VALID_FOR_TIMESTAMP(server_start_time)) { sql_print_error("This server doesn't support dates later than 2038"); exit(1); } +#endif opt_log_basename= const_cast("mysql"); diff --git a/sql/opt_histogram_json.cc b/sql/opt_histogram_json.cc index 1aec9e53917..a28dee10fef 100644 --- a/sql/opt_histogram_json.cc +++ b/sql/opt_histogram_json.cc @@ -180,9 +180,8 @@ private: char buf[128]; String str(buf, sizeof(buf), system_charset_info); THD *thd= current_thd; - timeval tv= {thd->query_start(), 0}; // we do not need microseconds - Timestamp(tv).to_datetime(thd).to_string(&str, 0); + Timestamp(thd->query_start(), 0).to_datetime(thd).to_string(&str, 0); writer.add_member("target_histogram_size").add_ull(hist_width); writer.add_member("collected_at").add_str(str.ptr()); writer.add_member("collected_by").add_str(server_version); diff --git a/sql/partition_info.cc b/sql/partition_info.cc index 577239c6c6c..422ca66d5a7 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -825,7 +825,7 @@ bool partition_info::vers_set_hist_part(THD *thd, uint *create_count) return 0; } else if (vers_info->interval.is_set() && - vers_info->hist_part->range_value <= thd->query_start()) + vers_info->hist_part->range_value <= (longlong) thd->query_start()) { partition_element *next= NULL; bool error= true; @@ -836,7 +836,7 @@ bool partition_info::vers_set_hist_part(THD *thd, uint *create_count) while ((next= it++) != vers_info->now_part) { vers_info->hist_part= next; - if (next->range_value > thd->query_start()) + if (next->range_value > (longlong) thd->query_start()) { error= false; break; @@ -2835,7 +2835,7 @@ bool partition_info::vers_set_interval(THD* thd, Item* interval, case DECIMAL_RESULT: case REAL_RESULT: /* When table member is defined, we are inside mysql_unpack_partition(). */ - if (!table || starts->val_int() > TIMESTAMP_MAX_VALUE) + if (!table || (ulonglong) starts->val_int() > TIMESTAMP_MAX_VALUE) goto interval_starts_error; vers_info->interval.start= (my_time_t) starts->val_int(); break; diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc index bbfc02110a7..2cbb112638e 100644 --- a/sql/rpl_parallel.cc +++ b/sql/rpl_parallel.cc @@ -60,7 +60,7 @@ rpt_handle_event(rpl_parallel_thread::queued_event *qev, rgi->future_event_relay_log_pos= qev->future_event_relay_log_pos; strcpy(rgi->future_event_master_log_name, qev->future_event_master_log_name); if (event_can_update_last_master_timestamp(ev)) - rgi->last_master_timestamp= ev->when + (time_t)ev->exec_time; + rgi->last_master_timestamp= ev->when + ev->exec_time; err= apply_event_and_update_pos_for_parallel(ev, thd, rgi); rli->executed_entries++; diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index c3be5df4c11..d20b0eb2ab4 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -251,7 +251,7 @@ public: */ bool sql_force_rotate_relay; - time_t last_master_timestamp; + my_time_t last_master_timestamp; /* The SQL driver thread sets this true while it is waiting at the end of the relay log for more events to arrive. SHOW SLAVE STATUS uses this to report @@ -838,7 +838,7 @@ struct rpl_group_info Used to do delayed update of rli->last_master_timestamp, for getting reasonable values out of Seconds_Behind_Master in SHOW SLAVE STATUS. */ - time_t last_master_timestamp; + my_time_t last_master_timestamp; /* Information to be able to re-try an event group in case of a deadlock or diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 797d0ec49b9..d97ce7f079c 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -11874,10 +11874,8 @@ ER_VERS_ENGINE_UNSUPPORTED spa "No se soporta versionado de sistema de transacción precisa para %`s" sw "Toleo la mfumo wa muamala kamili kwa %`s halitumiki" -ER_UNUSED_23 - eng "You should never see it" - spa "Nunca debería vd de ver esto" - sw "Hupaswi kuiona kamwe" +ER_WRONG_VERSIONING_RANGE + eng "Incorrect system-version range '%-.32s' value: '%-.128T' and '%-.32s' value: '%-.128T'" ER_PARTITION_WRONG_TYPE chi "错误分区类型%`s,应当是%`s" diff --git a/sql/slave.cc b/sql/slave.cc index 4ac0b57422e..7081096b513 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -4354,9 +4354,8 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli, if ((!rli->mi->using_parallel()) && event_can_update_last_master_timestamp(ev)) { - rli->last_master_timestamp= ev->when + (time_t) ev->exec_time; + rli->last_master_timestamp= ev->when + ev->exec_time; rli->sql_thread_caught_up= false; - DBUG_ASSERT(rli->last_master_timestamp >= 0); } /* @@ -4468,9 +4467,7 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli, */ if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT && rli->last_master_timestamp < ev->when + (time_t) ev->exec_time) - rli->last_master_timestamp= ev->when + (time_t) ev->exec_time; - - DBUG_ASSERT(rli->last_master_timestamp >= 0); + rli->last_master_timestamp= ev->when + ev->exec_time; } } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index a9786757fa0..a4d02ad037d 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -14614,7 +14614,8 @@ static bool check_password_lifetime(THD *thd, const ACL_USER &acl_user) thd->set_time(); - if ((thd->query_start() - acl_user.password_last_changed)/3600/24 >= interval) + if ((((longlong) thd->query_start() - (longlong) acl_user.password_last_changed))/3600/24 >= + interval) return true; return false; diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index 93b0dbb3ac7..3b9de6b1486 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -952,9 +952,10 @@ void field_longlong::get_opt_type(String *answer, else if (min_arg >= INT_MIN24 && max_arg <= (min_arg >= 0 ? UINT_MAX24 : INT_MAX24)) snprintf(buff, sizeof(buff), "MEDIUMINT(%d)", (int) max_length); - else if (min_arg >= INT_MIN32 && max_arg <= (min_arg >= 0 ? - (longlong) UINT_MAX32 : - (longlong) INT_MAX32)) + else if (min_arg >= INT_MIN32 && + (ulonglong) max_arg <= (min_arg >= 0 ? + (ulonglong) UINT_MAX32 : + (ulonglong) INT_MAX32)) snprintf(buff, sizeof(buff), "INT(%d)", (int) max_length); else snprintf(buff, sizeof(buff), "BIGINT(%d)", (int) max_length); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 5a21e8ecd33..f5a348a739e 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -8968,9 +8968,12 @@ static bool vers_update_or_validate_fields(TABLE *table) TIME_NO_ZERO_DATE, time_round_mode_t(time_round_mode_t::FRAC_NONE)))) return 0; - StringBuffer val; - row_start->val_str(&val); - my_error(ER_WRONG_VALUE, MYF(0), row_start->field_name.str, val.c_ptr()); + StringBuffer val_start, val_end; + row_start->val_str(&val_start); + row_end->val_str(&val_end); + my_error(ER_WRONG_VERSIONING_RANGE, MYF(0), + row_start->field_name.str, val_start.c_ptr(), + row_end->field_name.str, val_end.c_ptr()); return 1; } diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 15f7e6bb62f..3dfd48581aa 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -1571,7 +1571,7 @@ static bool check_vers_constants(THD *thd, partition_info *part_info) my_tz_OFFSET0->TIME_to_gmt_sec(<ime, &error); if (error) goto err; - if (vers_info->hist_part->range_value <= thd->query_start()) + if (vers_info->hist_part->range_value <= (longlong) thd->query_start()) vers_info->hist_part= el; } DBUG_ASSERT(el == vers_info->now_part); @@ -3501,14 +3501,14 @@ int vers_get_partition_id(partition_info *part_info, uint32 *part_id, goto done; // fastpath ts= row_end->get_timestamp(&unused); - if ((loc_hist_id == 0 || range_value[loc_hist_id - 1] < ts) && - (loc_hist_id == max_hist_id || range_value[loc_hist_id] >= ts)) + if ((loc_hist_id == 0 || range_value[loc_hist_id - 1] < (longlong) ts) && + (loc_hist_id == max_hist_id || range_value[loc_hist_id] >= (longlong) ts)) goto done; // fastpath while (max_hist_id > min_hist_id) { loc_hist_id= (max_hist_id + min_hist_id) / 2; - if (range_value[loc_hist_id] <= ts) + if (range_value[loc_hist_id] <= (longlong) ts) min_hist_id= loc_hist_id + 1; else max_hist_id= loc_hist_id; @@ -5416,7 +5416,7 @@ that are reorganised. tab_part_info->vers_info->interval.is_set()) { partition_element *hist_part= tab_part_info->vers_info->hist_part; - if (hist_part->range_value <= thd->query_start()) + if (hist_part->range_value <= (longlong) thd->query_start()) hist_part->part_state= PART_CHANGED; } } diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 183a6358123..8914afcf077 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -782,7 +782,7 @@ void Timestamp::round_or_set_max(uint dec, int *warn) { DBUG_ASSERT(dec <= TIME_SECOND_PART_DIGITS); if (add_nanoseconds_usec(msec_round_add[dec]) && - tv_sec++ >= TIMESTAMP_MAX_VALUE) + (ulonglong) tv_sec++ >= TIMESTAMP_MAX_VALUE) { tv_sec= TIMESTAMP_MAX_VALUE; tv_usec= TIME_MAX_SECOND_PART; diff --git a/sql/table.cc b/sql/table.cc index f5d9829b732..fb11a81bc4e 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -10416,7 +10416,7 @@ bool TR_table::update(ulonglong start_id, ulonglong end_id) store(FLD_BEGIN_TS, thd->transaction_time()); thd->set_time(); - timeval end_time= {thd->query_start(), int(thd->query_start_sec_part())}; + timeval end_time= { (time_t) thd->query_start(), int(thd->query_start_sec_part())}; store(FLD_TRX_ID, start_id); store(FLD_COMMIT_ID, end_id); store(FLD_COMMIT_TS, end_time); diff --git a/sql/tztime.cc b/sql/tztime.cc index 8b1a3f31111..6ad2fac9552 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -202,7 +202,7 @@ tz_load(const char *name, TIME_ZONE_INFO *sp, MEM_ROOT *storage) if (!(tzinfo_buf= (char *)alloc_root(storage, ALIGN_SIZE(sp->timecnt * - sizeof(my_time_t)) + + sizeof(*sp->ats)) + ALIGN_SIZE(sp->timecnt) + ALIGN_SIZE(sp->typecnt * sizeof(TRAN_TYPE_INFO)) + @@ -473,9 +473,10 @@ prepare_tz_info(TIME_ZONE_INFO *sp, MEM_ROOT *storage) /* Allocate arrays of proper size in sp and copy result there */ if (!(sp->revts= (my_time_t *)alloc_root(storage, - sizeof(my_time_t) * (sp->revcnt + 1))) || + sizeof(*sp->revts) * + (sp->revcnt + 1))) || !(sp->revtis= (REVT_INFO *)alloc_root(storage, - sizeof(REVT_INFO) * sp->revcnt))) + sizeof(REVT_INFO) * sp->revcnt))) return 1; memcpy(sp->revts, revts, sizeof(my_time_t) * (sp->revcnt + 1)); @@ -764,18 +765,16 @@ gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t sec_in_utc, const TIME_ZONE_INFO *sp) RETURN VALUE Seconds since epoch time representation. */ -static my_time_t +static longlong sec_since_epoch(int year, int mon, int mday, int hour, int min ,int sec) { - /* Guard against my_time_t overflow(on system with 32 bit my_time_t) */ - DBUG_ASSERT(!(year == TIMESTAMP_MAX_YEAR && mon == 1 && mday > 17)); #ifndef WE_WANT_TO_HANDLE_UNORMALIZED_DATES /* It turns out that only whenever month is normalized or unnormalized plays role. */ DBUG_ASSERT(mon > 0 && mon < 13); - long days= year * DAYS_PER_NYEAR - EPOCH_YEAR * DAYS_PER_NYEAR + + longlong days= year * DAYS_PER_NYEAR - EPOCH_YEAR * DAYS_PER_NYEAR + LEAPS_THRU_END_OF(year - 1) - LEAPS_THRU_END_OF(EPOCH_YEAR - 1); days+= mon_starts[isleap(year)][mon - 1]; @@ -790,8 +789,8 @@ sec_since_epoch(int year, int mon, int mday, int hour, int min ,int sec) #endif days+= mday - 1; - return ((days * HOURS_PER_DAY + hour) * MINS_PER_HOUR + min) * - SECS_PER_MIN + sec; + return ((longlong((days * HOURS_PER_DAY + hour) * MINS_PER_HOUR + min)) * + SECS_PER_MIN + sec); } /* @@ -869,10 +868,14 @@ sec_since_epoch(int year, int mon, int mday, int hour, int min ,int sec) 0 in case of error. */ +#if TIMESTAMP_MAX_DAY <= 2 +#error TIMESTAMP_MAX_DAY has to be > 2 for TIME_to_gmt_sec to work +#endif + static my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t, const TIME_ZONE_INFO *sp, uint *error_code) { - my_time_t local_t; + longlong local_t; uint saved_seconds; uint i; int shift= 0; @@ -894,7 +897,7 @@ TIME_to_gmt_sec(const MYSQL_TIME *t, const TIME_ZONE_INFO *sp, uint *error_code) /* NOTE: to convert full my_time_t range we do a shift of the - boundary dates here to avoid overflow of my_time_t. + boundary dates here to avoid overflow of my_time_t range. We use alike approach in my_system_gmt_sec(). However in that function we also have to take into account @@ -902,19 +905,19 @@ TIME_to_gmt_sec(const MYSQL_TIME *t, const TIME_ZONE_INFO *sp, uint *error_code) uses localtime_r(), which doesn't work with negative values correctly on platforms with unsigned time_t (QNX). Here we don't use localtime() => we negative values of local_t are ok. - */ +a */ - if ((t->year == TIMESTAMP_MAX_YEAR) && (t->month == 1) && t->day > 4) + if (t->year == TIMESTAMP_MAX_YEAR && t->month == TIMESTAMP_MAX_MONTH && + t->day > 2) { /* We will pass (t->day - shift) to sec_since_epoch(), and want this value to be a positive number, so we shift - only dates > 4.01.2038 (to avoid owerflow). + only dates > max_day (to avoid owerflow). */ shift= 2; } - local_t= sec_since_epoch(t->year, t->month, (t->day - shift), t->hour, t->minute, saved_seconds ? 0 : t->second); @@ -942,8 +945,8 @@ TIME_to_gmt_sec(const MYSQL_TIME *t, const TIME_ZONE_INFO *sp, uint *error_code) */ if (shift) { - if (local_t > (my_time_t) (TIMESTAMP_MAX_VALUE - shift * SECS_PER_DAY + - sp->revtis[i].rt_offset - saved_seconds)) + if (local_t > (longlong) (TIMESTAMP_MAX_VALUE - shift * SECS_PER_DAY + + sp->revtis[i].rt_offset - saved_seconds)) { *error_code= ER_WARN_DATA_OUT_OF_RANGE; DBUG_RETURN(0); /* my_time_t overflow */ @@ -965,14 +968,13 @@ TIME_to_gmt_sec(const MYSQL_TIME *t, const TIME_ZONE_INFO *sp, uint *error_code) else local_t= local_t - sp->revtis[i].rt_offset + saved_seconds; - /* check for TIMESTAMP_MAX_VALUE was already done above */ - if (local_t < TIMESTAMP_MIN_VALUE) + if (local_t < TIMESTAMP_MIN_VALUE || local_t > TIMESTAMP_MAX_VALUE) { local_t= 0; *error_code= ER_WARN_DATA_OUT_OF_RANGE; } - DBUG_RETURN(local_t); + DBUG_RETURN((my_time_t) local_t); } diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc index 2e227c0c4fe..ec5bbcfc530 100644 --- a/storage/innobase/dict/dict0mem.cc +++ b/storage/innobase/dict/dict0mem.cc @@ -1295,7 +1295,7 @@ dict_index_t::vers_history_row( return 0 != memcmp(data, trx_id_max_bytes, len); } ut_ad(len == sizeof timestamp_max_bytes); - return 0 != memcmp(data, timestamp_max_bytes, len); + return !IS_MAX_TIMESTAMP(data); } /** Check if record in secondary index is historical row. diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 2a68edf60e4..f6efc6a89fe 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -411,7 +411,7 @@ fts_read_stopword( } } else { ut_ad(len == sizeof timestamp_max_bytes); - if (0 != memcmp(data, timestamp_max_bytes, len)) { + if (!IS_MAX_TIMESTAMP(data)) { return true; } } @@ -3677,8 +3677,7 @@ fts_get_max_doc_id( break; } } else { - if (0 == memcmp(data, timestamp_max_bytes, - sizeof timestamp_max_bytes)) { + if (IS_MAX_TIMESTAMP(data)) { break; } } @@ -6008,7 +6007,7 @@ fts_init_get_doc_id( } } else { ut_ad(len == sizeof timestamp_max_bytes); - if (0 != memcmp(data, timestamp_max_bytes, len)) { + if (!IS_MAX_TIMESTAMP(data)) { return true; } } diff --git a/storage/innobase/include/data0data.h b/storage/innobase/include/data0data.h index fcb543ebb1a..5a3d53024b5 100644 --- a/storage/innobase/include/data0data.h +++ b/storage/innobase/include/data0data.h @@ -486,7 +486,7 @@ struct dfield_t{ ut_ad(type.vers_sys_end()); if (type.mtype == DATA_FIXBINARY) { ut_ad(len == sizeof timestamp_max_bytes); - return 0 != memcmp(data, timestamp_max_bytes, len); + return !IS_MAX_TIMESTAMP(data); } else { ut_ad(type.mtype == DATA_INT); ut_ad(len == sizeof trx_id_max_bytes); diff --git a/storage/innobase/include/dict0types.h b/storage/innobase/include/dict0types.h index f6169227433..b5239c90c8d 100644 --- a/storage/innobase/include/dict0types.h +++ b/storage/innobase/include/dict0types.h @@ -58,6 +58,11 @@ typedef ib_id_t index_id_t; extern const byte trx_id_max_bytes[8]; extern const byte timestamp_max_bytes[7]; +#define IS_MAX_TIMESTAMP(A) \ + (((unsigned char*) (A))[1] == 0xff && \ + memcmp((void*) (A), timestamp_max_bytes, 7) == 0) + + /** Error to ignore when we load table dictionary into memory. However, the table and index will be marked as "corrupted", and caller will be responsible to deal with corrupted table or index. diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index ff9d8c55119..85f4210a460 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -57,11 +57,17 @@ const byte trx_id_max_bytes[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -/** The bit pattern corresponding to max timestamp */ +#if SIZEOF_VOIDP == 4 +/* Max timestamp before 11.3 */ const byte timestamp_max_bytes[7] = { 0x7f, 0xff, 0xff, 0xff, 0x0f, 0x42, 0x3f }; - +#else +/** The bit pattern corresponding to max timestamp */ +const byte timestamp_max_bytes[7] = { + 0xff, 0xff, 0xff, 0xff, 0x0f, 0x42, 0x3f +}; +#endif /* SIZEOF_VOIDP */ static const ulint MAX_DETAILED_ERROR_LEN = 256;