mirror of
https://github.com/MariaDB/server.git
synced 2026-01-06 05:22:24 +03:00
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.
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user