diff options
author | Alexander Barkov <bar@mariadb.com> | 2023-02-13 15:14:40 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2023-02-13 17:25:18 +0400 |
commit | 8c1ad2a9fe940376d7cb79515685138e3591e5b7 (patch) | |
tree | da9f284500726e03c00a3d96ce2462ddcc057462 | |
parent | ce4a289f1c367987977f1a02bbb8d8b8e8e6bb53 (diff) | |
download | mariadb-git-bb-11.0-bar-MDEV-30633.tar.gz |
MDEV-30633 DATETIME to TIMESTAMP conversion to return maximum timestamp on overflowbb-11.0-bar-MDEV-30633
-rw-r--r-- | include/my_time.h | 79 | ||||
-rw-r--r-- | mysql-test/main/events_bugs.result | 28 | ||||
-rw-r--r-- | mysql-test/main/events_bugs.test | 19 | ||||
-rw-r--r-- | mysql-test/main/func_time.result | 16 | ||||
-rw-r--r-- | mysql-test/main/partition_datatype.result | 227 | ||||
-rw-r--r-- | mysql-test/main/partition_datatype.test | 21 | ||||
-rw-r--r-- | mysql-test/main/select.result | 4 | ||||
-rw-r--r-- | mysql-test/main/select_jcl6.result | 4 | ||||
-rw-r--r-- | mysql-test/main/select_pkeycache.result | 4 | ||||
-rw-r--r-- | mysql-test/main/timezone2.result | 12 | ||||
-rw-r--r-- | sql-common/my_time.c | 11 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 14 | ||||
-rw-r--r-- | sql/sql_time.cc | 9 | ||||
-rw-r--r-- | sql/sql_type.cc | 2 | ||||
-rw-r--r-- | sql/tztime.cc | 23 |
15 files changed, 303 insertions, 170 deletions
diff --git a/include/my_time.h b/include/my_time.h index 9f3e61b944f..5d0d734f505 100644 --- a/include/my_time.h +++ b/include/my_time.h @@ -25,6 +25,13 @@ #include "mysql_time.h" #include "my_decimal_limits.h" +/* Can't include mysqld_error.h, it needs mysys to build, thus hardcode 2 error values here. */ +#ifndef ER_WARN_DATA_OUT_OF_RANGE +#define ER_WARN_DATA_OUT_OF_RANGE 1264 +#define ER_WARN_INVALID_TIMESTAMP 1299 +#endif + + C_MODE_START extern MYSQL_PLUGIN_IMPORT ulonglong log_10_int[20]; @@ -166,33 +173,67 @@ void my_init_time(void); /* - Function to check sanity of a TIMESTAMP value + Check if the given MYSQL_TIME value is not below the minimum possible + TIMESTAMP value. + This function doesn't make precise check, but rather a rough estimate. + + @return FALSE - The value can be sane (further validation is needed). + @return TRUE - The MYSQL_TIME value is definitely out of range +*/ + +static inline my_bool MYSQL_TIME_below_min_timestamp(const MYSQL_TIME *t) +{ + return t->year < TIMESTAMP_MIN_YEAR || + (t->year == TIMESTAMP_MIN_YEAR && (t->month < 12 || t->day < 31)); +} + - DESCRIPTION - Check if a given MYSQL_TIME value fits in TIMESTAMP range. - This function doesn't make precise check, but rather a rough - estimate. +/* + Check if the given MYSQL_TIME value is not above the maximun possible + TIMESTAMP value. + This function doesn't make precise check, but rather a rough estimate. - RETURN VALUES - TRUE The value seems sane - FALSE The MYSQL_TIME value is definitely out of range + @return FALSE - The value can be sane (further validation is needed). + @return TRUE - The MYSQL_TIME value is definitely out of the range. */ -static inline my_bool validate_timestamp_range(const MYSQL_TIME *t) +static inline my_bool MYSQL_TIME_above_max_timestamp(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; + return t->year > TIMESTAMP_MAX_YEAR || + (t->year == TIMESTAMP_MAX_YEAR && (t->month > 1 || t->day > 19)); +} - return TRUE; + +/* + Check if the given MYSQL_TIME value is inside a valid TIMESTAMP range. + This function doesn't make precise check, but rather a rough estimate. + + @param t - The MYSQL_TIME to check. + @param [OUT] minmax - The saturated timestamp value, + if "t" is definitely outside of the TIMESTAMP range. + + @returns 0 - The value can be sane + (validation is still needed). + @returns ER_WARN_DATA_OUT_OF_RANGE - The MYSQL_TIME value is definitely + out of the TIMESTAMP range +*/ +static inline uint +MYSQL_TIME_check_rough_timestamp_range(const MYSQL_TIME *t, my_time_t *minmax) +{ + if (MYSQL_TIME_below_min_timestamp(t)) + { + *minmax= 0; + return ER_WARN_DATA_OUT_OF_RANGE; + } + if (MYSQL_TIME_above_max_timestamp(t)) + { + *minmax= TIMESTAMP_MAX_VALUE; + return ER_WARN_DATA_OUT_OF_RANGE; + } + *minmax= 0; /* Safety */ + return 0; } -/* Can't include mysqld_error.h, it needs mysys to build, thus hardcode 2 error values here. */ -#ifndef ER_WARN_DATA_OUT_OF_RANGE -#define ER_WARN_DATA_OUT_OF_RANGE 1264 -#define ER_WARN_INVALID_TIMESTAMP 1299 -#endif my_time_t my_system_gmt_sec(const MYSQL_TIME *t, long *my_timezone, uint *error_code); diff --git a/mysql-test/main/events_bugs.result b/mysql-test/main/events_bugs.result index 0615dac53b1..13793503b80 100644 --- a/mysql-test/main/events_bugs.result +++ b/mysql-test/main/events_bugs.result @@ -35,12 +35,34 @@ SET NAMES latin1; set @a=3; CREATE PROCEDURE p_16 () CREATE EVENT e_16 ON SCHEDULE EVERY @a SECOND DO SET @a=5; ERROR HY000: Recursion of EVENT DDL statements is forbidden when body is present +SET time_zone='+00:00'; +SET timestamp=UNIX_TIMESTAMP('2023-02-13 00:00:00'); create event e_55 on schedule at 99990101000000 do drop table t; -ERROR HY000: Incorrect AT value: '99990101000000' +Warnings: +Warning 1292 Truncated incorrect timestamp value: '9999-01-01 00:00:00' +Warning 1105 Event scheduler is switched off, use SET GLOBAL event_scheduler=ON to enable it. +show create event e_55; +Event sql_mode time_zone Create Event character_set_client collation_connection Database Collation +e_55 +00:00 CREATE DEFINER=`root`@`localhost` EVENT `e_55` ON SCHEDULE AT '2038-01-19 03:14:07' ON COMPLETION NOT PRESERVE ENABLE DO drop table t latin1 latin1_swedish_ci latin1_swedish_ci +drop event e_55; create event e_55 on schedule every 10 hour starts 99990101000000 do drop table t; -ERROR HY000: Incorrect STARTS value: '99990101000000' +Warnings: +Warning 1292 Truncated incorrect timestamp value: '9999-01-01 00:00:00' +Warning 1105 Event scheduler is switched off, use SET GLOBAL event_scheduler=ON to enable it. +show create event e_55; +Event sql_mode time_zone Create Event character_set_client collation_connection Database Collation +e_55 +00:00 CREATE DEFINER=`root`@`localhost` EVENT `e_55` ON SCHEDULE EVERY 10 HOUR STARTS '2038-01-19 03:14:07' ON COMPLETION NOT PRESERVE ENABLE DO drop table t latin1 latin1_swedish_ci latin1_swedish_ci +drop event e_55; create event e_55 on schedule every 10 minute ends 99990101000000 do drop table t; -ERROR HY000: ENDS is either invalid or before STARTS +Warnings: +Warning 1292 Truncated incorrect timestamp value: '9999-01-01 00:00:00' +Warning 1105 Event scheduler is switched off, use SET GLOBAL event_scheduler=ON to enable it. +show create event e_55; +Event sql_mode time_zone Create Event character_set_client collation_connection Database Collation +e_55 +00:00 CREATE DEFINER=`root`@`localhost` EVENT `e_55` ON SCHEDULE EVERY 10 MINUTE STARTS '2023-02-13 00:00:00' ENDS '2038-01-19 03:14:07' ON COMPLETION NOT PRESERVE ENABLE DO drop table t latin1 latin1_swedish_ci latin1_swedish_ci +drop event e_55; +SET time_zone=DEFAULT; +SET timestamp=DEFAULT; create event e_55 on schedule at 10000101000000 do drop table t; ERROR HY000: Incorrect AT value: '10000101000000' create event e_55 on schedule at 20000101000000 do drop table t; diff --git a/mysql-test/main/events_bugs.test b/mysql-test/main/events_bugs.test index fe744de86c9..6d2a98ca0a2 100644 --- a/mysql-test/main/events_bugs.test +++ b/mysql-test/main/events_bugs.test @@ -204,12 +204,25 @@ CREATE PROCEDURE p_16 () CREATE EVENT e_16 ON SCHEDULE EVERY @a SECOND DO SET @a # # Start - 16396: Events: Distant-future dates become past dates # ---error ER_WRONG_VALUE + +SET time_zone='+00:00'; +SET timestamp=UNIX_TIMESTAMP('2023-02-13 00:00:00'); + create event e_55 on schedule at 99990101000000 do drop table t; ---error ER_WRONG_VALUE +show create event e_55; +drop event e_55; + create event e_55 on schedule every 10 hour starts 99990101000000 do drop table t; ---error ER_EVENT_ENDS_BEFORE_STARTS +show create event e_55; +drop event e_55; + create event e_55 on schedule every 10 minute ends 99990101000000 do drop table t; +show create event e_55; +drop event e_55; + +SET time_zone=DEFAULT; +SET timestamp=DEFAULT; + --error ER_WRONG_VALUE create event e_55 on schedule at 10000101000000 do drop table t; diff --git a/mysql-test/main/func_time.result b/mysql-test/main/func_time.result index 7188c5de205..e10d4e0e02b 100644 --- a/mysql-test/main/func_time.result +++ b/mysql-test/main/func_time.result @@ -599,19 +599,25 @@ 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 +2147483647 +Warnings: +Warning 1292 Truncated incorrect timestamp value: '2039-01-20 01:00:00' 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 +2147483647 +Warnings: +Warning 1292 Truncated incorrect timestamp value: '2038-02-10 01:00:00' 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 +2147483647 +Warnings: +Warning 1292 Truncated incorrect timestamp value: '2038-01-20 01:00:00' select unix_timestamp('1969-12-30 01:00:00'); unix_timestamp('1969-12-30 01:00:00') NULL @@ -623,7 +629,9 @@ 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 +2147483647 +Warnings: +Warning 1292 Truncated incorrect timestamp value: '2038-01-19 07:14:07' SELECT CHARSET(DAYNAME(19700101)); CHARSET(DAYNAME(19700101)) latin1 diff --git a/mysql-test/main/partition_datatype.result b/mysql-test/main/partition_datatype.result index fb2635ceda9..5d74629ef62 100644 --- a/mysql-test/main/partition_datatype.result +++ b/mysql-test/main/partition_datatype.result @@ -350,7 +350,7 @@ 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)) +tz varchar(32)) ENGINE = MyISAM; CREATE TABLE t2 LIKE t1; ALTER TABLE t2 PARTITION BY RANGE (UNIX_TIMESTAMP(a)) @@ -373,9 +373,9 @@ 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 ('2038-01-19 03:14:08', 'UTCI/Max+1'); Warnings: -Warning 1264 Out of range value for column 'a' at row 1 +Warning 1292 Truncated incorrect timestamp value: '2038-01-19 03:14:08' INSERT IGNORE INTO t1 VALUES ('1970-01-01 00:00:00', 'UTCI'); Warnings: Warning 1264 Out of range value for column 'a' at row 1 @@ -383,8 +383,8 @@ Warning 1264 Out of range value for column 'a' at row 1 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'); +INSERT INTO t1 VALUES ('2038-01-19 03:14:06', 'UTC/Max-1'); +INSERT INTO t1 VALUES ('2038-01-19 03:14:07', 'UTC/Max'); # 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,9 +415,9 @@ 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 ('2038-01-19 06:14:08', 'MoscowI/Max+1'); Warnings: -Warning 1264 Out of range value for column 'a' at row 1 +Warning 1292 Truncated incorrect timestamp value: '2038-01-19 06:14:08' INSERT IGNORE INTO t1 VALUES ('1970-01-01 03:00:00', 'MoscowI'); Warnings: Warning 1264 Out of range value for column 'a' at row 1 @@ -435,8 +435,8 @@ Warning 1299 Invalid TIMESTAMP value in column 'a' at row 1 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'); +INSERT INTO t1 VALUES ('2038-01-19 06:14:06', 'Moscow/Max-1'); +INSERT INTO t1 VALUES ('2038-01-19 06:14:07', 'Moscow/Max'); # 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'); @@ -454,14 +454,14 @@ SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 't2'; PARTITION_NAME TABLE_ROWS p0 2 -p-2000 16 +p-2000 14 p-2011-MSK 2 p-2011-MSD-1 9 p-2011-MSD-2 6 p-2012-MSK-1 3 p-2012-MSK-2 4 pEnd 2 -pMax 2 +pMax 4 SELECT * FROM t1 ORDER BY a, tz; a tz NULL Moscow @@ -472,12 +472,10 @@ NULL UTC 0000-00-00 00:00:00 MoscowI 0000-00-00 00:00:00 MoscowI 0000-00-00 00:00:00 MoscowI -0000-00-00 00:00:00 MoscowI 0000-00-00 00:00:00 UTC 0000-00-00 00:00:00 UTCI 0000-00-00 00:00:00 UTCI 0000-00-00 00:00:00 UTCI -0000-00-00 00:00:00 UTCI 1970-01-01 00:00:01 Moscow 1970-01-01 00:00:01 UTC 1974-02-05 18:28:16 Moscow @@ -506,10 +504,12 @@ NULL UTC 2011-10-30 00:00:00 UTC 2011-10-30 00:00:01 Moscow 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 +2038-01-19 03:14:06 Moscow/Max-1 +2038-01-19 03:14:06 UTC/Max-1 +2038-01-19 03:14:07 Moscow/Max +2038-01-19 03:14:07 MoscowI/Max+1 +2038-01-19 03:14:07 UTC/Max +2038-01-19 03:14:07 UTCI/Max+1 SELECT * FROM t2 ORDER BY a, tz; a tz NULL Moscow @@ -520,12 +520,10 @@ NULL UTC 0000-00-00 00:00:00 MoscowI 0000-00-00 00:00:00 MoscowI 0000-00-00 00:00:00 MoscowI -0000-00-00 00:00:00 MoscowI 0000-00-00 00:00:00 UTC 0000-00-00 00:00:00 UTCI 0000-00-00 00:00:00 UTCI 0000-00-00 00:00:00 UTCI -0000-00-00 00:00:00 UTCI 1970-01-01 00:00:01 Moscow 1970-01-01 00:00:01 UTC 1974-02-05 18:28:16 Moscow @@ -554,10 +552,12 @@ NULL UTC 2011-10-30 00:00:00 UTC 2011-10-30 00:00:01 Moscow 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 +2038-01-19 03:14:06 Moscow/Max-1 +2038-01-19 03:14:06 UTC/Max-1 +2038-01-19 03:14:07 Moscow/Max +2038-01-19 03:14:07 MoscowI/Max+1 +2038-01-19 03:14:07 UTC/Max +2038-01-19 03:14:07 UTCI/Max+1 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,10 +687,13 @@ Warnings: Warning 1264 Out of range value for column 'a' at row 1 SELECT COUNT(*) FROM t2; COUNT(*) -35 +37 SELECT COUNT(*) FROM t2 WHERE a = 0; COUNT(*) 1 +SELECT COUNT(*) FROM t2 WHERE UNIX_TIMESTAMP(a)=0x7FFFFFFF; +COUNT(*) +4 SELECT * FROM t2 ORDER BY a, tz LIMIT 3; a tz NULL Moscow @@ -698,42 +701,42 @@ 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:07 Moscow/Max +2038-01-19 03:14:07 MoscowI/Max+1 +2038-01-19 03:14:07 UTC/Max 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 +Warning 1292 Truncated incorrect timestamp value: '2038-01-19 03:14:08' +Warning 1292 Truncated incorrect timestamp value: '2038-01-19 03:14:08' +Warning 1292 Truncated incorrect timestamp value: '2038-01-19 03:14:08' +Warning 1292 Truncated incorrect timestamp value: '2038-01-19 03:14:08' 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 +37 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 p-2012-MSK-1 4 p-2012-MSK-2 5 pEnd 0 -pMax 2 +pMax 6 SELECT * FROM t2 ORDER BY a, tz; 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 @@ -762,18 +765,25 @@ NULL UTC 2011-10-30 00:00:01 UTC 2011-10-30 00:00:02 Moscow 2011-10-30 00:00:02 UTC -2038-01-19 03:14:07 Moscow -2038-01-19 03:14:07 UTC +2038-01-19 03:14:07 Moscow/Max +2038-01-19 03:14:07 Moscow/Max-1 +2038-01-19 03:14:07 MoscowI/Max+1 +2038-01-19 03:14:07 UTC/Max +2038-01-19 03:14:07 UTC/Max-1 +2038-01-19 03:14:07 UTCI/Max+1 # Test start range changes INSERT IGNORE INTO t2 VALUES ('1970-01-01 00:00:00', 'UTC'); Warnings: Warning 1264 Out of range value for column 'a' at row 1 SELECT COUNT(*) FROM t2; COUNT(*) -36 +38 SELECT COUNT(*) FROM t2 WHERE a = 0; COUNT(*) -3 +1 +SELECT COUNT(*) FROM t2 WHERE UNIX_TIMESTAMP(a)=0x7FFFFFFF; +COUNT(*) +6 SELECT * FROM t2 ORDER BY a, tz LIMIT 3; a tz NULL Moscow @@ -781,40 +791,39 @@ NULL UTC NULL 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 -2011-10-30 00:00:02 Moscow +2038-01-19 03:14:07 Moscow/Max +2038-01-19 03:14:07 Moscow/Max-1 +2038-01-19 03:14:07 MoscowI/Max+1 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 +38 SELECT COUNT(*) FROM t2 WHERE a = 0; COUNT(*) 0 +SELECT COUNT(*) FROM t2 WHERE UNIX_TIMESTAMP(a)=0x7FFFFFFF; +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 p-2011-MSD-2 6 p-2012-MSK-1 3 p-2012-MSK-2 4 -pEnd 2 +pEnd 6 pMax 0 SELECT * FROM t2 ORDER BY a, tz; a tz NULL Moscow -NULL Moscow -NULL UTC NULL UTC NULL UTC NULL UTC @@ -846,13 +855,17 @@ NULL UTC 2011-10-30 00:00:00 UTC 2011-10-30 00:00:01 Moscow 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:06 Moscow/Max +2038-01-19 03:14:06 Moscow/Max-1 +2038-01-19 03:14:06 MoscowI/Max+1 +2038-01-19 03:14:06 UTC/Max +2038-01-19 03:14:06 UTC/Max-1 +2038-01-19 03:14:06 UTCI/Max+1 SHOW CREATE TABLE t2; Table Create Table t2 CREATE TABLE `t2` ( `a` timestamp NULL DEFAULT NULL, - `tz` varchar(16) DEFAULT NULL + `tz` varchar(32) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PARTITION BY RANGE (unix_timestamp(`a`)) (PARTITION `p0` VALUES LESS THAN (0) ENGINE = MyISAM, @@ -871,14 +884,14 @@ SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 't2'; PARTITION_NAME TABLE_ROWS p0 2 -p-2000 16 +p-2000 14 p-2011-MSK 2 p-2011-MSD-1 9 p-2011-MSD-2 6 p-2012-MSK-1 3 p-2012-MSK-2 4 pEnd 2 -pMax 2 +pMax 4 SELECT * FROM t1 ORDER BY a, tz; a tz NULL Moscow @@ -889,12 +902,10 @@ NULL UTC 0000-00-00 00:00:00 MoscowI 0000-00-00 00:00:00 MoscowI 0000-00-00 00:00:00 MoscowI -0000-00-00 00:00:00 MoscowI 0000-00-00 00:00:00 UTC 0000-00-00 00:00:00 UTCI 0000-00-00 00:00:00 UTCI 0000-00-00 00:00:00 UTCI -0000-00-00 00:00:00 UTCI 1970-01-01 03:00:01 Moscow 1970-01-01 03:00:01 UTC 1974-02-05 21:28:16 Moscow @@ -923,10 +934,12 @@ NULL UTC 2011-10-30 03:00:00 UTC 2011-10-30 03:00:01 Moscow 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 +2038-01-19 06:14:06 Moscow/Max-1 +2038-01-19 06:14:06 UTC/Max-1 +2038-01-19 06:14:07 Moscow/Max +2038-01-19 06:14:07 MoscowI/Max+1 +2038-01-19 06:14:07 UTC/Max +2038-01-19 06:14:07 UTCI/Max+1 SELECT * FROM t2 ORDER BY a, tz; a tz NULL Moscow @@ -937,12 +950,10 @@ NULL UTC 0000-00-00 00:00:00 MoscowI 0000-00-00 00:00:00 MoscowI 0000-00-00 00:00:00 MoscowI -0000-00-00 00:00:00 MoscowI 0000-00-00 00:00:00 UTC 0000-00-00 00:00:00 UTCI 0000-00-00 00:00:00 UTCI 0000-00-00 00:00:00 UTCI -0000-00-00 00:00:00 UTCI 1970-01-01 03:00:01 Moscow 1970-01-01 03:00:01 UTC 1974-02-05 21:28:16 Moscow @@ -971,10 +982,12 @@ NULL UTC 2011-10-30 03:00:00 UTC 2011-10-30 03:00:01 Moscow 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 +2038-01-19 06:14:06 Moscow/Max-1 +2038-01-19 06:14:06 UTC/Max-1 +2038-01-19 06:14:07 Moscow/Max +2038-01-19 06:14:07 MoscowI/Max+1 +2038-01-19 06:14:07 UTC/Max +2038-01-19 06:14:07 UTCI/Max+1 # 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,10 +1180,13 @@ Warnings: Warning 1264 Out of range value for column 'a' at row 1 SELECT COUNT(*) FROM t2; COUNT(*) -35 +37 SELECT COUNT(*) FROM t2 WHERE a = 0; COUNT(*) 1 +SELECT COUNT(*) FROM t2 WHERE UNIX_TIMESTAMP(a)=0x7FFFFFFF; +COUNT(*) +4 SELECT * FROM t2 ORDER BY a, tz LIMIT 3; a tz NULL Moscow @@ -1178,44 +1194,47 @@ 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:07 Moscow/Max +2038-01-19 06:14:07 MoscowI/Max+1 +2038-01-19 06:14:07 UTC/Max 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 +Warning 1292 Truncated incorrect timestamp value: '2038-01-19 06:14:08' +Warning 1292 Truncated incorrect timestamp value: '2038-01-19 06:14:08' +Warning 1292 Truncated incorrect timestamp value: '2038-01-19 06:14:08' +Warning 1292 Truncated incorrect timestamp value: '2038-01-19 06:14:08' 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 +37 SELECT COUNT(*) FROM t2 WHERE a = 0; COUNT(*) -2 +0 +SELECT COUNT(*) FROM t2 WHERE UNIX_TIMESTAMP(a)=0x7FFFFFFF; +COUNT(*) +6 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 p-2012-MSK-1 0 p-2012-MSK-2 7 pEnd 0 -pMax 2 +pMax 6 SELECT * FROM t2 ORDER BY a, tz; 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 @@ -1244,18 +1263,25 @@ NULL UTC 2011-10-30 03:00:01 UTC 2011-10-30 03:00:02 Moscow 2011-10-30 03:00:02 UTC -2038-01-19 06:14:07 Moscow -2038-01-19 06:14:07 UTC +2038-01-19 06:14:07 Moscow/Max +2038-01-19 06:14:07 Moscow/Max-1 +2038-01-19 06:14:07 MoscowI/Max+1 +2038-01-19 06:14:07 UTC/Max +2038-01-19 06:14:07 UTC/Max-1 +2038-01-19 06:14:07 UTCI/Max+1 # Test start range changes INSERT IGNORE INTO t2 VALUES ('1970-01-01 00:00:00', 'Moscow'); Warnings: Warning 1264 Out of range value for column 'a' at row 1 SELECT COUNT(*) FROM t2; COUNT(*) -36 +38 SELECT COUNT(*) FROM t2 WHERE a = 0; COUNT(*) -3 +1 +SELECT COUNT(*) FROM t2 WHERE UNIX_TIMESTAMP(a)=0x7FFFFFFF; +COUNT(*) +6 SELECT * FROM t2 ORDER BY a, tz LIMIT 3; a tz NULL Moscow @@ -1263,44 +1289,43 @@ NULL Moscow NULL UTC 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 -2011-10-30 03:00:02 Moscow +2038-01-19 06:14:07 Moscow/Max +2038-01-19 06:14:07 Moscow/Max-1 +2038-01-19 06:14:07 MoscowI/Max+1 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 +38 SELECT COUNT(*) FROM t2 WHERE a = 0; COUNT(*) 0 +SELECT COUNT(*) FROM t2 WHERE UNIX_TIMESTAMP(a)=0x7FFFFFFF; +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 p-2011-MSD-2 9 p-2012-MSK-1 0 p-2012-MSK-2 4 -pEnd 2 +pEnd 6 pMax 0 SELECT * FROM t2 ORDER BY a, tz; 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 @@ -1330,13 +1355,17 @@ NULL UTC 2011-10-30 03:00:00 UTC 2011-10-30 03:00:01 Moscow 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:06 Moscow/Max +2038-01-19 06:14:06 Moscow/Max-1 +2038-01-19 06:14:06 MoscowI/Max+1 +2038-01-19 06:14:06 UTC/Max +2038-01-19 06:14:06 UTC/Max-1 +2038-01-19 06:14:06 UTCI/Max+1 SHOW CREATE TABLE t2; Table Create Table t2 CREATE TABLE `t2` ( `a` timestamp NULL DEFAULT NULL, - `tz` varchar(16) DEFAULT NULL + `tz` varchar(32) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PARTITION BY RANGE (unix_timestamp(`a`)) (PARTITION `p0` VALUES LESS THAN (0) ENGINE = MyISAM, diff --git a/mysql-test/main/partition_datatype.test b/mysql-test/main/partition_datatype.test index 9ab3bd4d5fa..803f7a5d668 100644 --- a/mysql-test/main/partition_datatype.test +++ b/mysql-test/main/partition_datatype.test @@ -247,7 +247,7 @@ 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)) + tz varchar(32)) ENGINE = MyISAM; CREATE TABLE t2 LIKE t1; ALTER TABLE t2 PARTITION BY RANGE (UNIX_TIMESTAMP(a)) @@ -268,14 +268,14 @@ 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 ('2038-01-19 03:14:08', 'UTCI/Max+1'); 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'); +INSERT INTO t1 VALUES ('2038-01-19 03:14:06', 'UTC/Max-1'); +INSERT INTO t1 VALUES ('2038-01-19 03:14:07', 'UTC/Max'); --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 +300,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 ('2038-01-19 06:14:08', 'MoscowI/Max+1'); 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'); @@ -310,8 +310,8 @@ INSERT IGNORE INTO t1 VALUES ('2011-03-27 02:59:59', 'MoscowI'); 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'); +INSERT INTO t1 VALUES ('2038-01-19 06:14:06', 'Moscow/Max-1'); +INSERT INTO t1 VALUES ('2038-01-19 06:14:07', 'Moscow/Max'); --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'); @@ -393,6 +393,7 @@ DELETE FROM t2 WHERE a = 0; INSERT IGNORE INTO t2 VALUES ('1970-01-01 00:00:00', 'UTC'); SELECT COUNT(*) FROM t2; SELECT COUNT(*) FROM t2 WHERE a = 0; +SELECT COUNT(*) FROM t2 WHERE UNIX_TIMESTAMP(a)=0x7FFFFFFF; SELECT * FROM t2 ORDER BY a, tz LIMIT 3; SELECT * FROM t2 ORDER BY a DESC, tz LIMIT 3; UPDATE IGNORE t2 SET a = TIMESTAMPADD(SECOND, 1, a); @@ -407,12 +408,14 @@ SELECT * FROM t2 ORDER BY a, tz; INSERT IGNORE INTO t2 VALUES ('1970-01-01 00:00:00', 'UTC'); SELECT COUNT(*) FROM t2; SELECT COUNT(*) FROM t2 WHERE a = 0; +SELECT COUNT(*) FROM t2 WHERE UNIX_TIMESTAMP(a)=0x7FFFFFFF; SELECT * FROM t2 ORDER BY a, tz LIMIT 3; SELECT * FROM t2 ORDER BY a DESC, tz LIMIT 3; UPDATE IGNORE t2 SET a = TIMESTAMPADD(SECOND, -1, a); SELECT MIN(a), MAX(a) FROM t2; SELECT COUNT(*) FROM t2; SELECT COUNT(*) FROM t2 WHERE a = 0; +SELECT COUNT(*) FROM t2 WHERE UNIX_TIMESTAMP(a)=0x7FFFFFFF; SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 't2'; SELECT * FROM t2 ORDER BY a, tz; @@ -518,12 +521,14 @@ DELETE FROM t2 WHERE a = 0; INSERT IGNORE INTO t2 VALUES ('1970-01-01 00:00:00', 'Moscow'); SELECT COUNT(*) FROM t2; SELECT COUNT(*) FROM t2 WHERE a = 0; +SELECT COUNT(*) FROM t2 WHERE UNIX_TIMESTAMP(a)=0x7FFFFFFF; SELECT * FROM t2 ORDER BY a, tz LIMIT 3; SELECT * FROM t2 ORDER BY a DESC, tz LIMIT 3; UPDATE IGNORE t2 SET a = TIMESTAMPADD(SECOND, 1, a); SELECT MIN(a), MAX(a) FROM t2; SELECT COUNT(*) FROM t2; SELECT COUNT(*) FROM t2 WHERE a = 0; +SELECT COUNT(*) FROM t2 WHERE UNIX_TIMESTAMP(a)=0x7FFFFFFF; SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 't2'; SELECT * FROM t2 ORDER BY a, tz; @@ -532,12 +537,14 @@ SELECT * FROM t2 ORDER BY a, tz; INSERT IGNORE INTO t2 VALUES ('1970-01-01 00:00:00', 'Moscow'); SELECT COUNT(*) FROM t2; SELECT COUNT(*) FROM t2 WHERE a = 0; +SELECT COUNT(*) FROM t2 WHERE UNIX_TIMESTAMP(a)=0x7FFFFFFF; SELECT * FROM t2 ORDER BY a, tz LIMIT 3; SELECT * FROM t2 ORDER BY a DESC, tz LIMIT 3; UPDATE IGNORE t2 SET a = TIMESTAMPADD(SECOND, -1, a); SELECT MIN(a), MAX(a) FROM t2; SELECT COUNT(*) FROM t2; SELECT COUNT(*) FROM t2 WHERE a = 0; +SELECT COUNT(*) FROM t2 WHERE UNIX_TIMESTAMP(a)=0x7FFFFFFF; SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 't2'; SELECT * FROM t2 ORDER BY a, tz; diff --git a/mysql-test/main/select.result b/mysql-test/main/select.result index 93687056c91..eefdab96551 100644 --- a/mysql-test/main/select.result +++ b/mysql-test/main/select.result @@ -3766,11 +3766,15 @@ AND t1.ts BETWEEN "2006-01-01" AND "2006-12-31"; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 1 SIMPLE t1 range ts ts 4 NULL 2 Using index condition; Using where +Warnings: +Warning 1292 Truncated incorrect timestamp value: '2999-12-31 00:00:00' SELECT * FROM t1 LEFT JOIN t2 ON (t1.a=t2.a) WHERE t1.a=30 AND t1.ts BETWEEN t2.dt1 AND t2.dt2 AND t1.ts BETWEEN "2006-01-01" AND "2006-12-31"; a ts a dt1 dt2 30 2006-01-03 23:00:00 30 2006-01-01 00:00:00 2999-12-31 00:00:00 +Warnings: +Warning 1292 Truncated incorrect timestamp value: '2999-12-31 00:00:00' DROP TABLE t1,t2; create table t1 (a bigint unsigned); insert into t1 values diff --git a/mysql-test/main/select_jcl6.result b/mysql-test/main/select_jcl6.result index c1098e660cd..5434d109da7 100644 --- a/mysql-test/main/select_jcl6.result +++ b/mysql-test/main/select_jcl6.result @@ -3777,11 +3777,15 @@ AND t1.ts BETWEEN "2006-01-01" AND "2006-12-31"; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 1 SIMPLE t1 range ts ts 4 NULL 2 Using index condition; Using where; Rowid-ordered scan +Warnings: +Warning 1292 Truncated incorrect timestamp value: '2999-12-31 00:00:00' SELECT * FROM t1 LEFT JOIN t2 ON (t1.a=t2.a) WHERE t1.a=30 AND t1.ts BETWEEN t2.dt1 AND t2.dt2 AND t1.ts BETWEEN "2006-01-01" AND "2006-12-31"; a ts a dt1 dt2 30 2006-01-03 23:00:00 30 2006-01-01 00:00:00 2999-12-31 00:00:00 +Warnings: +Warning 1292 Truncated incorrect timestamp value: '2999-12-31 00:00:00' DROP TABLE t1,t2; create table t1 (a bigint unsigned); insert into t1 values diff --git a/mysql-test/main/select_pkeycache.result b/mysql-test/main/select_pkeycache.result index 93687056c91..eefdab96551 100644 --- a/mysql-test/main/select_pkeycache.result +++ b/mysql-test/main/select_pkeycache.result @@ -3766,11 +3766,15 @@ AND t1.ts BETWEEN "2006-01-01" AND "2006-12-31"; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 1 SIMPLE t1 range ts ts 4 NULL 2 Using index condition; Using where +Warnings: +Warning 1292 Truncated incorrect timestamp value: '2999-12-31 00:00:00' SELECT * FROM t1 LEFT JOIN t2 ON (t1.a=t2.a) WHERE t1.a=30 AND t1.ts BETWEEN t2.dt1 AND t2.dt2 AND t1.ts BETWEEN "2006-01-01" AND "2006-12-31"; a ts a dt1 dt2 30 2006-01-03 23:00:00 30 2006-01-01 00:00:00 2999-12-31 00:00:00 +Warnings: +Warning 1292 Truncated incorrect timestamp value: '2999-12-31 00:00:00' DROP TABLE t1,t2; create table t1 (a bigint unsigned); insert into t1 values diff --git a/mysql-test/main/timezone2.result b/mysql-test/main/timezone2.result index 31b17fbc0d9..72dbd5ed990 100644 --- a/mysql-test/main/timezone2.result +++ b/mysql-test/main/timezone2.result @@ -120,7 +120,7 @@ insert into t1 values ('0000-00-00 00:00:00'),('1969-12-31 23:59:59'), 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 +Warning 1292 Truncated incorrect timestamp value: '2038-01-19 03:14:08' select * from t1; ts 0000-00-00 00:00:00 @@ -128,7 +128,7 @@ 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 +2038-01-19 03:14:07 truncate table t1; set time_zone='MET'; insert into t1 values ('0000-00-00 00:00:00'),('1970-01-01 00:30:00'), @@ -137,7 +137,7 @@ insert into t1 values ('0000-00-00 00:00:00'),('1970-01-01 00:30:00'), 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 +Warning 1292 Truncated incorrect timestamp value: '2038-01-19 04:14:08' select * from t1; ts 0000-00-00 00:00:00 @@ -145,7 +145,7 @@ 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 +2038-01-19 04:14:07 truncate table t1; set time_zone='+01:30'; insert into t1 values ('0000-00-00 00:00:00'),('1970-01-01 01:00:00'), @@ -154,7 +154,7 @@ insert into t1 values ('0000-00-00 00:00:00'),('1970-01-01 01:00:00'), 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 +Warning 1292 Truncated incorrect timestamp value: '2038-01-19 04:44:08' select * from t1; ts 0000-00-00 00:00:00 @@ -162,7 +162,7 @@ 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 +2038-01-19 04:44:07 drop table t1; show variables like 'time_zone'; Variable_name Value diff --git a/sql-common/my_time.c b/sql-common/my_time.c index 96674723b34..fe26e55cf7b 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -1257,6 +1257,10 @@ my_system_gmt_sec(const MYSQL_TIME *t_src, long *my_timezone, uint *error_code) MYSQL_TIME *t= &tmp_time; struct tm *l_time,tm_tmp; long diff, current_timezone; + my_time_t minmax; + + if ((*error_code= MYSQL_TIME_check_rough_timestamp_range(t_src, &minmax))) + return minmax; /* Use temp variable to avoid trashing input data, which could happen in @@ -1264,13 +1268,6 @@ my_system_gmt_sec(const MYSQL_TIME *t_src, long *my_timezone, uint *error_code) */ memcpy(&tmp_time, t_src, sizeof(MYSQL_TIME)); - if (!validate_timestamp_range(t)) - { - *error_code= ER_WARN_DATA_OUT_OF_RANGE; - return 0; - } - *error_code= 0; - /* Calculate the gmt time based on current time and timezone The -1 on the end is to ensure that if have a date that exists twice diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 26adc4eddaa..52b9ae7a682 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2793,11 +2793,17 @@ bool Item_func_convert_tz::get_date(THD *thd, MYSQL_TIME *ltime, return true; { - uint not_used; - my_time_tmp= from_tz->TIME_to_gmt_sec(ltime, ¬_used); + uint error_code; + my_time_tmp= from_tz->TIME_to_gmt_sec(ltime, &error_code); ulong sec_part= ltime->second_part; - /* my_time_tmp is guaranteed to be in the allowed range */ - if (my_time_tmp) + /* + my_time_tmp is guaranteed to be in the allowed range. + Don't perform the conversion in case the source DATETIME was above + TIMESTAMP_MAX_VALUE (and was truncated to TIMESTAMP_MAX_VALUE). + */ + if (my_time_tmp && + (my_time_tmp != TIMESTAMP_MAX_VALUE || + error_code != ER_WARN_DATA_OUT_OF_RANGE)) to_tz->gmt_sec_to_TIME(ltime, my_time_tmp); /* we rely on the fact that no timezone conversion can change sec_part */ ltime->second_part= sec_part; diff --git a/sql/sql_time.cc b/sql/sql_time.cc index 753f78ccc22..6899654c28f 100644 --- a/sql/sql_time.cc +++ b/sql/sql_time.cc @@ -509,7 +509,14 @@ bool int_to_datetime_with_warn(THD *thd, const Longlong_hybrid &nr, my_time_t TIME_to_timestamp(THD *thd, const MYSQL_TIME *t, uint *error_code) { thd->used|= THD::TIME_ZONE_USED; - return thd->variables.time_zone->TIME_to_gmt_sec(t, error_code); + my_time_t ts= thd->variables.time_zone->TIME_to_gmt_sec(t, error_code); + if (*error_code == ER_WARN_DATA_OUT_OF_RANGE && ts == TIMESTAMP_MAX_VALUE) + { + ErrConvTime value(t); + thd->push_warning_truncated_wrong_value("timestamp", value.ptr()); + *error_code= 0; + } + return ts; } diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 3759c0ba02f..5d109309d85 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -410,7 +410,7 @@ Timestamp_or_zero_datetime::Timestamp_or_zero_datetime(THD *thd, const MYSQL_TIME *ltime, uint *error_code) :Timestamp(thd, ltime, error_code), - m_is_zero_datetime(*error_code == ER_WARN_DATA_OUT_OF_RANGE) + m_is_zero_datetime(*error_code == ER_WARN_DATA_OUT_OF_RANGE && tv_sec == 0) { if (m_is_zero_datetime) { diff --git a/sql/tztime.cc b/sql/tztime.cc index 57f1ab872ee..8aee74f0510 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -902,13 +902,8 @@ TIME_to_gmt_sec(const MYSQL_TIME *t, const TIME_ZONE_INFO *sp, uint *error_code) int shift= 0; DBUG_ENTER("TIME_to_gmt_sec"); - if (!validate_timestamp_range(t)) - { - *error_code= ER_WARN_DATA_OUT_OF_RANGE; - DBUG_RETURN(0); - } - - *error_code= 0; + if ((*error_code= MYSQL_TIME_check_rough_timestamp_range(t, &local_t))) + DBUG_RETURN(local_t); /* We need this for correct leap seconds handling */ if (t->second < SECS_PER_MIN) @@ -953,7 +948,7 @@ TIME_to_gmt_sec(const MYSQL_TIME *t, const TIME_ZONE_INFO *sp, uint *error_code) limited my_time_t range. */ *error_code= ER_WARN_DATA_OUT_OF_RANGE; - DBUG_RETURN(0); + DBUG_RETURN(local_t > sp->revts[sp->revcnt] ? TIMESTAMP_MAX_VALUE : 0); } /* binary search for our range */ @@ -970,7 +965,7 @@ TIME_to_gmt_sec(const MYSQL_TIME *t, const TIME_ZONE_INFO *sp, uint *error_code) sp->revtis[i].rt_offset - saved_seconds)) { *error_code= ER_WARN_DATA_OUT_OF_RANGE; - DBUG_RETURN(0); /* my_time_t overflow */ + DBUG_RETURN(TIMESTAMP_MAX_VALUE); /* my_time_t overflow */ } local_t+= shift * SECS_PER_DAY; } @@ -1368,12 +1363,8 @@ Time_zone_offset::TIME_to_gmt_sec(const MYSQL_TIME *t, uint *error_code) const Check timestamp range.we have to do this as calling function relies on us to make all validation checks here. */ - if (!validate_timestamp_range(t)) - { - *error_code= ER_WARN_DATA_OUT_OF_RANGE; - return 0; - } - *error_code= 0; + if ((*error_code= MYSQL_TIME_check_rough_timestamp_range(t, &local_t))) + return local_t; /* Do a temporary shift of the boundary dates to avoid @@ -1398,7 +1389,7 @@ Time_zone_offset::TIME_to_gmt_sec(const MYSQL_TIME *t, uint *error_code) const /* range error*/ *error_code= ER_WARN_DATA_OUT_OF_RANGE; - return 0; + return local_t > TIMESTAMP_MAX_VALUE ? TIMESTAMP_MAX_VALUE : 0; } |