diff options
Diffstat (limited to 'mysql-test/suite/versioning')
71 files changed, 10440 insertions, 0 deletions
diff --git a/mysql-test/suite/versioning/common.inc b/mysql-test/suite/versioning/common.inc new file mode 100644 index 00000000000..cbc515241b0 --- /dev/null +++ b/mysql-test/suite/versioning/common.inc @@ -0,0 +1,127 @@ +--disable_query_log +source include/have_innodb.inc; + +set @@session.time_zone='+00:00'; +select ifnull(max(transaction_id), 0) into @start_trx_id from mysql.transaction_registry; +set @test_start=now(6); + +delimiter ~~; +create procedure if not exists verify_vtq() +begin + set @i= 0; + select + @i:= @i + 1 as No, + transaction_id > 0 as A, + commit_id > transaction_id as B, + begin_timestamp > @test_start as C, + commit_timestamp >= begin_timestamp as D + from mysql.transaction_registry + where transaction_id > @start_trx_id; + select ifnull(max(transaction_id), 0) + into @start_trx_id + from mysql.transaction_registry; +end~~ + +create function if not exists default_engine() +returns varchar(255) +deterministic +begin + declare e varchar(255); + select engine from information_schema.engines where support='DEFAULT' into e; + return e; +end~~ + +create function if not exists non_default_engine() +returns varchar(255) +deterministic +begin + if default_engine() = 'InnoDB' then + return 'MyISAM'; + end if; + return 'InnoDB'; +end~~ + +create function if not exists sys_datatype(engine varchar(255)) +returns varchar(255) +deterministic +begin + if engine = 'InnoDB' then + return 'bigint(20) unsigned'; + elseif engine = 'MyISAM' then + return 'timestamp(6)'; + end if; + return NULL; +end~~ + +create function if not exists current_row(sys_trx_end varbinary(255)) +returns int +deterministic +begin + declare continue handler for sqlwarning begin end; + return sys_trx_end = timestamp'2038-01-19 03:14:07.999999' + or sys_trx_end = 18446744073709551615; +end~~ + +create function if not exists sys_commit_ts(sys_field varchar(255)) +returns varchar(255) +deterministic +begin + if default_engine() = 'InnoDB' then + return concat('vtq_commit_ts(', sys_field, ')'); + elseif default_engine() = 'MyISAM' then + return sys_field; + end if; + return NULL; +end~~ + +create procedure if not exists verify_vtq_dummy(recs int) +begin + declare i int default 1; + create temporary table tmp (No int, A bool, B bool, C bool, D bool); + while i <= recs do + insert into tmp values (i, 1, 1, 1, 1); + set i= i + 1; + end while; + select * from tmp; + drop table tmp; +end~~ + +create procedure concat_exec2(a varchar(255), b varchar(255)) +begin + prepare stmt from concat(a, b); + execute stmt; + deallocate prepare stmt; +end~~ + +create procedure concat_exec3(a varchar(255), b varchar(255), c varchar(255)) +begin + prepare stmt from concat(a, b, c); + execute stmt; + deallocate prepare stmt; +end~~ +delimiter ;~~ + +let $default_engine= `select default_engine()`; +let $non_default_engine= `select non_default_engine()`; +let $sys_datatype= timestamp(6); +let $sys_datatype_expl= timestamp(6); +let $sys_datatype_uc= TIMESTAMP(6); +let $sys_datatype_expl_uc= TIMESTAMP(6); + +let $non_sys_datatype= `select sys_datatype(non_default_engine())`; +let $non_sys_datatype_uc= `select upper(sys_datatype(non_default_engine()))`; +let $sys_datatype_null= $sys_datatype NULL DEFAULT NULL; +let $sys_datatype_default_null= $sys_datatype DEFAULT NULL; +let $sys_datatype_not_null= $sys_datatype NOT NULL DEFAULT '0000-00-00 00:00:00.000000'; +let $non_sys_datatype_null= $non_sys_datatype NULL; + +if ($MTR_COMBINATION_MYISAM) +{ + --let $MTR_COMBINATION_TIMESTAMP= 1 +} +if ($MTR_COMBINATION_TRX_ID) +{ + let $sys_datatype_expl= bigint(20) unsigned; + let $sys_datatype_expl_uc= BIGINT(20) UNSIGNED; +} +--enable_query_log diff --git a/mysql-test/suite/versioning/common.opt b/mysql-test/suite/versioning/common.opt new file mode 100644 index 00000000000..412290a7585 --- /dev/null +++ b/mysql-test/suite/versioning/common.opt @@ -0,0 +1 @@ +--plugin-load-add=test_versioning diff --git a/mysql-test/suite/versioning/common_finish.inc b/mysql-test/suite/versioning/common_finish.inc new file mode 100644 index 00000000000..1059bb1251d --- /dev/null +++ b/mysql-test/suite/versioning/common_finish.inc @@ -0,0 +1,11 @@ +--disable_query_log +drop procedure verify_vtq; +drop procedure verify_vtq_dummy; +drop function default_engine; +drop function non_default_engine; +drop function sys_commit_ts; +drop function sys_datatype; +drop function current_row; +drop procedure concat_exec2; +drop procedure concat_exec3; +--enable_query_log diff --git a/mysql-test/suite/versioning/disabled.def b/mysql-test/suite/versioning/disabled.def new file mode 100644 index 00000000000..e0f1483d0ef --- /dev/null +++ b/mysql-test/suite/versioning/disabled.def @@ -0,0 +1,15 @@ +############################################################################## +# +# List the test cases that are to be disabled temporarily. +# +# Separate the test case name and the comment with ':'. +# +# <testcasename> : BUG#<xxxx> <date disabled> <disabler> <comment> +# +# Do not use any TAB characters for whitespace. +# +############################################################################## +ddl : DDL Survival WIP +vtmd : DDL Survival WIP +vtmd_show : DDL Survival WIP +cte: MDEV-14820 diff --git a/mysql-test/suite/versioning/engines.combinations b/mysql-test/suite/versioning/engines.combinations new file mode 100644 index 00000000000..561c5656929 --- /dev/null +++ b/mysql-test/suite/versioning/engines.combinations @@ -0,0 +1,8 @@ +[timestamp] +default-storage-engine=innodb + +[trx_id] +default-storage-engine=innodb + +[myisam] +default-storage-engine=myisam diff --git a/mysql-test/suite/versioning/engines.inc b/mysql-test/suite/versioning/engines.inc new file mode 100644 index 00000000000..c841fece702 --- /dev/null +++ b/mysql-test/suite/versioning/engines.inc @@ -0,0 +1 @@ +--source include/have_innodb.inc diff --git a/mysql-test/suite/versioning/key_type.combinations b/mysql-test/suite/versioning/key_type.combinations new file mode 100644 index 00000000000..1929aee9a84 --- /dev/null +++ b/mysql-test/suite/versioning/key_type.combinations @@ -0,0 +1,2 @@ +[unique] +[pk] diff --git a/mysql-test/suite/versioning/key_type.inc b/mysql-test/suite/versioning/key_type.inc new file mode 100644 index 00000000000..648430771cf --- /dev/null +++ b/mysql-test/suite/versioning/key_type.inc @@ -0,0 +1,23 @@ +--disable_query_log +if ($MTR_COMBINATION_UNIQUE) +{ + set @KEY_TYPE= 'unique'; +} +if ($MTR_COMBINATION_PK) +{ + set @KEY_TYPE= 'primary key'; +} + +delimiter ~~; +create procedure create_table(name varchar(255), cols varchar(255)) +begin + if (cols is null or cols = '') then + set cols= ''; + else + set cols= concat(', ', cols); + end if; + set @str= concat('create or replace table ', name, '(id int ', @KEY_TYPE, cols, ') with system versioning'); + prepare stmt from @str; execute stmt; drop prepare stmt; +end~~ +delimiter ;~~ +--enable_query_log diff --git a/mysql-test/suite/versioning/r/alter.result b/mysql-test/suite/versioning/r/alter.result new file mode 100644 index 00000000000..04d7139b207 --- /dev/null +++ b/mysql-test/suite/versioning/r/alter.result @@ -0,0 +1,452 @@ +select @@system_versioning_alter_history; +@@system_versioning_alter_history +ERROR +create table t( +a int +); +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +alter table t drop system versioning; +ERROR HY000: Table `t` is not system-versioned +alter table t add system versioning; +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +alter table t add column y int; +ERROR HY000: Not allowed for system-versioned `test`.`t`. Change @@system_versioning_alter_history to proceed with ALTER. +alter table t engine innodb; +ERROR HY000: Not allowed for system-versioned `test`.`t`. Change to/from native system versioning engine is prohibited. +alter table t drop system versioning; +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +set system_versioning_alter_history= keep; +alter table t +add column trx_start bigint(20) unsigned as row start invisible, +add column trx_end bigint(20) unsigned as row end invisible, +add period for system_time(trx_start, trx_end), +add system versioning; +ERROR HY000: `trx_start` must be of type TIMESTAMP(6) for system-versioned table `t` +alter table t +add column trx_start timestamp as row start invisible, +add column trx_end timestamp as row end invisible, +add period for system_time(trx_start, trx_end), +add system versioning; +ERROR HY000: `trx_start` must be of type TIMESTAMP(6) for system-versioned table `t` +alter table t +add column trx_start timestamp(6) not null as row start invisible, +add column trx_end timestamp(6) not null as row end invisible, +add period for system_time(trx_start, trx_end), +add system versioning; +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 'as row start invisible, +add column trx_end timestamp(6) not null as row end invi' at line 2 +alter table t +add column trx_start timestamp(6) as row start invisible, +add column trx_end timestamp(6) as row end invisible, +add period for system_time(trx_start, trx_end), +add system versioning; +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL, + `trx_start` timestamp(6) GENERATED ALWAYS AS ROW START INVISIBLE, + `trx_end` timestamp(6) GENERATED ALWAYS AS ROW END INVISIBLE, + PERIOD FOR SYSTEM_TIME (`trx_start`, `trx_end`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +alter table t drop column trx_start, drop column trx_end; +alter table t drop system versioning; +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +alter table t add system versioning; +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +alter table t add column b int; +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +alter table t add column c int; +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +alter table t add column d int first; +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `d` int(11) DEFAULT NULL, + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +alter table t add column e int after d; +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `d` int(11) DEFAULT NULL, + `e` int(11) DEFAULT NULL, + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +alter table t drop column a; +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `d` int(11) DEFAULT NULL, + `e` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +create or replace table t ( +a int, +row_start timestamp(6) as row start invisible, +row_end timestamp(6) as row end invisible, +period for system_time(row_start, row_end)) +with system versioning; +select * from t for system_time all; +a +alter table t drop column row_start; +ERROR HY000: Wrong parameters for `t`: missing 'DROP COLUMN row_end' +alter table t drop column row_end; +ERROR HY000: Wrong parameters for `t`: missing 'DROP COLUMN row_start' +alter table t drop column row_start, drop column row_end; +select * from t for system_time all; +a +alter table t drop column row_start; +ERROR 42000: Can't DROP COLUMN `row_start`; check that it exists +alter table t drop column row_end; +ERROR 42000: Can't DROP COLUMN `row_end`; check that it exists +create or replace table t ( +a int, +row_start timestamp(6) as row start invisible, +row_end timestamp(6) as row end invisible, +period for system_time(row_start, row_end)) +with system versioning; +select * from t for system_time all; +a +alter table t drop column row_start, drop column row_end; +select * from t for system_time all; +a +create or replace table t( +a int +); +insert into t values(1); +alter table t add system versioning; +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +insert into t values(2); +select * from t for system_time all; +a +1 +2 +select * from t; +a +1 +2 +update t set a=3 where a=1; +select * from t; +a +3 +2 +select * from t for system_time all; +a +3 +2 +1 +select row_start from t where a=3 into @tm; +alter table t add column b int; +select @tm=row_start from t where a=3; +@tm=row_start +1 +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +select * from t; +a b +3 NULL +2 NULL +select * from t for system_time all; +a b +3 NULL +2 NULL +1 NULL +alter table t drop system versioning; +select * from t; +a b +3 NULL +2 NULL +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +alter table t modify a int with system versioning; +ERROR HY000: Table `t` is not system-versioned +alter table t modify a int without system versioning; +ERROR HY000: Table `t` is not system-versioned +alter table t add system versioning; +alter table t modify a int without system versioning; +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL WITHOUT SYSTEM VERSIONING, + `b` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +alter table t modify a int with system versioning; +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +create or replace table t( +a int +) engine=innodb; +alter table t +add column trx_start timestamp(6) as row start invisible, +add column trx_end timestamp(6) as row end invisible, +add period for system_time(trx_start, trx_end), +add system versioning; +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL, + `trx_start` timestamp(6) GENERATED ALWAYS AS ROW START INVISIBLE, + `trx_end` timestamp(6) GENERATED ALWAYS AS ROW END INVISIBLE, + PERIOD FOR SYSTEM_TIME (`trx_start`, `trx_end`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +# Issue #211: drop of system columns required before drop system versioning +alter table t drop column trx_start, drop column trx_end; +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +alter table t drop system versioning; +insert into t values(1); +call verify_vtq; +No A B C D +alter table t +add column trx_start bigint(20) unsigned as row start invisible, +add column trx_end bigint(20) unsigned as row end invisible, +add period for system_time(trx_start, trx_end), +add system versioning; +call verify_vtq; +No A B C D +1 1 1 1 1 +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL, + `trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START INVISIBLE, + `trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END INVISIBLE, + PERIOD FOR SYSTEM_TIME (`trx_start`, `trx_end`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +alter table t drop column trx_start, drop column trx_end; +call verify_vtq; +No A B C D +alter table t drop system versioning, algorithm=copy; +call verify_vtq; +No A B C D +alter table t add system versioning, algorithm=copy; +call verify_vtq; +No A B C D +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +update t set a= 2; +select * from t for system_time all; +a +2 +1 +alter table t add column b int, algorithm=copy; +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +select * from t; +a b +2 NULL +call verify_vtq; +No A B C D +alter table t drop column b, algorithm=copy; +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +select * from t for system_time all; +a +2 +1 +call verify_vtq; +No A B C D +alter table t drop system versioning, algorithm=copy; +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +call verify_vtq; +No A B C D +create or replace table t (a int); +insert t values (1),(2),(3),(4); +alter table t add b int auto_increment null unique; +select * from t; +a b +1 1 +2 2 +3 3 +4 4 +drop table t; +create or replace table t (a int) with system versioning engine=innodb; +insert into t values (1), (2), (3); +delete from t where a<3; +alter table t add b int not null unique; +Got one of the listed errors +alter table t add b int auto_increment unique; +Got one of the listed errors +alter table t add b int auto_increment null unique; +select * from t; +a b +3 1 +select * from t for system_time all; +a b +1 NULL +2 NULL +3 1 +insert into t values (4, 0); +select * from t for system_time all; +a b +1 NULL +2 NULL +3 1 +4 4 +create or replace table t (a int) with system versioning; +insert into t values (1), (2), (3); +delete from t where a<3; +alter table t add b int not null unique; +Got one of the listed errors +alter table t add b int auto_increment unique; +Got one of the listed errors +alter table t add b int auto_increment null unique; +select * from t; +a b +3 1 +select * from t for system_time all; +a b +1 NULL +2 NULL +3 1 +insert into t values (4, 0); +select * from t for system_time all; +a b +1 NULL +2 NULL +3 1 +4 2 +create or replace table t ( +a int, +row_start timestamp(6) as row start invisible, +row_end timestamp(6) as row end invisible, +period for system_time(row_start, row_end) +) with system versioning; +alter table t change column row_start asdf timestamp(6); +ERROR HY000: Can not change system versioning field `row_start` +insert into t values (1); +alter table t modify column row_start bigint unsigned; +ERROR HY000: Can not change system versioning field `row_start` +set system_versioning_alter_history= SURVIVE; +ERROR 42000: Variable 'system_versioning_alter_history' can't be set to the value of 'SURVIVE' +set system_versioning_alter_history= 'DROP'; +ERROR 42000: Variable 'system_versioning_alter_history' can't be set to the value of 'DROP' +create or replace table t (a int) with system versioning; +alter table t add system versioning; +ERROR HY000: Table `t` is already system-versioned +alter table t add system versioning, drop system versioning; +ERROR HY000: Table `t` is already system-versioned +set @@system_versioning_alter_history=keep; +create or replace table t(x int, y int) with system versioning engine=innodb; +alter table t modify y int without system versioning; +insert into t values(1, 1); +update t set y=2; +# MDEV-14681 Bogus ER_UNSUPPORTED_EXTENSION +create or replace table t1 (pk int auto_increment unique) with system versioning; +insert into t1 values (1); +delete from t1; +alter table t1 engine=myisam; +# MDEV-14692 crash in MDL_context::upgrade_shared_lock() +create or replace temporary table t (a int); +alter table t change column if exists b c bigint unsigned generated always as row start; +ERROR HY000: System versioning prohibited for TEMPORARY tables +alter table t change column if exists b c bigint unsigned generated always as row end; +ERROR HY000: System versioning prohibited for TEMPORARY tables +alter table t add system versioning; +ERROR HY000: System versioning prohibited for TEMPORARY tables +drop table t; +# MDEV-14744 trx_id-based and transaction-based mixup in assertion +create or replace table t (c text) engine=innodb with system versioning; +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `c` text DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +alter table t add fulltext key (c); +Warnings: +Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID +create or replace table t (a int) with system versioning; +alter table t drop column a; +ERROR HY000: Table `t` must have at least one versioned column +alter table t drop column a, drop column a; +ERROR 42000: Can't DROP COLUMN `a`; check that it exists +create or replace table t1 (row_start int); +alter table t1 with system versioning; +ERROR 42S21: Duplicate column name 'row_start' +create or replace table t1 (row_end int); +alter table t1 with system versioning; +ERROR 42S21: Duplicate column name 'row_end' +create or replace table t1 (a int, row_start int) with system versioning; +ERROR 42S21: Duplicate column name 'row_start' +create or replace table t1 (a int) with system versioning; +set statement system_versioning_alter_history=keep for +alter table t1 add column row_start int; +ERROR 42S21: Duplicate column name 'row_start' +set statement system_versioning_alter_history=keep for +alter table t1 add column row_start timestamp(6); +ERROR 42S21: Duplicate column name 'row_start' +# MDEV-14798 Add, drop system versioning semantic and syntax +create or replace table t (a int) with system versioning; +alter table t add period for system_time(sys_trx_start, sys_trx_end); +ERROR HY000: Table `t` is already system-versioned +drop database test; +create database test; diff --git a/mysql-test/suite/versioning/r/auto_increment.result b/mysql-test/suite/versioning/r/auto_increment.result new file mode 100644 index 00000000000..1f43595848b --- /dev/null +++ b/mysql-test/suite/versioning/r/auto_increment.result @@ -0,0 +1,119 @@ +create procedure test_01( +sys_type varchar(255), +engine varchar(255), +fields varchar(255)) +begin +set @str= concat(' + create table t1( + id int unsigned auto_increment primary key, + x int unsigned, + y int unsigned, + sys_start ', sys_type, ' as row start invisible, + sys_end ', sys_type, ' as row end invisible, + period for system_time (sys_start, sys_end)) + with system versioning + engine ', engine); +prepare stmt from @str; execute stmt; drop prepare stmt; +set @str= concat(' + create table t2( + id int unsigned auto_increment primary key, + x int unsigned, + y int unsigned) + engine ', engine); +prepare stmt from @str; execute stmt; drop prepare stmt; +insert into t1(x, y) values(1, 11); +insert into t2(x, y) values(1, 11); +insert into t1(x, y) values(2, 12); +insert into t2(x, y) values(2, 12); +insert into t1(x, y) values(3, 13); +insert into t2(x, y) values(3, 13); +insert into t1(x, y) values(4, 14); +insert into t2(x, y) values(4, 14); +insert into t1(x, y) values(5, 15); +insert into t2(x, y) values(5, 15); +insert into t1(x, y) values(6, 16); +insert into t2(x, y) values(6, 16); +insert into t1(x, y) values(7, 17); +insert into t2(x, y) values(7, 17); +insert into t1(x, y) values(8, 18); +insert into t2(x, y) values(8, 18); +insert into t1(x, y) values(9, 19); +insert into t2(x, y) values(9, 19); +select t1.x = t2.x and t1.y = t2.y as A, t1.x, t1.y, t2.x, t2.y from t1 inner join t2 on t1.id = t2.id; +delete from t1 where x = 2; +delete from t2 where x = 2; +select t1.x = t2.x and t1.y = t2.y as A, t1.x, t1.y, t2.x, t2.y from t1 inner join t2 on t1.id = t2.id; +delete from t1 where x > 7; +delete from t2 where x > 7; +select t1.x = t2.x and t1.y = t2.y as A, t1.x, t1.y, t2.x, t2.y from t1 inner join t2 on t1.id = t2.id; +drop table t1; +drop table t2; +end~~ +call test_01('timestamp(6)', 'myisam', 'sys_end'); +A x y x y +1 1 11 1 11 +1 2 12 2 12 +1 3 13 3 13 +1 4 14 4 14 +1 5 15 5 15 +1 6 16 6 16 +1 7 17 7 17 +1 8 18 8 18 +1 9 19 9 19 +A x y x y +1 1 11 1 11 +1 3 13 3 13 +1 4 14 4 14 +1 5 15 5 15 +1 6 16 6 16 +1 7 17 7 17 +1 8 18 8 18 +1 9 19 9 19 +A x y x y +1 1 11 1 11 +1 3 13 3 13 +1 4 14 4 14 +1 5 15 5 15 +1 6 16 6 16 +1 7 17 7 17 +call test_01('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_end)'); +A x y x y +1 1 11 1 11 +1 2 12 2 12 +1 3 13 3 13 +1 4 14 4 14 +1 5 15 5 15 +1 6 16 6 16 +1 7 17 7 17 +1 8 18 8 18 +1 9 19 9 19 +A x y x y +1 1 11 1 11 +1 3 13 3 13 +1 4 14 4 14 +1 5 15 5 15 +1 6 16 6 16 +1 7 17 7 17 +1 8 18 8 18 +1 9 19 9 19 +A x y x y +1 1 11 1 11 +1 3 13 3 13 +1 4 14 4 14 +1 5 15 5 15 +1 6 16 6 16 +1 7 17 7 17 +call verify_vtq; +No A B C D +1 1 1 1 1 +2 1 1 1 1 +3 1 1 1 1 +4 1 1 1 1 +5 1 1 1 1 +6 1 1 1 1 +7 1 1 1 1 +8 1 1 1 1 +9 1 1 1 1 +10 1 1 1 1 +11 1 1 1 1 +drop procedure test_01; diff --git a/mysql-test/suite/versioning/r/commit_id.result b/mysql-test/suite/versioning/r/commit_id.result new file mode 100644 index 00000000000..e2bd0f21b64 --- /dev/null +++ b/mysql-test/suite/versioning/r/commit_id.result @@ -0,0 +1,98 @@ +create table t1( +id int auto_increment primary key, +sys_trx_start bigint unsigned as row start invisible, +sys_trx_end bigint unsigned as row end invisible, +period for system_time (sys_trx_start, sys_trx_end) +) +with system versioning +engine innodb; +insert into t1 values (); +set @ts0= now(6); +insert into t1 values (); +select sys_trx_start from t1 where id = last_insert_id() into @tx0; +select transaction_id = @tx0 from mysql.transaction_registry +order by transaction_id desc limit 1; +transaction_id = @tx0 +1 +set @ts1= now(6); +insert into t1 values (); +select sys_trx_start from t1 where id = last_insert_id() into @tx1; +select transaction_id = @tx1 from mysql.transaction_registry +order by transaction_id desc limit 1; +transaction_id = @tx1 +1 +set @ts2= now(6); +insert into t1 values (); +select sys_trx_start from t1 where id = last_insert_id() into @tx2; +select transaction_id = @tx2 from mysql.transaction_registry +order by transaction_id desc limit 1; +transaction_id = @tx2 +1 +set @ts3= now(6); +select +vtq_trx_id(@ts0) < @tx0 as A, +vtq_trx_id(@ts0, true) = @tx0 as B, +vtq_trx_id(@ts1) = @tx0 as C, +vtq_trx_id(@ts1, true) = @tx1 as D, +vtq_trx_id(@ts2) = @tx1 as E, +vtq_trx_id(@ts2, true) = @tx2 as F, +vtq_trx_id(@ts3) = @tx2 as G, +vtq_trx_id(@ts3, true) is null as H; +A B C D E F G H +1 1 1 1 1 1 1 1 +select +vtq_commit_id(@ts0) < @tx0 as A, +vtq_commit_id(@ts0, true) = vtq_commit_id(null, @tx0) as B, +vtq_commit_id(@ts1) = vtq_commit_id(null, @tx0) as C, +vtq_commit_id(@ts1, true) = vtq_commit_id(null, @tx1) as D, +vtq_commit_id(@ts2) = vtq_commit_id(null, @tx1) as E, +vtq_commit_id(@ts2, true) = vtq_commit_id(null, @tx2) as F, +vtq_commit_id(@ts3) = vtq_commit_id(null, @tx2) as G, +vtq_commit_id(@ts3, true) is null as H; +A B C D E F G H +1 1 1 1 1 1 1 1 +select +vtq_trx_sees(@tx1, @tx0) as A, +not vtq_trx_sees(@tx0, @tx1) as B, +vtq_trx_sees_eq(@tx1, @tx1) as C, +not vtq_trx_sees(@tx1, @tx1) as D, +vtq_trx_sees(@tx2, 0) as E, +vtq_trx_sees(0, @tx2) is null as F, +vtq_trx_sees(-1, @tx2) as H; +A B C D E F H +1 1 1 1 1 1 1 +set transaction isolation level read uncommitted; +insert into t1 values (); +select sys_trx_start from t1 where id = last_insert_id() into @tx3; +select isolation_level = 'READ-UNCOMMITTED' from mysql.transaction_registry where transaction_id = @tx3; +isolation_level = 'READ-UNCOMMITTED' +1 +set transaction isolation level read committed; +insert into t1 values (); +select sys_trx_start from t1 where id = last_insert_id() into @tx4; +select isolation_level = 'READ-COMMITTED' from mysql.transaction_registry where transaction_id = @tx4; +isolation_level = 'READ-COMMITTED' +1 +set transaction isolation level serializable; +insert into t1 values (); +select sys_trx_start from t1 where id = last_insert_id() into @tx5; +select isolation_level = 'SERIALIZABLE' from mysql.transaction_registry where transaction_id = @tx5; +isolation_level = 'SERIALIZABLE' +1 +set transaction isolation level repeatable read; +insert into t1 values (); +select sys_trx_start from t1 where id = last_insert_id() into @tx6; +select isolation_level = 'REPEATABLE-READ' from mysql.transaction_registry where transaction_id = @tx6; +isolation_level = 'REPEATABLE-READ' +1 +drop table t1; +call verify_vtq; +No A B C D +1 1 1 1 1 +2 1 1 1 1 +3 1 1 1 1 +4 1 1 1 1 +5 1 1 1 1 +6 1 1 1 1 +7 1 1 1 1 +8 1 1 1 1 diff --git a/mysql-test/suite/versioning/r/create.result b/mysql-test/suite/versioning/r/create.result new file mode 100644 index 00000000000..7fe1db5964f --- /dev/null +++ b/mysql-test/suite/versioning/r/create.result @@ -0,0 +1,470 @@ +drop table if exists t1; +create table t1 ( +x1 int unsigned, +Sys_start SYS_DATATYPE as row start invisible comment 'start', +Sys_end SYS_DATATYPE as row end invisible comment 'end', +period for system_time (Sys_start, Sys_end) +) with system versioning; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x1` int(10) unsigned DEFAULT NULL, + `Sys_start` SYS_DATATYPE GENERATED ALWAYS AS ROW START INVISIBLE COMMENT 'start', + `Sys_end` SYS_DATATYPE GENERATED ALWAYS AS ROW END INVISIBLE COMMENT 'end', + PERIOD FOR SYSTEM_TIME (`Sys_start`, `Sys_end`) +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +select table_catalog,table_schema,table_name,table_type,version,table_rows,avg_row_length,data_free,auto_increment,check_time,table_collation,checksum,create_options,table_comment from information_schema.tables where table_name='t1'; +table_catalog def +table_schema test +table_name t1 +table_type SYSTEM VERSIONED +version 10 +table_rows 0 +avg_row_length 0 +data_free 0 +auto_increment NULL +check_time NULL +table_collation latin1_swedish_ci +checksum NULL +create_options +table_comment +select table_catalog,table_schema,table_name,column_name,ordinal_position,column_default,character_maximum_length,character_octet_length,character_set_name,collation_name,column_key,extra,column_comment,is_generated,generation_expression from information_schema.columns where table_name='t1'; +table_catalog def +table_schema test +table_name t1 +column_name x1 +ordinal_position 1 +column_default NULL +character_maximum_length NULL +character_octet_length NULL +character_set_name NULL +collation_name NULL +column_key +extra +column_comment +is_generated NEVER +generation_expression NULL +table_catalog def +table_schema test +table_name t1 +column_name Sys_start +ordinal_position 2 +column_default NULL +character_maximum_length NULL +character_octet_length NULL +character_set_name NULL +collation_name NULL +column_key +extra INVISIBLE +column_comment start +is_generated ALWAYS +generation_expression ROW START +table_catalog def +table_schema test +table_name t1 +column_name Sys_end +ordinal_position 3 +column_default NULL +character_maximum_length NULL +character_octet_length NULL +character_set_name NULL +collation_name NULL +column_key +extra INVISIBLE +column_comment end +is_generated ALWAYS +generation_expression ROW END +# Implicit fields test +create or replace table t1 ( +x2 int unsigned +) with system versioning; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x2` int(10) unsigned DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +create or replace table t1 ( +x3 int unsigned, +Sys_start SYS_DATATYPE as row start invisible, +Sys_end SYS_DATATYPE as row end invisible, +period for system_time (x, Sys_end) +) with system versioning; +ERROR HY000: PERIOD FOR SYSTEM_TIME must use columns `Sys_start` and `Sys_end` +create or replace table t1 ( +x4 int unsigned, +Sys_start SYS_DATATYPE as row start invisible, +Sys_end2 SYS_DATATYPE as row end invisible, +period for system_time (Sys_start, Sys_end) +) with system versioning; +ERROR HY000: PERIOD FOR SYSTEM_TIME must use columns `Sys_start` and `Sys_end2` +create or replace table t1 ( +x5 int unsigned, +Sys_start SYS_DATATYPE as row start invisible, +Sys_end SYS_DATATYPE as row end invisible, +period for system_time (Sys_start, x) +) with system versioning; +ERROR HY000: PERIOD FOR SYSTEM_TIME must use columns `Sys_start` and `Sys_end` +create or replace table t1 ( +x6 int unsigned, +period for system_time (Sys_start, Sys_end) +) with system versioning; +ERROR HY000: Wrong parameters for `t1`: missing 'AS ROW START' +create or replace table t1 ( +x7 int unsigned, +Sys_start SYS_DATATYPE as row start invisible, +Sys_end SYS_DATATYPE as row end invisible, +period for system_time (Sys_start, Sys_end) +); +ERROR HY000: Wrong parameters for `t1`: missing 'WITH SYSTEM VERSIONING' +create or replace table t1 ( +x8 int unsigned, +Sys_start SYS_DATATYPE as row start invisible, +Sys_end SYS_DATATYPE as row end invisible, +period for system_time (sys_insert, sys_remove) +) with system versioning; +ERROR HY000: PERIOD FOR SYSTEM_TIME must use columns `Sys_start` and `Sys_end` +create or replace table t1 ( +x9 int unsigned, +Sys_start SYS_DATATYPE as row start invisible, +Sys_end SYS_DATATYPE as row end invisible, +period for system_time (Sys_start, Sys_end) +); +ERROR HY000: Wrong parameters for `t1`: missing 'WITH SYSTEM VERSIONING' +create or replace table t1 ( +x10 int unsigned, +Sys_start SYS_DATATYPE as row start invisible, +Sys_end SYS_DATATYPE as row end invisible, +period for system_time (Sys_start, Sys_start) +); +ERROR HY000: Wrong parameters for `t1`: missing 'WITH SYSTEM VERSIONING' +create or replace table t1 ( +x11 int unsigned, +Sys_start bigint unsigned as row start invisible, +Sys_end timestamp(6) as row end invisible, +period for system_time (Sys_start, Sys_end) +) with system versioning; +Got one of the listed errors +create or replace table t1 ( +x12 int unsigned, +Sys_start timestamp(6) as row start invisible, +Sys_end bigint unsigned as row end invisible, +period for system_time (Sys_start, Sys_end) +) with system versioning; +Got one of the listed errors +create or replace table t1 ( +x13 int unsigned, +Sys_start bigint as row start invisible, +Sys_end bigint unsigned as row end invisible, +period for system_time (Sys_start, Sys_end) +) with system versioning engine innodb; +ERROR HY000: `Sys_start` must be of type TIMESTAMP(6) for system-versioned table `t1` +create or replace table t1 ( +x14 int unsigned, +Sys_start bigint unsigned as row start invisible, +Sys_end bigint as row end invisible, +period for system_time (Sys_start, Sys_end) +) with system versioning engine innodb; +ERROR HY000: `Sys_end` must be of type BIGINT(20) UNSIGNED for system-versioned table `t1` +create or replace table t1 ( +x15 int with system versioning, +B int +); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x15` int(11) DEFAULT NULL, + `B` int(11) DEFAULT NULL WITHOUT SYSTEM VERSIONING +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +create or replace table t1 ( +x16 int with system versioning, +B int +) with system versioning; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x16` int(11) DEFAULT NULL, + `B` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +create or replace table t1 ( +x17 int, +B int without system versioning +); +create or replace table t1 ( +x18 int, +B int without system versioning +) with system versioning; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x18` int(11) DEFAULT NULL, + `B` int(11) DEFAULT NULL WITHOUT SYSTEM VERSIONING +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +create or replace table t1 ( +x19 int with system versioning, +B int without system versioning +); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x19` int(11) DEFAULT NULL, + `B` int(11) DEFAULT NULL WITHOUT SYSTEM VERSIONING +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +create or replace table t1 ( +x20 int with system versioning, +B int without system versioning +) with system versioning; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x20` int(11) DEFAULT NULL, + `B` int(11) DEFAULT NULL WITHOUT SYSTEM VERSIONING +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +create or replace table t1 ( +x21 int without system versioning +); +create or replace table t1 ( +x22 int without system versioning +) with system versioning; +ERROR HY000: Table `t1` must have at least one versioned column +create or replace table t1 (a int) with system versioning; +create table tt1 like t1; +show create table tt1; +Table Create Table +tt1 CREATE TABLE `tt1` ( + `a` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +drop table tt1; +create temporary table tt1 like t1; +Warnings: +Warning 1105 System versioning is stripped from temporary `test.tt1` +# Temporary is stripped from versioning +show create table tt1; +Table Create Table +tt1 CREATE TEMPORARY TABLE `tt1` ( + `a` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 +# CREATE TABLE ... SELECT +create or replace table t1 (x23 int) with system versioning; +create or replace table t0( +y int, +st SYS_DATATYPE as row start, +en SYS_DATATYPE as row end, +period for system_time (st, en) +) with system versioning; +## For non-versioned table: +### 1. invisible fields are not included +create or replace table t2 as select * from t1; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `x23` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 +### 2. all visible fields are included +create or replace table t3 as select * from t0; +select * from t0; +y st en +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `y` int(11) DEFAULT NULL, + `st` SYS_DATATYPE, + `en` SYS_DATATYPE +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 +## For versioned table +insert into t1 values (1); +select row_start from t1 into @row_start; +insert into t0 (y) values (2); +select st from t0 into @st; +create or replace table t2 with system versioning as select * from t1; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `x23` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +#### invisible fields are not copied +select * from t2; +x23 +1 +select * from t2 where row_start <= @row_start; +x23 +### 2. source table with visible system fields, target with invisible +create or replace table t3 with system versioning as select * from t0; +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `y` int(11) DEFAULT NULL, + `st` SYS_DATATYPE, + `en` SYS_DATATYPE +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +select * from t3 where y > 2; +y st en +select y from t3 where st = @st and row_start > @st; +y +2 +### 3. source and target table with visible system fields +create or replace table t3 ( +st SYS_DATATYPE as row start invisible, +en SYS_DATATYPE as row end invisible, +period for system_time (st, en) +) with system versioning as select * from t0; +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `y` int(11) DEFAULT NULL, + `st` SYS_DATATYPE GENERATED ALWAYS AS ROW START INVISIBLE, + `en` SYS_DATATYPE GENERATED ALWAYS AS ROW END INVISIBLE, + PERIOD FOR SYSTEM_TIME (`st`, `en`) +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +select y from t3; +y +2 +select y from t3 where st = @st; +y +### 4. system fields not or wrongly selected +create or replace table t3 with system versioning select x23 from t1; +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `x23` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +select * from t3; +x23 +1 +create or replace table t3 with system versioning select x23, row_start from t1; +ERROR HY000: Wrong parameters for `t3`: missing 'AS ROW END' +create or replace table t3 with system versioning select x23, row_end from t1; +ERROR HY000: Wrong parameters for `t3`: missing 'AS ROW START' +# Prepare checking for historical row +delete from t1; +select row_end from t1 for system_time all into @row_end; +delete from t0; +select en from t0 for system_time all into @en; +## Combinations of versioned + non-versioned +create or replace table t2 (y int); +insert into t2 values (3); +create or replace table t3 with system versioning select * from t1 for system_time all, t2; +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `x23` int(11) DEFAULT NULL, + `y` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +select * from t3 for system_time all; +x23 y +1 3 +select * from t3 for system_time all where row_start = @row_start and row_end = @row_end; +x23 y +create or replace table t2 like t0; +insert into t2 (y) values (1), (2); +delete from t2 where y = 2; +create or replace table t3 select * from t2 for system_time all; +select st, en from t3 where y = 1 into @st, @en; +select y from t2 for system_time all where st = @st and en = @en; +y +1 +select st, en from t3 where y = 2 into @st, @en; +select y from t2 for system_time all where st = @st and en = @en; +y +2 +## Default engine detection +create or replace table t1 (x25 int) with system versioning engine NON_DEFAULT_ENGINE; +create or replace table t2 +as select x25, row_start, row_end from t1 for system_time all; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `x25` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 +create or replace table t2 with system versioning +as select x25, row_start, row_end from t1; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `x25` int(11) DEFAULT NULL +) ENGINE=NON_DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +create or replace table t1 ( +x26 int, +st bigint unsigned as row start, +en bigint unsigned as row end, +period for system_time (st, en) +) with system versioning engine innodb; +create or replace table t2 with system versioning engine myisam +as select * from t1; +ERROR HY000: `st` must be of type TIMESTAMP(6) for system-versioned table `t2` +create or replace table t1 (x27 int, id int) with system versioning engine NON_DEFAULT_ENGINE; +create or replace table t2 (b int, id int); +create or replace table t3 with system versioning +as select t2.b, t1.x27, t1.row_start, t1.row_end from t2 inner join t1 on t2.id=t1.id; +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `b` int(11) DEFAULT NULL, + `x27` int(11) DEFAULT NULL +) ENGINE=NON_DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +## Errors +create or replace temporary table t (x28 int) with system versioning; +ERROR HY000: System versioning prohibited for TEMPORARY tables +create or replace table t1 ( +x29 int unsigned, +Sys_start0 timestamp(6) as row start invisible, +Sys_start timestamp(6) as row start invisible, +Sys_end timestamp(6) as row end invisible, +period for system_time (Sys_start, Sys_end) +) with system versioning; +ERROR HY000: Duplicate ROW START column `Sys_start` +create or replace table t1 ( +x29 int unsigned, +Sys_end0 timestamp(6) as row end invisible, +Sys_start timestamp(6) as row start invisible, +Sys_end timestamp(6) as row end invisible, +period for system_time (Sys_start, Sys_end) +) with system versioning; +ERROR HY000: Duplicate ROW END column `Sys_end` +## System fields detection +create or replace table t1 (x30 int) with system versioning; +create or replace table t2 ( +y int, +st SYS_DATATYPE as row start invisible, +en SYS_DATATYPE as row end invisible, +period for system_time (st, en) +) with system versioning; +create or replace table t3 +as select x30, y, row_start, row_end, st, en from t1, t2; +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `x30` int(11) DEFAULT NULL, + `y` int(11) DEFAULT NULL, + `st` SYS_DATATYPE NOT NULL INVISIBLE DEFAULT '0000-00-00 00:00:00.000000', + `en` SYS_DATATYPE NOT NULL INVISIBLE DEFAULT '0000-00-00 00:00:00.000000' +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 +create or replace table t3 ( +y int, +st SYS_DATATYPE as row start invisible, +en SYS_DATATYPE as row end invisible, +period for system_time (st, en) +) with system versioning +as select x30, y, row_start, row_end, st, en from t1, t2; +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `x30` int(11) DEFAULT NULL, + `y` int(11) DEFAULT NULL, + `st` SYS_DATATYPE GENERATED ALWAYS AS ROW START INVISIBLE, + `en` SYS_DATATYPE GENERATED ALWAYS AS ROW END INVISIBLE, + PERIOD FOR SYSTEM_TIME (`st`, `en`) +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +# MDEV-14828 Server crashes in JOIN::prepare / setup_fields on 2nd execution of PS [#437] +create or replace table t1 (x int) with system versioning; +prepare bad from 'create or replace table t2 with system versioning as select * from t1'; +execute bad; +execute bad; +execute bad; +execute bad; +execute bad; +execute bad; +execute bad; +execute bad; +# bad is good. +drop database test; +create database test; diff --git a/mysql-test/suite/versioning/r/cte.result b/mysql-test/suite/versioning/r/cte.result new file mode 100644 index 00000000000..fda5e086be2 --- /dev/null +++ b/mysql-test/suite/versioning/r/cte.result @@ -0,0 +1,118 @@ +set default_storage_engine=innodb; +create or replace table dept ( +dept_id int(10) primary key, +name varchar(100) +) +with system versioning; +create or replace table emp ( +emp_id int(10) primary key, +dept_id int(10) not null, +name varchar(100) not null, +mgr int(10), +salary int(10) not null, +constraint `dept-emp-fk` + foreign key (dept_id) references dept (dept_id) +on delete cascade +on update restrict, +constraint `mgr-fk` + foreign key (mgr) references emp (emp_id) +on delete restrict +on update restrict +) +with system versioning; +insert into dept (dept_id, name) values (10, "accounting"); +insert into emp (emp_id, name, salary, dept_id, mgr) values +(1, "bill", 1000, 10, null), +(20, "john", 500, 10, 1), +(30, "jane", 750, 10,1 ); +select max(sys_trx_start) into @ts_1 from emp; +update emp set mgr=30 where name ="john"; +select sys_trx_start into @ts_2 from emp where name="john"; +/* All report to 'Bill' */ +with recursive +ancestors +as +( +select e.emp_id, e.name, e.mgr, e.salary +from emp for system_time as of timestamp @ts_1 as e +where name = 'bill' + union +select e.emp_id, e.name, e.mgr, e.salary +from emp for system_time as of timestamp @ts_1 as e, +ancestors as a +where e.mgr = a.emp_id +) +select * from ancestors; +emp_id name mgr salary +1 bill NULL 1000 +20 john 1 500 +30 jane 1 750 +/* Expected 3 rows */ +with recursive +ancestors +as +( +select e.emp_id, e.name, e.mgr, e.salary +from emp for system_time as of timestamp @ts_2 as e +where name = 'bill' + union +select e.emp_id, e.name, e.mgr, e.salary +from emp for system_time as of timestamp @ts_2 as e, +ancestors as a +where e.mgr = a.emp_id +) +select * from ancestors; +emp_id name mgr salary +1 bill NULL 1000 +30 jane 1 750 +20 john 30 500 +create or replace table emp ( emp_id int, name varchar(127), mgr int) with system versioning; +create or replace table addr ( emp_id int, address varchar(100)) with system versioning; +insert emp values (1, 'bill', 0), (2, 'bill', 1), (3, 'kate', 1); +insert addr values (1, 'Moscow'), (2, 'New York'), (3, 'London'); +set @ts=now(6); +delete from emp; +delete from addr; +with recursive +ancestors +as +( +select e.emp_id, e.name, e.mgr +from emp for system_time as of timestamp @ts as e +where name = 'bill' + union +select ee.emp_id, ee.name, ee.mgr +from emp for system_time as of timestamp @ts as ee, ancestors as a +where ee.mgr = a.emp_id +) +select * from ancestors; +emp_id name mgr +1 bill 0 +2 bill 1 +3 kate 1 +insert emp values (4, 'john', 1); +insert addr values (4, 'Paris'); +with ancestors as (select * from emp natural join addr) select * from ancestors; +emp_id name mgr address +4 john 1 Paris +with ancestors as (select * from emp natural join addr) select * from ancestors for system_time all; +emp_id name mgr address +1 bill 0 Moscow +2 bill 1 New York +3 kate 1 London +4 john 1 Paris +with ancestors as (select * from (select * from emp natural join addr) for system_time all as t) select * from ancestors; +emp_id name mgr address +1 bill 0 Moscow +2 bill 1 New York +3 kate 1 London +4 john 1 Paris +select * from (select * from emp natural join addr) for system_time all as t; +emp_id name mgr address +1 bill 0 Moscow +2 bill 1 New York +3 kate 1 London +4 john 1 Paris +drop table emp; +drop table dept; +drop table addr; diff --git a/mysql-test/suite/versioning/r/ddl.result b/mysql-test/suite/versioning/r/ddl.result new file mode 100644 index 00000000000..a4323b89ee1 --- /dev/null +++ b/mysql-test/suite/versioning/r/ddl.result @@ -0,0 +1,211 @@ +set @@session.time_zone='+00:00'; +select ifnull(max(transaction_id), 0) into @start_trx_id from mysql.transaction_registry; +set @test_start=now(6); +create procedure if not exists verify_vtq() +begin +set @i= 0; +select +@i:= @i + 1 as No, +transaction_id > 0 as A, +commit_id > transaction_id as B, +begin_timestamp > @test_start as C, +commit_timestamp >= begin_timestamp as D +from mysql.transaction_registry +where transaction_id > @start_trx_id; +select ifnull(max(transaction_id), 0) +into @start_trx_id +from mysql.transaction_registry; +end~~ +create function if not exists default_engine() +returns varchar(255) +deterministic +begin +declare e varchar(255); +select lower(engine) from information_schema.engines where support='DEFAULT' into e; +return e; +end~~ +create function if not exists sys_datatype() +returns varchar(255) +deterministic +begin +if default_engine() = 'innodb' then +return 'bigint unsigned'; +elseif default_engine() = 'myisam' then +return 'timestamp(6)'; +end if; +return NULL; +end~~ +create function if not exists sys_commit_ts(sys_field varchar(255)) +returns varchar(255) +deterministic +begin +if default_engine() = 'innodb' then +return concat('vtq_commit_ts(', sys_field, ')'); +elseif default_engine() = 'myisam' then +return sys_field; +end if; +return NULL; +end~~ +create procedure if not exists innodb_verify_vtq(recs int) +begin +declare i int default 1; +if default_engine() = 'innodb' then +call verify_vtq; +elseif default_engine() = 'myisam' then +create temporary table tmp (No int, A bool, B bool, C bool, D bool); +while i <= recs do +insert into tmp values (i, 1, 1, 1, 1); +set i= i + 1; +end while; +select * from tmp; +drop table tmp; +end if; +end~~ +create procedure concat_exec2(a varchar(255), b varchar(255)) +begin +prepare stmt from concat(a, b); +execute stmt; +deallocate prepare stmt; +end~~ +create procedure concat_exec3(a varchar(255), b varchar(255), c varchar(255)) +begin +prepare stmt from concat(a, b, c); +execute stmt; +deallocate prepare stmt; +end~~ +create function get_archive_table_name() +returns varchar(255) +begin +return (select archive_name from t_vtmd for system_time all where archive_name is not NULL +order by start desc limit 1); +end~~ +create procedure drop_last_archive() +begin +call concat_exec2('drop table ', get_archive_table_name()); +end~~ +set versioning_alter_history= survive; +create or replace table t (a int) with system versioning; +insert into t values (1); +update t set a=2 where a=1; +select sys_trx_start from t where a=2 into @tm; +alter table t add column b int; +select * from t; +a b +2 NULL +call concat_exec3('select * from ', get_archive_table_name(), ' for system_time all'); +a +2 +1 +call concat_exec3('select @tm=sys_trx_start from ', get_archive_table_name(), ' for system_time all where a=2'); +@tm=sys_trx_start +1 +select @tm<sys_trx_start from t where a=2; +@tm<sys_trx_start +1 +select sys_trx_start from t where a=2 into @tm; +call concat_exec3('select @tm=sys_trx_end from ', get_archive_table_name(), ' for system_time all where a=2'); +@tm=sys_trx_end +1 +call drop_last_archive(); +set versioning_alter_history= keep; +drop table t_vtmd; +drop table t; +set versioning_alter_history= survive; +create or replace table t (a int) with system versioning; +insert into t values (1); +update t set a=2 where a=1; +select sys_trx_start from t where a=2 into @tm; +alter table t add column b int; +select * from t; +a b +2 NULL +call concat_exec3('select * from ', get_archive_table_name(), ' for system_time all'); +a +2 +1 +call concat_exec3('select @tm=sys_trx_start from ', get_archive_table_name(), ' for system_time all where a=2'); +@tm=sys_trx_start +1 +select @tm<sys_trx_start from t where a=2; +@tm<sys_trx_start +1 +select sys_trx_start from t where a=2 into @tm; +call concat_exec3('select @tm=sys_trx_end from ', get_archive_table_name(), ' for system_time all where a=2'); +@tm=sys_trx_end +1 +call drop_last_archive(); +set versioning_alter_history= keep; +drop table t_vtmd; +drop table t; +set versioning_alter_history= survive; +create or replace table t (a int) with system versioning engine innodb; +insert into t values (1); +update t set a=2 where a=1; +select sys_trx_start from t where a=2 into @tm; +alter table t add column b int; +select * from t; +a b +2 NULL +call concat_exec3('select * from ', get_archive_table_name(), ' for system_time all'); +a +2 +1 +call concat_exec3('select @tm=sys_trx_start from ', get_archive_table_name(), ' for system_time all where a=2'); +@tm=sys_trx_start +1 +select @tm<sys_trx_start from t where a=2; +@tm<sys_trx_start +1 +select sys_trx_start from t where a=2 into @tm; +call concat_exec3('select @tm=sys_trx_end from ', get_archive_table_name(), ' for system_time all where a=2'); +@tm=sys_trx_end +1 +call drop_last_archive(); +set versioning_alter_history= keep; +drop table t_vtmd; +drop table t; +set versioning_alter_history= survive; +create or replace table t (a int) with system versioning engine innodb; +insert into t values (1); +update t set a=2 where a=1; +alter table t add column b int, algorithm=inplace; +set versioning_alter_history = keep; +drop function get_archive_table_name; +drop procedure drop_last_archive; +select * from mysql.vtmd_template; +start end name archive_name col_renames +show create table mysql.vtmd_template; +Table Create Table +vtmd_template CREATE TABLE `vtmd_template` ( + `start` bigint(20) unsigned GENERATED ALWAYS AS ROW START COMMENT 'TRX_ID of table lifetime start', + `end` bigint(20) unsigned GENERATED ALWAYS AS ROW END NOT NULL COMMENT 'TRX_ID of table lifetime end', + `name` varchar(64) COLLATE utf8_bin NOT NULL COMMENT 'Table name during current lifetime period', + `archive_name` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT 'Name of archive table', + `col_renames` blob DEFAULT NULL COMMENT 'Column name mappings from previous lifetime', + PRIMARY KEY (`end`), + KEY `archive_name` (`archive_name`), + PERIOD FOR SYSTEM_TIME (`start`, `end`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin STATS_PERSISTENT=0 WITH SYSTEM VERSIONING +call verify_vtq; +No A B C D +1 1 1 1 1 +2 1 1 1 1 +3 1 1 1 1 +4 1 1 1 1 +5 1 1 1 1 +6 1 1 1 1 +7 1 1 1 1 +8 1 1 1 1 +9 1 1 1 1 +10 1 1 1 1 +11 1 1 1 1 +12 1 1 1 1 +drop table t; +drop table t_vtmd; +drop procedure verify_vtq; +drop procedure innodb_verify_vtq; +drop function default_engine; +drop function sys_commit_ts; +drop function sys_datatype; +drop procedure concat_exec2; +drop procedure concat_exec3; diff --git a/mysql-test/suite/versioning/r/debug.result b/mysql-test/suite/versioning/r/debug.result new file mode 100644 index 00000000000..406717f8b5d --- /dev/null +++ b/mysql-test/suite/versioning/r/debug.result @@ -0,0 +1,54 @@ +create table t1 (a int); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +create temporary table tt1 (a int) with system versioning; +ERROR HY000: System versioning prohibited for TEMPORARY tables +set @old_dbug=@@global.debug_dbug; +set global debug_dbug='+d,sysvers_force'; +create table t2 (a int); +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +create temporary table tt2 (a int) with system versioning; +show create table tt2; +Table Create Table +tt2 CREATE TEMPORARY TABLE `tt2` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +connect con1, localhost, root; +create table t3 (a int); +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +create temporary table tt3 (a int) with system versioning; +show create table tt3; +Table Create Table +tt3 CREATE TEMPORARY TABLE `tt3` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +disconnect con1; +connection default; +set debug_dbug='+d,sysvers_show'; +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +create table t4 (a int); +show create table t4; +Table Create Table +t4 CREATE TABLE `t4` ( + `a` int(11) DEFAULT NULL, + `row_start` timestamp(6) GENERATED ALWAYS AS ROW START, + `row_end` timestamp(6) GENERATED ALWAYS AS ROW END, + PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +set global debug_dbug=@old_dbug; +drop table t1, t2, t3, t4; diff --git a/mysql-test/suite/versioning/r/delete.result b/mysql-test/suite/versioning/r/delete.result new file mode 100644 index 00000000000..79f619fecdd --- /dev/null +++ b/mysql-test/suite/versioning/r/delete.result @@ -0,0 +1,320 @@ +create or replace procedure test_01( +sys_type varchar(255), +engine varchar(255), +fields varchar(255)) +begin +set @str= concat(' + create or replace table t1( + XNo int unsigned, + sys_start ', sys_type, ' as row start invisible, + sys_end ', sys_type, ' as row end invisible, + period for system_time (sys_start, sys_end)) + with system versioning + engine ', engine); +prepare stmt from @str; execute stmt; drop prepare stmt; +insert into t1(XNo) values(0); +insert into t1(XNo) values(1); +insert into t1(XNo) values(2); +insert into t1(XNo) values(3); +insert into t1(XNo) values(4); +insert into t1(XNo) values(5); +insert into t1(XNo) values(6); +insert into t1(XNo) values(7); +insert into t1(XNo) values(8); +insert into t1(XNo) values(9); +set @str= concat('select XNo, ', +fields, " < '2038-01-19 03:14:07' + from t1 for system_time + between timestamp '0000-0-0 0:0:0' + and timestamp '2038-01-19 04:14:07'"); +prepare stmt from @str; execute stmt; +delete from t1 where XNo = 0; +select "Deleted 0"; +execute stmt; +delete from t1 where XNo = 1; +select "Deleted 1"; +execute stmt; +delete from t1 where XNo > 5; +select "Deleted >5"; +create view vt1 as select XNo from t1; +select XNo as XNo_vt1 from vt1; +delete from vt1 where XNo = 3; +select "Deleted from VIEW 3"; +select XNo as XNo_vt1 from vt1; +execute stmt; drop prepare stmt; +drop view vt1; +drop table t1; +end~~ +create or replace procedure test_02( +sys_type varchar(255), +engine varchar(255), +fields varchar(255)) +begin +set @str= concat('create or replace table t1 ( + x int, + sys_start ', sys_type, ' as row start invisible, + sys_end ', sys_type, ' as row end invisible, + period for system_time (sys_start, sys_end)) + with system versioning + engine ', engine); +prepare stmt from @str; execute stmt; drop prepare stmt; +insert into t1(x) values (1); +select sys_start into @sys_start from t1; +delete from t1; +select * from t1; +select x = 1 as A, sys_start = @sys_start as B, sys_end > sys_start as C +from t1 for system_time between timestamp '0-0-0' and timestamp '2038-01-19 04:14:07'; +drop table t1; +end~~ +create or replace procedure test_03( +sys_type varchar(255), +engine varchar(255), +fields varchar(255)) +begin +set @str0= concat('( + x int, + y int, + sys_start ', sys_type, ' as row start invisible, + sys_end ', sys_type, ' as row end invisible, + period for system_time (sys_start, sys_end)) + with system versioning + engine ', engine); +set @str= concat('create or replace table t1', @str0); +prepare stmt from @str; execute stmt; drop prepare stmt; +set @str= concat('create or replace table t2', @str0); +prepare stmt from @str; execute stmt; drop prepare stmt; +insert into t1(x, y) values (1, 1), (2, 2), (3, 3), (14, 4); +insert into t2(x, y) values (11, 1), (12, 2), (13, 32), (14, 4); +delete t1, t2 from t1 join t2 where t1.y = 3 and t2.y = 32; +select x as t1_x from t1; +select x as t2_x from t2; +delete t1, t2 from t1 join t2 where t1.x = t2.x; +select x as t1_x from t1; +select x as t2_x from t2; +select x as t1_x_all from t1 for system_time between timestamp '0-0-0' and timestamp '2038-01-19 04:14:07'; +select x as t2_x_all from t2 for system_time between timestamp '0-0-0' and timestamp '2038-01-19 04:14:07'; +drop table t1; +drop table t2; +end~~ +# Basic + delete from view +call test_01('timestamp(6)', 'myisam', 'sys_end'); +XNo sys_end < '2038-01-19 03:14:07' +0 0 +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +7 0 +8 0 +9 0 +Deleted 0 +Deleted 0 +XNo sys_end < '2038-01-19 03:14:07' +0 1 +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +7 0 +8 0 +9 0 +Deleted 1 +Deleted 1 +XNo sys_end < '2038-01-19 03:14:07' +0 1 +1 1 +2 0 +3 0 +4 0 +5 0 +6 0 +7 0 +8 0 +9 0 +Deleted >5 +Deleted >5 +XNo_vt1 +2 +3 +4 +5 +Deleted from VIEW 3 +Deleted from VIEW 3 +XNo_vt1 +2 +4 +5 +XNo sys_end < '2038-01-19 03:14:07' +0 1 +1 1 +2 0 +3 1 +4 0 +5 0 +6 1 +7 1 +8 1 +9 1 +call test_01('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_end)'); +XNo vtq_commit_ts(sys_end) < '2038-01-19 03:14:07' +0 0 +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +7 0 +8 0 +9 0 +Deleted 0 +Deleted 0 +XNo vtq_commit_ts(sys_end) < '2038-01-19 03:14:07' +0 1 +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +7 0 +8 0 +9 0 +Deleted 1 +Deleted 1 +XNo vtq_commit_ts(sys_end) < '2038-01-19 03:14:07' +0 1 +1 1 +2 0 +3 0 +4 0 +5 0 +6 0 +7 0 +8 0 +9 0 +Deleted >5 +Deleted >5 +XNo_vt1 +2 +3 +4 +5 +Deleted from VIEW 3 +Deleted from VIEW 3 +XNo_vt1 +2 +4 +5 +XNo vtq_commit_ts(sys_end) < '2038-01-19 03:14:07' +0 1 +1 1 +2 0 +3 1 +4 0 +5 0 +6 1 +7 1 +8 1 +9 1 +call verify_vtq; +No A B C D +1 1 1 1 1 +2 1 1 1 1 +3 1 1 1 1 +4 1 1 1 1 +5 1 1 1 1 +6 1 1 1 1 +7 1 1 1 1 +8 1 1 1 1 +9 1 1 1 1 +10 1 1 1 1 +11 1 1 1 1 +12 1 1 1 1 +13 1 1 1 1 +14 1 1 1 1 +# Check sys_start, sys_end +call test_02('timestamp(6)', 'myisam', 'sys_end'); +x +A B C +1 1 1 +call test_02('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_end)'); +x +A B C +1 1 1 +call verify_vtq; +No A B C D +1 1 1 1 1 +2 1 1 1 1 +# Multi-delete +call test_03('timestamp(6)', 'myisam', 'sys_end'); +t1_x +1 +2 +14 +t2_x +11 +12 +14 +t1_x +1 +2 +t2_x +11 +12 +t1_x_all +1 +2 +3 +14 +t2_x_all +11 +12 +13 +14 +call test_03('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_end)'); +t1_x +1 +2 +14 +t2_x +11 +12 +14 +t1_x +1 +2 +t2_x +11 +12 +t1_x_all +1 +2 +3 +14 +t2_x_all +11 +12 +13 +14 +call verify_vtq; +No A B C D +1 1 1 1 1 +2 1 1 1 1 +3 1 1 1 1 +4 1 1 1 1 +# Update + delete +create or replace table t1 (x int) with system versioning; +insert into t1 values (1); +update t1 set x= 2; +delete from t1; +select x from t1 for system_time all; +x +2 +1 +drop database test; +create database test; diff --git a/mysql-test/suite/versioning/r/derived.result b/mysql-test/suite/versioning/r/derived.result new file mode 100644 index 00000000000..cd6cec7e725 --- /dev/null +++ b/mysql-test/suite/versioning/r/derived.result @@ -0,0 +1,295 @@ +create table emp +( +emp_id int, +name varchar(127), +mgr int +) with system versioning; +insert into emp values (1, 'bill', 0), +(2, 'bill', 1), +(3, 'kate', 1); +set @ts=now(6); +delete from emp; +insert into emp values (4, 'john', 1); +with ancestors as (select * from emp) select * from ancestors; +emp_id name mgr +4 john 1 +set @tmp= "with ancestors as (select * from emp) select * from ancestors"; +prepare stmt from @tmp; +execute stmt; +emp_id name mgr +4 john 1 +drop prepare stmt; +with ancestors as (select * from emp for system_time all) select * from ancestors; +emp_id name mgr +1 bill 0 +2 bill 1 +3 kate 1 +4 john 1 +set @tmp= "with ancestors as (select * from emp for system_time all) select * from ancestors"; +prepare stmt from @tmp; +execute stmt; +emp_id name mgr +1 bill 0 +2 bill 1 +3 kate 1 +4 john 1 +drop prepare stmt; +with recursive ancestors as (select * from emp) select * from ancestors; +emp_id name mgr +4 john 1 +set @tmp= "with recursive ancestors as (select * from emp) select * from ancestors"; +prepare stmt from @tmp; +execute stmt; +emp_id name mgr +4 john 1 +drop prepare stmt; +select emp_id from (select emp_id from emp where row_end>'2031-1-1') as tmp; +emp_id +4 +set @tmp= "select emp_id from (select emp_id from emp where row_end>'2031-1-1') as tmp"; +prepare stmt from @tmp; +execute stmt; +emp_id +4 +drop prepare stmt; +with recursive +ancestors +as +( +select e.emp_id, e.name, e.mgr +from emp as e +where name = 'john' + union +select ee.emp_id, ee.name, ee.mgr +from emp as ee, ancestors as a +where ee.mgr = a.emp_id +) +select * from ancestors; +emp_id name mgr +4 john 1 +set @tmp= " +with recursive +ancestors +as +( + select e.emp_id, e.name, e.mgr + from emp as e + where name = 'john' + union + select ee.emp_id, ee.name, ee.mgr + from emp as ee, ancestors as a + where ee.mgr = a.emp_id +) +select * from ancestors"; +prepare stmt from @tmp; +execute stmt; +emp_id name mgr +4 john 1 +drop prepare stmt; +with recursive +ancestors +as +( +select e.emp_id, e.name, e.mgr +from emp for system_time as of timestamp @ts as e +where name = 'bill' + union +select ee.emp_id, ee.name, ee.mgr +from emp for system_time as of timestamp @ts as ee, +ancestors as a +where ee.mgr = a.emp_id +) +select * from ancestors; +emp_id name mgr +1 bill 0 +2 bill 1 +3 kate 1 +set @tmp= " +with recursive +ancestors +as +( + select e.emp_id, e.name, e.mgr + from emp for system_time as of timestamp @ts as e + where name = 'bill' + union + select ee.emp_id, ee.name, ee.mgr + from emp for system_time as of timestamp @ts as ee, + ancestors as a + where ee.mgr = a.emp_id +) +select * from ancestors"; +prepare stmt from @tmp; +execute stmt; +emp_id name mgr +1 bill 0 +2 bill 1 +3 kate 1 +drop prepare stmt; +drop table emp; +create or replace table t1 (x int) with system versioning; +create or replace table t2 (y int) with system versioning; +insert into t1 values (1); +set @t0= now(6); +delete from t1; +insert into t1 values (2); +insert into t2 values (10); +select * from (select *, t1.row_end, t1.row_end as endo from t1) as s0; +x row_end endo +2 # # +select * from (select *, t1.row_end, t2.row_start from t1, t2) as s0; +x y row_end row_start +2 10 # # +# SYSTEM_TIME propagation from inner to outer +select * from (select * from t1 for system_time as of timestamp @t0, t2) as s0; +x y +1 10 +with s1 as (select * from t1 for system_time as of timestamp @t0, t2) select * from s1; +x y +1 10 +# leading table selection +select * from (select *, t1.row_end from t2, t1 for system_time as of timestamp @t0) as s2; +y x row_end +10 1 # +with s3 as (select *, t1.row_end from t2, t1 for system_time as of timestamp @t0) select * from s3; +y x row_end +10 1 # +### VIEW instead of t1 +set @q= concat("create view vt1 as select * from t1 for system_time as of timestamp '", @t0, "'"); +prepare q from @q; +execute q; +drop prepare q; +create view vt2 as select * from t1; +# SYSTEM_TIME propagation from view +select * from vt1; +x +1 +# SYSTEM_TIME propagation from inner to outer +select * from (select * from vt1, t2) as s0; +x y +1 10 +### SYSTEM_TIME clash +select * from (select * from t1 for system_time all) for system_time all as dt0; +ERROR HY000: Table `dt0` is not system-versioned +select * from vt1 for system_time all; +ERROR HY000: Table `vt1` is not system-versioned +with dt1 as (select * from t1 for system_time all) +select * from dt1 for system_time all; +ERROR HY000: Table `dt1` is not system-versioned +### UNION +set @t1= now(6); +delete from t2; +insert into t2 values (3); +# SYSTEM_TIME is not propagated +select x from t1 union +select y from t2; +x +2 +3 +select x from t1 for system_time as of @t0 union +select y from t2; +x +1 +3 +select x from t1 union +select y from t2 for system_time as of @t1; +x +2 +10 +select x from t1 for system_time as of @t0 union +select y from t2 for system_time as of @t1; +x +1 +10 +# LEFT/RIGHT JOIN +create or replace table t1 (x int, y int) with system versioning; +create or replace table t2 (x int, y int) with system versioning; +insert into t1 values (1, 1), (1, 2), (1, 3), (4, 4), (5, 5); +insert into t2 values (1, 2), (2, 1), (3, 1); +## Outer or inner SYSTEM_TIME produces same expression +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join) +Query A: +Note 1003 select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t1` FOR SYSTEM_TIME ALL join `test`.`t2` FOR SYSTEM_TIME ALL where `test`.`t1`.`x` = `test`.`t2`.`x` and `test`.`t1`.`row_end` > <cache>(cast(current_timestamp(6) as datetime(6))) and `test`.`t1`.`row_start` <= <cache>(cast(current_timestamp(6) as datetime(6))) and `test`.`t2`.`row_end` > <cache>(cast(current_timestamp(6) as datetime(6))) and `test`.`t2`.`row_start` <= <cache>(cast(current_timestamp(6) as datetime(6))) +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join) +Query B: +Note 1003 select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t1` FOR SYSTEM_TIME ALL join `test`.`t2` FOR SYSTEM_TIME ALL where `test`.`t1`.`x` = `test`.`t2`.`x` and `test`.`t1`.`row_end` > <cache>(cast(current_timestamp(6) as datetime(6))) and `test`.`t1`.`row_start` <= <cache>(cast(current_timestamp(6) as datetime(6))) and `test`.`t2`.`row_end` > <cache>(cast(current_timestamp(6) as datetime(6))) and `test`.`t2`.`row_start` <= <cache>(cast(current_timestamp(6) as datetime(6))) +Fine result: queries A and B are equal. +## LEFT JOIN: t1, t2 versioned +select * from ( +select t1.x as LJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 +from t1 left join t2 on t1.x = t2.x) +as derived; +LJ1_x1 y1 x2 y2 +1 1 1 2 +1 2 1 2 +1 3 1 2 +4 4 NULL NULL +5 5 NULL NULL +alter table t2 drop system versioning; +## LEFT JOIN: t1 versioned +select * from ( +select t1.x as LJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 +from t1 left join t2 on t1.x = t2.x) +as derived; +LJ2_x1 y1 x2 y2 +1 1 1 2 +1 2 1 2 +1 3 1 2 +4 4 NULL NULL +5 5 NULL NULL +alter table t1 drop system versioning; +alter table t2 add system versioning; +## LEFT JOIN: t2 versioned +select * from ( +select t1.x as LJ3_x1, t1.y as y1, t2.x as x2, t2.y as y2 +from t1 left join t2 on t1.x = t2.x) +as derived; +LJ3_x1 y1 x2 y2 +1 1 1 2 +1 2 1 2 +1 3 1 2 +4 4 NULL NULL +5 5 NULL NULL +alter table t1 add system versioning; +## RIGHT JOIN: t1, t2 versioned +select * from ( +select t1.x as RJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 +from t1 right join t2 on t1.x = t2.x) +as derived; +RJ1_x1 y1 x2 y2 +1 1 1 2 +1 2 1 2 +1 3 1 2 +NULL NULL 2 1 +NULL NULL 3 1 +alter table t2 drop system versioning; +## RIGHT JOIN: t1 versioned +select * from ( +select t1.x as RJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 +from t1 right join t2 on t1.x = t2.x) +as derived; +RJ2_x1 y1 x2 y2 +1 1 1 2 +1 2 1 2 +1 3 1 2 +NULL NULL 2 1 +NULL NULL 3 1 +alter table t1 drop system versioning; +alter table t2 add system versioning; +## RIGHT JOIN: t2 versioned +select * from ( +select t1.x as RJ3_x1, t1.y as y1, t2.x as x2, t2.y as y2 +from t1 right join t2 on t1.x = t2.x) +as derived; +RJ3_x1 y1 x2 y2 +1 1 1 2 +1 2 1 2 +1 3 1 2 +NULL NULL 2 1 +NULL NULL 3 1 +drop table t1, t2; +drop view vt1, vt2; diff --git a/mysql-test/suite/versioning/r/foreign.result b/mysql-test/suite/versioning/r/foreign.result new file mode 100644 index 00000000000..ca2459f784a --- /dev/null +++ b/mysql-test/suite/versioning/r/foreign.result @@ -0,0 +1,232 @@ +################# +# Test RESTRICT # +################# +create table parent( +id int unique key +) engine innodb; +create table child( +parent_id int, +sys_start SYS_DATATYPE as row start invisible, +sys_end SYS_DATATYPE as row end invisible, +period for system_time(sys_start, sys_end), +foreign key(parent_id) references parent(id) +on delete restrict +on update restrict +) engine innodb with system versioning; +insert into parent values(1); +insert into child values(1); +delete from parent where id = 1; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) +delete from child where parent_id = 1; +delete from parent where id = 1; +insert into parent values(1); +insert into child values(1); +update parent set id=id+1; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) +delete from child; +update parent set id=id+1; +select * from child for system_time from timestamp '1-1-1' to timestamp now(6); +parent_id +1 +1 +drop table child; +drop table parent; +############################################## +# Test when clustered index is a foreign key # +############################################## +create table parent( +id int(10) unsigned unique key +) engine innodb; +create table child( +parent_id int(10) unsigned primary key, +sys_start SYS_DATATYPE as row start invisible, +sys_end SYS_DATATYPE as row end invisible, +period for system_time(sys_start, sys_end), +foreign key(parent_id) references parent(id) +) engine innodb with system versioning; +insert into parent values(1); +insert into child values(1); +delete from parent where id = 1; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) +drop table child; +drop table parent; +################ +# Test CASCADE # +################ +create table parent( +id int unique key +) engine innodb; +create table child( +parent_id int, +sys_start SYS_DATATYPE as row start invisible, +sys_end SYS_DATATYPE as row end invisible, +period for system_time(sys_start, sys_end), +foreign key(parent_id) references parent(id) +on delete cascade +on update cascade +) engine innodb with system versioning; +insert into parent values(1); +insert into child values(1); +## FIXME: #415 update of foreign constraints is disabled +call mtr.add_suppression("foreign key constraints in timestamp-based temporal table"); +delete from parent where id = 1; +ERROR 42000: Table 'parent' uses an extension that doesn't exist in this MariaDB version +delete from child where parent_id = 1; +## FIXME END +delete from parent where id = 1; +select * from child; +parent_id +select * from child for system_time all; +parent_id +1 +insert into parent values(1); +insert into child values(1); +update parent set id = id + 1; +select * from child; +parent_id +2 +select * from child for system_time all; +parent_id +1 +2 +drop table child; +drop table parent; +create or replace table parent ( +id int primary key, +sys_start SYS_DATATYPE as row start invisible, +sys_end SYS_DATATYPE as row end invisible, +period for system_time(sys_start, sys_end) +) with system versioning +engine innodb; +create or replace table child ( +x int, +parent_id int not null, +constraint `parent-fk` + foreign key (parent_id) references parent (id) +on delete cascade +on update restrict +) +engine innodb; +insert into parent (id) values (2); +insert into child (x, parent_id) values (2, 2); +delete from parent; +select * from child; +x parent_id +drop table child; +drop table parent; +create or replace table parent ( +id int primary key +) +engine innodb; +create or replace table child ( +id int primary key, +parent_id int not null, +constraint `parent-fk` + foreign key (parent_id) references parent (id) +on delete cascade +on update restrict +) with system versioning +engine innodb; +insert into parent (id) values (3); +insert into child (id, parent_id) values (3, 3); +## FIXME: #415 update of foreign constraints is disabled +delete from child; +## FIXME END +delete from parent; +select * from child; +id parent_id +select * from child for system_time all; +id parent_id +3 3 +drop table child; +drop table parent; +################# +# Test SET NULL # +################# +create table parent( +id int unique key +) engine innodb; +create table child( +parent_id int, +sys_start SYS_DATATYPE as row start invisible, +sys_end SYS_DATATYPE as row end invisible, +period for system_time(sys_start, sys_end), +foreign key(parent_id) references parent(id) +on delete set null +on update set null +) engine innodb with system versioning; +insert into parent values(1); +insert into child values(1); +delete from child; +insert into child values(1); +## FIXME: #415 update of foreign constraints is disabled +delete from child where parent_id = 1; +## FIXME END +delete from parent where id = 1; +select * from child; +parent_id +select * from child for system_time from timestamp '1-1-1' to timestamp now(6); +parent_id +1 +1 +delete from child; +insert into parent values(1); +insert into child values(1); +drop table child; +drop table parent; +########################### +# Parent table is foreign # +########################### +create or replace table parent( +id int unique key, +sys_start SYS_DATATYPE as row start invisible, +sys_end SYS_DATATYPE as row end invisible, +period for system_time(sys_start, sys_end) +) engine innodb with system versioning; +create or replace table child( +parent_id int, +foreign key(parent_id) references parent(id) +) engine innodb; +insert into parent values(1); +insert into child values(1); +delete from parent; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) +update parent set id=2; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) +delete from child; +delete from parent; +insert into child values(1); +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) +insert into parent values(1); +insert into child values(1); +delete from parent; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) +update parent set id=2; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) +drop table child; +drop table parent; +################### +# crash on DELETE # +################### +create or replace table a ( +cola int(10) primary key, +v_cola int(10) as (cola mod 10) virtual, +sys_start SYS_DATATYPE as row start invisible, +sys_end SYS_DATATYPE as row end invisible, +period for system_time(sys_start, sys_end) +) engine=innodb with system versioning; +create index v_cola on a (v_cola); +create or replace table b( +cola int(10), +v_cola int(10), +sys_start SYS_DATATYPE as row start invisible, +sys_end SYS_DATATYPE as row end invisible, +period for system_time(sys_start, sys_end) +) engine=innodb with system versioning; +alter table b add constraint `v_cola_fk` +foreign key (v_cola) references a (v_cola); +insert into a(cola) values (12); +insert into b(cola, v_cola) values (10,2); +delete from a; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`b`, CONSTRAINT `v_cola_fk` FOREIGN KEY (`v_cola`) REFERENCES `a` (`v_cola`)) +drop table b, a; diff --git a/mysql-test/suite/versioning/r/insert.result b/mysql-test/suite/versioning/r/insert.result new file mode 100644 index 00000000000..0c9718c106b --- /dev/null +++ b/mysql-test/suite/versioning/r/insert.result @@ -0,0 +1,368 @@ +create procedure test_01( +sys_type varchar(255), +engine varchar(255), +fields varchar(255)) +begin +set @str= concat(' + create table t1( + x int unsigned, + y int unsigned, + sys_start ', sys_type, ' as row start invisible, + sys_end ', sys_type, ' as row end invisible, + period for system_time (sys_start, sys_end)) + with system versioning + engine ', engine); +prepare stmt from @str; execute stmt; drop prepare stmt; +insert into t1(x, y) values(3, 4); +insert delayed into t1(x, y) values(2, 3); +insert into t1 values(40, 33); +set @str= concat('select x, y, ', fields, ' from t1'); +prepare stmt from @str; execute stmt; drop prepare stmt; +drop table t1; +end~~ +create procedure test_02( +sys_type varchar(255), +engine varchar(255), +fields varchar(255)) +begin +set @str= concat(' + create table t1( + id int unsigned auto_increment primary key, + x int unsigned, + y int unsigned, + sys_start ', sys_type, ' as row start invisible, + sys_end ', sys_type, ' as row end invisible, + period for system_time (sys_start, sys_end)) + with system versioning + engine ', engine); +prepare stmt from @str; execute stmt; drop prepare stmt; +insert into t1(x, y) values(33, 44); +insert into t1(id, x, y) values(20, 33, 44); +insert into t1 values(40, 33, 44); +set @str= concat('select id, x, y, ', fields, ' from t1'); +prepare stmt from @str; execute stmt; drop prepare stmt; +drop table t1; +end~~ +create procedure test_03( +sys_type varchar(255), +engine varchar(255), +fields varchar(255)) +begin +set @str= concat(' + create table t1( + x int unsigned, + y int unsigned, + sys_start ', sys_type, ' as row start invisible, + sys_end ', sys_type, ' as row end invisible, + period for system_time (sys_start, sys_end)) + with system versioning + engine ', engine); +prepare stmt from @str; execute stmt; drop prepare stmt; +create view vt1_1 as select x, y from t1; +insert into t1(x, y) values(8001, 9001); +insert into vt1_1(x, y) values(1001, 2001); +insert into vt1_1 values(1002, 2002); +set @str= concat('select x, y, ', fields, ' from t1'); +prepare stmt from @str; execute stmt; drop prepare stmt; +select x, y from vt1_1; +end~~ +create procedure test_04( +sys_type varchar(255), +engine varchar(255), +fields varchar(255)) +begin +set @str= concat(' + create table t1( + id bigint primary key, + a int, + b int) + with system versioning + engine ', engine); +prepare stmt from @str; execute stmt; drop prepare stmt; +insert into t1 values(1, 1, 1); +select row_start, row_end from t1 into @sys_start, @sys_end; +select id, a, b from t1; +insert into t1 values(2, 2, 2); +select id, a, b, row_start > @sys_start as C, row_end = @sys_end as D from t1 where id = 2; +drop table t1; +end~~ +create procedure test_05( +sys_type varchar(255), +engine varchar(255), +fields varchar(255)) +begin +set @str= concat('( + x int unsigned, + y int unsigned, + sys_start ', sys_type, ' as row start invisible, + sys_end ', sys_type, ' as row end invisible, + period for system_time (sys_start, sys_end)) + with system versioning + engine ', engine); +set @str2= concat('create table t1', @str); +prepare stmt from @str2; execute stmt; drop prepare stmt; +set @str2= concat('create table t2', @str); +prepare stmt from @str2; execute stmt; drop prepare stmt; +insert into t1(x, y) values +(1, 1000), +(2, 2000), +(3, 3000), +(4, 4000), +(5, 5000), +(6, 6000), +(7, 7000), +(8, 8000), +(9, 9000); +delete from t1 where x >= 1; +insert into t1(x, y) values +(1, 1001), +(2, 2001), +(3, 3001), +(4, 4001), +(5, 5001), +(6, 6001); +insert into t1(x, y, sys_start) values +(7, 7001, DEFAULT); +insert into t1(x, y, sys_end) values +(8, 8001, DEFAULT); +insert into t1(x, y, sys_start, sys_end) values +(9, 9001, DEFAULT, DEFAULT); +insert into t2 select x, y from t1 for system_time between timestamp '0000-0-0 0:0:0' and timestamp '9999-1-1 0:0:0'; +select x, y from t1; +select x, y from t2; +drop table t1; +drop table t2; +end~~ +call test_01('timestamp(6)', 'myisam', 'sys_end'); +x y sys_end +3 4 2038-01-19 03:14:07.999999 +2 3 2038-01-19 03:14:07.999999 +40 33 2038-01-19 03:14:07.999999 +call test_01('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_end)'); +x y vtq_commit_ts(sys_end) +3 4 2038-01-19 03:14:07.999999 +2 3 2038-01-19 03:14:07.999999 +40 33 2038-01-19 03:14:07.999999 +call test_02('timestamp(6)', 'myisam', 'sys_end'); +id x y sys_end +1 33 44 2038-01-19 03:14:07.999999 +20 33 44 2038-01-19 03:14:07.999999 +40 33 44 2038-01-19 03:14:07.999999 +call test_02('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_end)'); +id x y vtq_commit_ts(sys_end) +1 33 44 2038-01-19 03:14:07.999999 +20 33 44 2038-01-19 03:14:07.999999 +40 33 44 2038-01-19 03:14:07.999999 +call test_03('timestamp(6)', 'myisam', 'sys_end'); +x y sys_end +8001 9001 2038-01-19 03:14:07.999999 +1001 2001 2038-01-19 03:14:07.999999 +1002 2002 2038-01-19 03:14:07.999999 +x y +8001 9001 +1001 2001 +1002 2002 +drop table t1; +drop view vt1_1; +call test_03('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_end)'); +x y vtq_commit_ts(sys_end) +8001 9001 2038-01-19 03:14:07.999999 +1001 2001 2038-01-19 03:14:07.999999 +1002 2002 2038-01-19 03:14:07.999999 +x y +8001 9001 +1001 2001 +1002 2002 +drop table t1; +drop view vt1_1; +call test_04('timestamp(6)', 'myisam', 'sys_end'); +id a b +1 1 1 +id a b C D +2 2 2 1 1 +call test_04('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_end)'); +id a b +1 1 1 +id a b C D +2 2 2 1 1 +call test_05('timestamp(6)', 'myisam', 'sys_end'); +x y +1 1001 +2 2001 +3 3001 +4 4001 +5 5001 +6 6001 +7 7001 +8 8001 +9 9001 +x y +1 1000 +2 2000 +3 3000 +4 4000 +5 5000 +6 6000 +7 7000 +8 8000 +9 9000 +1 1001 +2 2001 +3 3001 +4 4001 +5 5001 +6 6001 +7 7001 +8 8001 +9 9001 +call test_05('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_end)'); +x y +1 1001 +2 2001 +3 3001 +4 4001 +5 5001 +6 6001 +7 7001 +8 8001 +9 9001 +x y +1 1000 +2 2000 +3 3000 +4 4000 +5 5000 +6 6000 +7 7000 +8 8000 +9 9000 +1 1001 +2 2001 +3 3001 +4 4001 +5 5001 +6 6001 +7 7001 +8 8001 +9 9001 +call verify_vtq; +No A B C D +1 1 1 1 1 +2 1 1 1 1 +3 1 1 1 1 +4 1 1 1 1 +5 1 1 1 1 +6 1 1 1 1 +7 1 1 1 1 +8 1 1 1 1 +9 1 1 1 1 +10 1 1 1 1 +11 1 1 1 1 +12 1 1 1 1 +13 1 1 1 1 +14 1 1 1 1 +15 1 1 1 1 +16 1 1 1 1 +create table t1( +x int unsigned, +sys_start bigint unsigned as row start invisible, +sys_end bigint unsigned as row end invisible, +period for system_time (sys_start, sys_end)) +with system versioning engine=innodb; +create table t2(x int unsigned) engine=innodb; +start transaction; +insert into t1(x) values(1); +commit; +call verify_vtq; +No A B C D +1 1 1 1 1 +start transaction; +insert into t2(x) values(1); +savepoint a; +insert into t1(x) values(1); +rollback to a; +commit; +call verify_vtq; +No A B C D +insert into t2(x) values (1); +create or replace table t1 ( +x int, +y int as (x) virtual, +sys_trx_start bigint unsigned as row start invisible, +sys_trx_end bigint unsigned as row end invisible, +period for system_time (sys_trx_start, sys_trx_end) +) engine=innodb with system versioning; +insert into t1 values (1, null); +update t1 set x= x + 1; +select x, y, sys_trx_end = 18446744073709551615 as current from t1 for system_time all; +x y current +2 2 1 +1 1 0 +create or replace table t1 (x int) with system versioning engine innodb; +insert into t1 values (1), (2); +insert into t1 (row_start) select row_end from t1; +ERROR HY000: The value specified for generated column 'row_start' in table 't1' ignored +set sql_mode=''; +insert into t1 (row_start, row_end) values (DEFAULT, 1); +Warnings: +Warning 1906 The value specified for generated column 'row_end' in table 't1' ignored +set sql_mode=default; +select @@sql_mode into @saved_mode; +set sql_mode= ''; +insert into t1 (x, row_start, row_end) values (3, 4, 5); +Warnings: +Warning 1906 The value specified for generated column 'row_start' in table 't1' ignored +Warning 1906 The value specified for generated column 'row_end' in table 't1' ignored +set sql_mode= @saved_mode; +insert into t1 (row_start, row_end) values (DEFAULT, DEFAULT); +select * from t1; +x +1 +2 +NULL +3 +NULL +# MDEV-14792 INSERT without column list into table with explicit versioning columns produces bad data +create or replace table t1 ( +i int, +s timestamp(6) as row start, +e timestamp(6) as row end, +c varchar(8), +period for system_time(s, e)) +with system versioning; +insert into t1 values (1, null, null, 'foo'); +select i, c, current_row(e) from t1; +i c current_row(e) +1 foo 1 +drop table t1; +drop table t2; +drop procedure test_01; +drop procedure test_02; +drop procedure test_03; +drop procedure test_04; +drop procedure test_05; +set timestamp=1000000019; +select now() < sysdate(); +now() < sysdate() +1 +create table t1 (a int) with system versioning; +insert t1 values (1); +set @a=sysdate(6); +select * from t1 for system_time as of now(6); +a +select * from t1 for system_time as of sysdate(6); +a +1 +update t1 set a=2; +delete from t1; +select *, row_start > @a, row_end > @a from t1 for system_time all; +a row_start > @a row_end > @a +1 0 1 +2 1 1 +# +# MDEV-14871 Server crashes in fill_record / fill_record_n_invoke_before_triggers upon inserting into versioned table with trigger +# +create or replace table t1 (pk int primary key) with system versioning; +create trigger tr before insert on t1 for each row select 1 into @a; +insert into t1 values (1),(2); +drop table t1; diff --git a/mysql-test/suite/versioning/r/online.result b/mysql-test/suite/versioning/r/online.result new file mode 100644 index 00000000000..b2a34481d63 --- /dev/null +++ b/mysql-test/suite/versioning/r/online.result @@ -0,0 +1,34 @@ +set system_versioning_alter_history=keep; +create or replace table t (a int, b int) engine=innodb; +alter table t add system versioning, lock=none; +ERROR 0A000: LOCK=NONE is not supported. Reason: Not implemented for system-versioned tables. Try LOCK=SHARED +alter table t add system versioning, lock=shared; +alter table t drop column b, lock=none; +ERROR 0A000: LOCK=NONE is not supported. Reason: Not implemented for system-versioned tables. Try LOCK=SHARED +alter table t drop column b, algorithm=inplace; +ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Not implemented for system-versioned tables. Try ALGORITHM=COPY +alter table t add index idx(a), lock=none; +alter table t drop system versioning, lock=none; +ERROR 0A000: LOCK=NONE is not supported. Reason: Not implemented for system-versioned tables. Try LOCK=SHARED +alter table t drop system versioning, algorithm=inplace; +ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Not implemented for system-versioned tables. Try ALGORITHM=COPY +create or replace table t (a int, b int) engine=innodb; +alter table t +add s bigint unsigned as row start, +add e bigint unsigned as row end, +add period for system_time(s, e), +add system versioning, +lock=none; +ERROR 0A000: LOCK=NONE is not supported. Reason: Not implemented for system-versioned tables. Try LOCK=SHARED +alter table t +add s bigint unsigned as row start, +add e bigint unsigned as row end, +add period for system_time(s, e), +add system versioning; +alter table t drop column b, lock=none; +ERROR 0A000: LOCK=NONE is not supported. Reason: Not implemented for system-versioned tables. Try LOCK=SHARED +alter table t add index idx(a), lock=none; +alter table t drop column s, drop column e; +alter table t drop system versioning, lock=none; +ERROR 0A000: LOCK=NONE is not supported. Reason: Not implemented for system-versioned tables. Try LOCK=SHARED +drop table t; diff --git a/mysql-test/suite/versioning/r/optimized.result b/mysql-test/suite/versioning/r/optimized.result new file mode 100644 index 00000000000..443d0401771 --- /dev/null +++ b/mysql-test/suite/versioning/r/optimized.result @@ -0,0 +1,97 @@ +create table t ( +a int, +b int without system versioning +) with system versioning; +insert into t values(1, 2); +insert into t values(3, 4); +select * from t; +a b +1 2 +3 4 +select a from t for system_time as of timestamp now(6); +a +1 +3 +select a, b, b+0 from t for system_time as of timestamp now(6); +a b b+0 +1 2 2 +3 4 4 +Warnings: +Note 4110 Non-versioned field `b` in historical query +Note 4110 Non-versioned field `b` in historical query +select * from t for system_time as of timestamp now(6); +a b +1 2 +3 4 +Warnings: +Note 4110 Non-versioned field `b` in historical query +select count(*) from t for system_time as of timestamp now(6) group by b; +count(*) +1 +1 +Warnings: +Note 4110 Non-versioned field `b` in historical query +select * from t for system_time as of timestamp now(6) order by b asc; +a b +1 2 +3 4 +Warnings: +Note 4110 Non-versioned field `b` in historical query +Note 4110 Non-versioned field `b` in historical query +select * from t for system_time as of timestamp now(6) order by b desc; +a b +3 4 +1 2 +Warnings: +Note 4110 Non-versioned field `b` in historical query +Note 4110 Non-versioned field `b` in historical query +select * from t for system_time as of timestamp now(6) group by a having a=2; +a b +Warnings: +Note 4110 Non-versioned field `b` in historical query +select * from t for system_time as of timestamp now(6) group by b having b=2; +a b +1 2 +Warnings: +Note 4110 Non-versioned field `b` in historical query +Note 4110 Non-versioned field `b` in historical query +Note 4110 Non-versioned field `b` in historical query +select a from t for system_time as of timestamp now(6) where b=2; +a +1 +Warnings: +Note 4110 Non-versioned field `b` in historical query +select a from t for system_time as of timestamp now(6) where b=NULL; +a +Warnings: +Note 4110 Non-versioned field `b` in historical query +select a from t for system_time as of timestamp now(6) where b is NULL; +a +Warnings: +Note 4110 Non-versioned field `b` in historical query +select count(*), b from t for system_time as of timestamp now(6) group by b having b=NULL; +count(*) b +Warnings: +Note 4110 Non-versioned field `b` in historical query +Note 4110 Non-versioned field `b` in historical query +Note 4110 Non-versioned field `b` in historical query +select a, b from t; +a b +1 2 +3 4 +create or replace table t ( +a int, +b int not null without system versioning +) with system versioning; +insert into t values (1, 2), (3, 4); +select * from t for system_time as of timestamp now(6); +a b +1 2 +3 4 +Warnings: +Note 4110 Non-versioned field `b` in historical query +select * from t for system_time as of timestamp now(6) where b is NULL; +a b +Warnings: +Note 4110 Non-versioned field `b` in historical query +drop table t; diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result new file mode 100644 index 00000000000..2b275538fb9 --- /dev/null +++ b/mysql-test/suite/versioning/r/partition.result @@ -0,0 +1,420 @@ +# Check conventional partitioning on temporal tables +create table t1 (x int) +with system versioning +partition by range columns (x) ( +partition p0 values less than (100), +partition p1 values less than (1000)); +insert into t1 values (3), (300); +select * from t1; +x +3 +300 +select * from t1 partition (p0); +x +3 +select * from t1 partition (p1); +x +300 +delete from t1; +select * from t1; +x +select * from t1 partition (p0); +x +select * from t1 partition (p1); +x +select * from t1 for system_time all; +x +3 +300 +select * from t1 partition (p0) for system_time all; +x +3 +select * from t1 partition (p1) for system_time all; +x +300 +# Engine change native <-> non-native versioning prohibited +create or replace table t1 (i int) engine=DEFAULT_ENGINE with system versioning partition by hash(i); +alter table t1 engine=NON_DEFAULT_ENGINE; +ERROR HY000: Not allowed for system-versioned `test`.`t1`. Change to/from native system versioning engine is prohibited. +## CREATE TABLE +create or replace table t1 (x int) +partition by system_time ( +partition p0 history, +partition pn current); +ERROR HY000: Transaction system versioning for `t1` is not supported +create or replace table t1 (x int); +alter table t1 +partition by system_time ( +partition p0 history, +partition pn current); +Got one of the listed errors +create or replace table t1 (x int) +with system versioning +partition by system_time ( +partition p0 current); +ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT +create or replace table t1 (x int) +with system versioning +partition by system_time ( +partition p0 current, +partition p1 current); +ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT +create or replace table t1 (x int) +with system versioning +partition by system_time ( +partition p0 history, +partition p1 history); +ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT +create or replace table t1 (x int) +with system versioning +partition by system_time ( +partition pn current, +partition p0 history); +ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT +create or replace table t1 (x int) +with system versioning +partition by system_time ( +partition p0, +partition pn current); +ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT +create or replace table t1 (x int) +with system versioning +partition by system_time ( +partition p0 history, +partition pn current); +## ALTER TABLE +alter table t1 add partition ( +partition p1 current); +ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT +alter table t1 add partition ( +partition p1 history); +Warnings: +Warning 4113 Maybe missing parameters: no rotation condition for multiple HISTORY partitions. +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING + PARTITION BY SYSTEM_TIME +(PARTITION `p0` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE) +insert into t1 values (1), (2); +alter table t1 drop partition pn; +ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT +alter table t1 drop partition p1; +alter table t1 drop partition p0; +ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT +select x from t1; +x +1 +2 +# Bug #260: incorrect IB partitioning warning +create or replace table t1 (x int) +with system versioning +partition by system_time limit 1 ( +partition p0 history, +partition pn current); +alter table t1 change x big int; +create or replace table t1 (i int) engine myisam partition by hash(i) partitions 2; +alter table t1 add partition (partition px history); +ERROR HY000: Wrong partitioning type, expected type: `SYSTEM_TIME` +## INSERT, UPDATE, DELETE +create or replace table t1 (x int) +with system versioning +partition by system_time ( +partition p0 history, +partition pn current); +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)'); +prepare select_pn from @str; +execute select_p0; +x A B +execute select_pn; +x C D +1 1 1 +## pruning check +explain partitions select * from tN; +id select_type table partitions type possible_keys key key_len ref rows Extra +N SIMPLE tN pN,pn system NULL NULL NULL NULL N +set @str= concat('select row_start from t1 partition (pn) into @ts0'); +prepare stmt from @str; +execute stmt; +drop prepare stmt; +set @now= now(6); +delete from t1; +execute select_p0; +x A B +1 1 1 +execute select_pn; +x C D +set @str= concat('select row_start from t1 partition (p0) into @ts1'); +prepare stmt from @str; +execute stmt; +drop prepare stmt; +select @ts0 = @ts1; +@ts0 = @ts1 +1 +set @now= now(6); +insert into t1 values (2); +execute select_p0; +x A B +1 1 0 +execute select_pn; +x C D +2 1 1 +set @str= concat('select row_start from t1 partition (pn) into @ts0'); +prepare stmt from @str; +execute stmt; +drop prepare stmt; +set @now= now(6); +update t1 set x = x + 1; +execute select_p0; +x A B +1 1 0 +2 1 1 +execute select_pn; +x C D +3 1 1 +drop prepare select_p0; +drop prepare select_pn; +set @str= concat('select row_start from t1 partition (p0) where x = 2 into @ts1'); +prepare stmt from @str; +execute stmt; +drop prepare stmt; +set @str= concat('select row_end from t1 partition (p0) where x = 2 into @ts2'); +prepare stmt from @str; +execute stmt; +drop prepare stmt; +set @str= concat('select row_start from t1 partition (pn) into @ts3'); +prepare stmt from @str; +execute stmt; +drop prepare stmt; +select @ts0 = @ts1; +@ts0 = @ts1 +1 +select @ts2 = @ts3; +@ts2 = @ts3 +1 +## rotation by LIMIT +create or replace table t1 (x int) +with system versioning +partition by system_time limit 0 ( +partition p0 history, +partition p1 history, +partition pn current); +ERROR HY000: Wrong parameters for partitioned `t1`: wrong value for 'LIMIT' +create or replace table t1 (x int) +with system versioning +partition by system_time limit 2 ( +partition p0 history, +partition p1 history, +partition pn current); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING + PARTITION BY SYSTEM_TIME LIMIT 2 +(PARTITION `p0` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE) +alter table t1 drop partition non_existent; +ERROR HY000: Error in list of partitions to DROP +insert into t1 values (1), (2), (3); +select * from t1 partition (pn); +x +1 +2 +3 +### warn about partition switching +delete from t1; +Warnings: +Note 4114 Versioned table `test`.`t1`: switching from partition `p0` to `p1` +select * from t1 partition (p0); +x +1 +2 +select * from t1 partition (p1); +x +3 +insert into t1 values (4), (5); +### warn about full partition +delete from t1; +Warnings: +Warning 4112 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions +select * from t1 partition (p1) order by x; +x +3 +4 +5 +### Assertion in ALTER on warning from partitioning LIMIT [#446] +create or replace table t1 (x int) with system versioning; +insert into t1 values (1), (2); +delete from t1; +alter table t1 partition by system_time limit 1 ( +partition p1 history, +partition pn current); +Warnings: +Note 4112 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions +## rotation by INTERVAL +create or replace table t1 (x int) +with system versioning +partition by system_time interval 0 second ( +partition p0 history, +partition p1 history, +partition pn current); +ERROR HY000: Wrong parameters for partitioned `t1`: wrong value for 'INTERVAL' +create or replace table t1 (x int) +with system versioning +partition by system_time interval 1 second ( +partition p0 history, +partition p1 history, +partition pn current); +insert into t1 values (1), (2), (3); +select * from t1 partition (pn); +x +1 +2 +3 +delete from t1; +select * from t1 partition (p0); +x +1 +2 +3 +insert into t1 values (4); +delete from t1; +Warnings: +Note 4114 Versioned table `test`.`t1`: switching from partition `p0` to `p1` +select * from t1 partition (p1); +x +4 +## Subpartitions +create or replace table t1 (x int) +with system versioning +partition by system_time limit 2 +subpartition by key (x) +subpartitions 2 ( +partition p0 history, +partition p1 history, +partition pn current); +insert into t1 (x) values (1), (2), (3), (4), (5); +select * from t1 partition (pnsp0); +x +1 +3 +5 +select * from t1 partition (pnsp1); +x +2 +4 +### warn about partition switching and about full partition +delete from t1; +Warnings: +Note 4114 Versioned table `test`.`t1`: switching from partition `p0` to `p1` +Warning 4112 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions +select * from t1 partition (p0sp0); +x +1 +3 +select * from t1 partition (p0sp1); +x +select * from t1 partition (p1sp0); +x +5 +select * from t1 partition (p1sp1); +x +2 +4 +create or replace table t1 (a bigint) +with system versioning +partition by range (a) +(partition p0 values less than (20) engine innodb, +partition p1 values less than maxvalue engine innodb); +insert into t1 values (1); +create or replace table t1 ( +f_int1 integer default 0 +) with system versioning +partition by range(f_int1) +subpartition by hash(f_int1) +( partition part1 values less than (1000) +(subpartition subpart11 storage engine = 'innodb', +subpartition subpart12 storage engine = 'innodb')); +insert into t1 values (1); +create or replace table t1 (i int) engine=innodb partition by key(i); +alter table t1 add system versioning; +insert into t1 values(); +# MDEV-14722 Assertion in ha_commit_trans for sub-statement +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 day ( +partition p1 history, +partition pc current); +create or replace table t2 (f int); +create or replace trigger tr before insert on t2 +for each row select table_rows from information_schema.tables +where table_name = 't1' into @a; +insert into t2 values (1); +# MDEV-14740 Locking assertion for system_time partitioning +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 week ( +partition p1 history, +partition pn current); +create or replace table t2 (f int); +create or replace trigger tr before insert on t2 +for each row select count(*) from t1 into @a; +insert into t2 values (1); +# MDEV-14741 Assertion `(trx)->start_file == 0' failed in row_truncate_table_for_mysql() +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 hour ( +partition p1 history, +partition pn current); +set autocommit= off; +truncate table t1; +set autocommit= on; +# MDEV-14747 ALTER PARTITION BY SYSTEM_TIME after LOCK TABLES +create or replace table t1 (x int) with system versioning; +lock table t1 write; +alter table t1 partition by system_time interval 1 week ( +partition p1 history, +partition pn current); +unlock tables; +# MDEV-14748 Assertion in ha_myisammrg::attach_children() +create or replace table t1 (x int) engine=myisam with system versioning +partition by system_time interval 1 month (partition p1 history, partition pn current); +create or replace table t2 (x int) engine=myisam; +create or replace table t3 (x int) engine=merge union=(t2); +create or replace table t4 (x int) engine=myisam; +create or replace trigger tr after insert on t4 for each row insert into t2 +( select x from t3 ) union ( select x from t1 ); +insert into t4 values (1); +# MDEV-14821 Assertion failure +create or replace table t1 (x int) with system versioning; +insert into t1 values (0), (1); +update t1 set x= x + 1; +alter table t1 partition by system_time limit 1 ( +partition p1 history, +partition p2 history, +partition pn current); +Warnings: +Note 4114 Versioned table `test`.`t1`: switching from partition `p1` to `p2` +delete from t1 where x = 1; +Warnings: +Warning 4112 Versioned table `test`.`t1`: partition `p2` is full, add more HISTORY partitions +delete from t1 where x = 2; +Warnings: +Warning 4112 Versioned table `test`.`t1`: partition `p2` is full, add more HISTORY partitions +# MDEV-14923 Assertion upon INSERT into locked versioned partitioned table +create or replace table t1 (x int) with system versioning +partition by system_time (partition p1 history, partition pn current); +lock table t1 write; +alter table t1 add partition (partition p1 history); +ERROR HY000: Duplicate partition name p1 +insert into t1 values (1); +unlock tables; +# Test cleanup +drop database test; +create database test; diff --git a/mysql-test/suite/versioning/r/replace.result b/mysql-test/suite/versioning/r/replace.result new file mode 100644 index 00000000000..94302c1adf4 --- /dev/null +++ b/mysql-test/suite/versioning/r/replace.result @@ -0,0 +1,10 @@ +call create_table('t', 'x int'); +insert t values (1, 2); +replace t values (1, 3); +select *, current_row(row_end) as current from t for system_time all +order by x; +id x current +1 2 0 +1 3 1 +drop database test; +create database test; diff --git a/mysql-test/suite/versioning/r/rpl.result b/mysql-test/suite/versioning/r/rpl.result new file mode 100644 index 00000000000..b91c8fd33c8 --- /dev/null +++ b/mysql-test/suite/versioning/r/rpl.result @@ -0,0 +1,118 @@ +include/master-slave.inc +[connection master] +connection slave; +connection master; +CREATE TABLE t1 (x int) with system versioning; +insert into t1 values (1); +SELECT * FROM t1; +x +1 +delete from t1; +select * from t1; +x +select * from t1 for system_time all; +x +1 +connection slave; +select * from t1; +x +select * from t1 for system_time all; +x +1 +connection master; +insert into t1 values (2); +connection slave; +select * from t1; +x +2 +connection master; +update t1 set x = 3; +connection slave; +select * from t1; +x +3 +select * from t1 for system_time all; +x +1 +3 +2 +connection master; +create or replace table t1 (x int primary key); +connection slave; +alter table t1 with system versioning; +connection master; +insert into t1 values (1); +connection slave; +select * from t1; +x +1 +select * from t1 for system_time all; +x +1 +connection master; +update t1 set x= 2 where x = 1; +connection slave; +select * from t1; +x +2 +select * from t1 for system_time all; +x +1 +2 +connection master; +delete from t1; +connection slave; +select * from t1; +x +select * from t1 for system_time all; +x +1 +2 +connection master; +create or replace table t1 (x int); +connection slave; +alter table t1 with system versioning; +connection master; +insert into t1 values (1); +update t1 set x= 2 where x = 1; +connection slave; +select * from t1; +x +2 +select * from t1 for system_time all; +x +2 +1 +connection master; +delete from t1; +connection slave; +select * from t1; +x +select * from t1 for system_time all; +x +2 +1 +connection master; +create or replace table t1 (x int) with system versioning; +create or replace table t2 (x int) with system versioning; +insert into t1 values (1); +insert into t2 values (2); +update t1, t2 set t1.x=11, t2.x=22; +connection slave; +select * from t1; +x +11 +select * from t2; +x +22 +select * from t1 for system_time all; +x +11 +1 +select * from t2 for system_time all; +x +22 +2 +connection master; +drop table t1, t2; +include/rpl_end.inc diff --git a/mysql-test/suite/versioning/r/select.result b/mysql-test/suite/versioning/r/select.result new file mode 100644 index 00000000000..1f7e0306b9b --- /dev/null +++ b/mysql-test/suite/versioning/r/select.result @@ -0,0 +1,515 @@ +create or replace table t1 ( +x int unsigned, +y int unsigned, +sys_trx_start SYS_DATATYPE as row start invisible, +sys_trx_end SYS_DATATYPE as row end invisible, +period for system_time (sys_trx_start, sys_trx_end) +) with system versioning; +insert into t1 (x, y) values +(0, 100), +(1, 101), +(2, 102), +(3, 103), +(4, 104), +(5, 105), +(6, 106), +(7, 107), +(8, 108), +(9, 109); +set @t0= now(6); +delete from t1 where x = 3; +delete from t1 where x > 7; +insert into t1(x, y) values(3, 33); +select sys_trx_start from t1 where x = 3 and y = 33 into @t1; +select x, y from t1; +x y +0 100 +1 101 +2 102 +4 104 +5 105 +6 106 +7 107 +3 33 +select x as ASOF_x, y from t1 for system_time as of timestamp @t0; +ASOF_x y +0 100 +1 101 +2 102 +3 103 +4 104 +5 105 +6 106 +7 107 +8 108 +9 109 +select x as FROMTO_x, y from t1 for system_time from timestamp '0-0-0 0:0:0' to timestamp @t1; +FROMTO_x y +0 100 +1 101 +2 102 +3 103 +4 104 +5 105 +6 106 +7 107 +8 108 +9 109 +select x as BETWAND_x, y from t1 for system_time between timestamp '0-0-0 0:0:0' and timestamp @t1; +BETWAND_x y +0 100 +1 101 +2 102 +3 103 +4 104 +5 105 +6 106 +7 107 +8 108 +9 109 +3 33 +select x as ALL_x, y from t1 for system_time all; +ALL_x y +0 100 +1 101 +2 102 +3 103 +4 104 +5 105 +6 106 +7 107 +8 108 +9 109 +3 33 +ASOF2_x y +0 100 +1 101 +2 102 +3 103 +4 104 +5 105 +6 106 +7 107 +8 108 +9 109 +FROMTO2_x y +0 100 +1 101 +2 102 +3 103 +4 104 +5 105 +6 106 +7 107 +8 108 +9 109 +BETWAND2_x y +0 100 +1 101 +2 102 +3 103 +4 104 +5 105 +6 106 +7 107 +8 108 +9 109 +3 33 +create or replace table t1 ( +x int unsigned, +y int unsigned +) with system versioning; +create or replace table t2 ( +x int unsigned, +y int unsigned +) with system versioning; +insert into t1 values (1, 1), (1, 2), (1, 3), (4, 4), (5, 5); +insert into t2 values (1, 2), (2, 1), (3, 1); +set @t0= now(6); +select t1.x as IJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 inner join t2 on t1.x = t2.x; +IJ1_x1 y1 x2 y2 +1 1 1 2 +1 2 1 2 +1 3 1 2 +select t1.x as LJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 left join t2 on t1.x = t2.x; +LJ1_x1 y1 x2 y2 +1 1 1 2 +1 2 1 2 +1 3 1 2 +4 4 NULL NULL +5 5 NULL NULL +select t1.x as RJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 right join t2 on t1.x = t2.x; +RJ1_x1 y1 x2 y2 +1 1 1 2 +1 2 1 2 +1 3 1 2 +NULL NULL 2 1 +NULL NULL 3 1 +delete from t1; +delete from t2; +explain extended select * from (select t1.x as IJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 inner join t2 on t1.x = t2.x) +for system_time as of timestamp @t0 as t; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join) +Warnings: +Note 1003 select `test`.`t1`.`x` AS `IJ2_x1`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t1` FOR SYSTEM_TIME ALL join `test`.`t2` FOR SYSTEM_TIME ALL where `test`.`t1`.`x` = `test`.`t2`.`x` and `test`.`t1`.`row_end` > <cache>(cast(@`t0` as datetime(6))) and `test`.`t1`.`row_start` <= <cache>(cast(@`t0` as datetime(6))) and `test`.`t2`.`row_end` > <cache>(cast(@`t0` as datetime(6))) and `test`.`t2`.`row_start` <= <cache>(cast(@`t0` as datetime(6))) +explain extended select * from (select t1.x as LJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 left join t2 on t1.x = t2.x) +for system_time as of timestamp @t0 as t; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +Warnings: +Note 1003 select `test`.`t1`.`x` AS `LJ2_x1`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t1` FOR SYSTEM_TIME ALL left join `test`.`t2` FOR SYSTEM_TIME ALL on(`test`.`t2`.`x` = `test`.`t1`.`x` and `test`.`t1`.`row_end` > <cache>(cast(@`t0` as datetime(6))) and `test`.`t1`.`row_start` <= <cache>(cast(@`t0` as datetime(6))) and `test`.`t2`.`row_end` > <cache>(cast(@`t0` as datetime(6))) and `test`.`t2`.`row_start` <= <cache>(cast(@`t0` as datetime(6)))) where 1 +explain extended select * from (select t1.x as RJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 right join t2 on t1.x = t2.x) +for system_time as of timestamp @t0 as t; +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 +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join) +Warnings: +Note 1003 select `test`.`t1`.`x` AS `RJ2_x1`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t2` FOR SYSTEM_TIME ALL left join `test`.`t1` FOR SYSTEM_TIME ALL on(`test`.`t1`.`x` = `test`.`t2`.`x` and `test`.`t1`.`row_end` > <cache>(cast(@`t0` as datetime(6))) and `test`.`t1`.`row_start` <= <cache>(cast(@`t0` as datetime(6))) and `test`.`t2`.`row_end` > <cache>(cast(@`t0` as datetime(6))) and `test`.`t2`.`row_start` <= <cache>(cast(@`t0` as datetime(6)))) where 1 +select * from (select t1.x as IJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 inner join t2 on t1.x = t2.x) +for system_time as of timestamp @t0 as t; +IJ2_x1 y1 x2 y2 +1 1 1 2 +1 2 1 2 +1 3 1 2 +select * from (select t1.x as LJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 left join t2 on t1.x = t2.x) +for system_time as of timestamp @t0 as t; +LJ2_x1 y1 x2 y2 +1 1 1 2 +1 2 1 2 +1 3 1 2 +4 4 NULL NULL +5 5 NULL NULL +select * from (select t1.x as RJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 right join t2 on t1.x = t2.x) +for system_time as of timestamp @t0 as t; +RJ2_x1 y1 x2 y2 +1 1 1 2 +1 2 1 2 +1 3 1 2 +NULL NULL 2 1 +NULL NULL 3 1 +drop table t1; +drop table t2; +create table t1( +A int +) with system versioning; +insert into t1 values(1); +select * from t1; +A +1 +create or replace table t1 (x int); +insert into t1 values (1); +select * from t1 for system_time all; +ERROR HY000: Table `t1` is not system-versioned +create or replace table t1 (x int) with system versioning; +insert into t1 values (1); +select * from t1 for system_time all for update; +x +1 +create or replace table t1 (a int not null auto_increment primary key) with system versioning; +select * from (t1 as t2 left join t1 as t3 using (a)) natural left join t1; +a +create or replace table t1 (a int) with system versioning; +create or replace table t2 (a int) with system versioning; +insert into t1 values(1); +insert into t2 values(1); +create view v1 as select * from t2 inner join t1 using (a); +select * from v1; +a +1 +drop view v1; +create or replace table t1 (a int) with system versioning; +insert into t1 values (1); +create view vt1 as select a from t1; +select * from t1 natural join vt1; +a +1 +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 +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; +select @end; +@end +MAX_RESULT +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); +insert into t2 values (2); +select * from (select * from t1 cross join t2) as tmp; +a b +1 2 +select * from (select * from (select * from t1 cross join t2) as tmp1) as tmp2; +a b +1 2 +select * from (select * from t1 cross join t2 for system_time as of timestamp '0-0-0') as tmp; +a b +create or replace table t1(a1 int) with system versioning; +create or replace table t2(a2 int) with system versioning; +insert into t1 values(1),(2); +insert into t2 values(1),(2); +select * from t1 for system_time all natural left join t2 for system_time all; +a1 a2 +1 1 +2 1 +1 2 +2 2 +create or replace table t1(a1 int) with system versioning; +create or replace table t2(a2 int) with system versioning; +insert into t1 values(1),(2); +insert into t2 values(1),(2); +create or replace view v1 as select a1 from t1; +select * from v1 natural join t2; +a1 a2 +1 1 +2 1 +1 2 +2 2 +select * from v1 natural left join t2; +a1 a2 +1 1 +2 1 +1 2 +2 2 +select * from v1 natural right join t2; +a2 a1 +1 1 +2 1 +1 2 +2 2 +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); +select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1; +a a +2 1 +3 1 +2 2 +3 2 +2 3 +3 3 +1 NULL +create or replace table t1 (x int) with system versioning; +create or replace table t2 (y int) with system versioning; +insert into t1 values (1), (2), (3); +delete from t1 where x = 3; +insert into t2 values (1); +select * from t1, t2 for system_time all; +x y +1 1 +2 1 +select * from (select * from t1 for system_time all, t2 for system_time all) +for system_time all as t; +ERROR HY000: Table `t` is not system-versioned +# TRANSACTION/TIMESTAMP specifier in SYSTEM_TIME [MDEV-14645, Issue #396] +create or replace table t1 (x int) with system versioning engine myisam; +select * from t1 for system_time as of transaction 1; +ERROR HY000: Transaction system versioning for `t1` is not supported +create or replace table t1 ( +x int, +sys_trx_start bigint unsigned as row start invisible, +sys_trx_end bigint unsigned as row end invisible, +period for system_time (sys_trx_start, sys_trx_end) +) with system versioning engine innodb; +insert into t1 values (1); +set @ts= now(6); +delete from t1; +select sys_trx_start from t1 for system_time all into @trx_start; +## ensure @trx_start is much lower than unix timestamp +select @trx_start < unix_timestamp(@ts) - 100 as trx_start_good; +trx_start_good +1 +## TIMESTAMP specifier +select x from t1 for system_time as of timestamp @ts; +x +1 +select x from t1 for system_time as of timestamp unix_timestamp(@ts); +x +1 +select x from t1 for system_time as of timestamp @trx_start; +x +set @ts= timestamp'1-1-1 0:0:0'; +## TRANSACTION specifier +select x from t1 for system_time as of transaction @ts; +x +select x from t1 for system_time as of transaction unix_timestamp(@ts); +x +select x from t1 for system_time as of transaction @trx_start; +x +1 +## no specifier (auto-detection) +select x from t1 for system_time as of @ts; +x +select x from t1 for system_time as of unix_timestamp(@ts); +x +select x from t1 for system_time as of @trx_start; +x +1 +### Issue #365, bug 4 (related to #226, optimized fields) +create or replace table t1 (i int, b int) with system versioning; +insert into t1 values (0, 0), (0, 0); +select min(i) over (partition by b) as f +from (select i + 0 as i, b from t1) as tt +order by i; +f +0 +0 +### Issue #365, bug 5 (dangling AND) +create or replace table t1 (a int); +create or replace table t2 (b int) with system versioning; +select * from t1 +where exists (select 1 from t2 where t2.b = t1.a and t2.b = t1.a); +a +### Issue #365, bug 9 (not a derived subquery) +create or replace table t1 (x int) with system versioning; +select t1.x in (select x from t1) a from t1, (select x from t1) b; +a +### Issue #365, bug 10 (WHERE cond freed prematurely for PS) +create or replace table t1 (x int) with system versioning; +insert into t1 values (1); +create or replace view v1 as select x from t1 where x = 1; +prepare stmt from " +select x from t1 where x in (select x from v1);"; +execute stmt; +x +1 +execute stmt; +x +1 +### Issue #365, bug 11 (WHERE cond not top level item) +create or replace table t1 (a int, b int, key idx(a)) with system versioning; +insert into t1 values (1, 1), (2, 2); +select * from t1 where (a, 2) in ((1, 1), (2, 2)) and b = 1; +a b +### Issue #398, NOW is now non-magic +create or replace table t1 (x int) with system versioning; +select * from t1 for system_time as of current_timestamp; +x +select * from t1 for system_time as of now; +ERROR 42S22: Unknown column 'now' in 'where clause' +### Issue #405, NATURAL JOIN failure +create or replace table t1 (a int) with system versioning; +create or replace table t2 (b int); +create or replace view v1 as select a, row_start, row_end from t1 where a > round(rand()*1000); +select * from v1 natural join t2; +a b +### Issue #406, MDEV-14633 Assertion on TRT read +create or replace table t1 (pk int primary key, i int, t time, key (i)) with system versioning; +insert into t1 values (1, 10, '15:01:53'), (2, 20, '00:00:00'); +delete from t1; +select * from t1 where t = '00:00:00' and i > 0 and row_end <> '2012-12-12 00:00:00'; +pk i t +### MDEV-14816 Assertion `join->best_read < double(1.797...e+308L)' failed in bool greedy_search +create or replace table t1 (f1 int) with system versioning; +create or replace table t2 (f2 int) with system versioning; +create or replace table t3 (f3 int); +create or replace table t4 (f4 int); +insert into t1 values (1), (2), (3), (4); +insert into t2 values (1), (2), (3); +insert into t3 values (1), (2); +insert into t4 values (1); +select * from +t1 as t1a +left join t2 as t2a left join (t3 as t3a inner join t1) on t2a.f2 = t3a.f3 on t1a.f1 = t2a.f2 +left join (t2 join t3 inner join t4) on t2a.f2 = t1a.f1; +f1 f2 f3 f1 f2 f3 f4 +1 1 1 1 1 1 1 +2 2 2 1 1 1 1 +1 1 1 2 1 1 1 +2 2 2 2 1 1 1 +1 1 1 3 1 1 1 +2 2 2 3 1 1 1 +1 1 1 4 1 1 1 +2 2 2 4 1 1 1 +1 1 1 1 1 2 1 +2 2 2 1 1 2 1 +1 1 1 2 1 2 1 +2 2 2 2 1 2 1 +1 1 1 3 1 2 1 +2 2 2 3 1 2 1 +1 1 1 4 1 2 1 +2 2 2 4 1 2 1 +1 1 1 1 2 1 1 +2 2 2 1 2 1 1 +1 1 1 2 2 1 1 +2 2 2 2 2 1 1 +1 1 1 3 2 1 1 +2 2 2 3 2 1 1 +1 1 1 4 2 1 1 +2 2 2 4 2 1 1 +1 1 1 1 2 2 1 +2 2 2 1 2 2 1 +1 1 1 2 2 2 1 +2 2 2 2 2 2 1 +1 1 1 3 2 2 1 +2 2 2 3 2 2 1 +1 1 1 4 2 2 1 +2 2 2 4 2 2 1 +1 1 1 1 3 1 1 +2 2 2 1 3 1 1 +1 1 1 2 3 1 1 +2 2 2 2 3 1 1 +1 1 1 3 3 1 1 +2 2 2 3 3 1 1 +1 1 1 4 3 1 1 +2 2 2 4 3 1 1 +1 1 1 1 3 2 1 +2 2 2 1 3 2 1 +1 1 1 2 3 2 1 +2 2 2 2 3 2 1 +1 1 1 3 3 2 1 +2 2 2 3 3 2 1 +1 1 1 4 3 2 1 +2 2 2 4 3 2 1 +3 3 NULL NULL 1 1 1 +3 3 NULL NULL 1 2 1 +3 3 NULL NULL 2 1 1 +3 3 NULL NULL 2 2 1 +3 3 NULL NULL 3 1 1 +3 3 NULL NULL 3 2 1 +4 NULL NULL NULL NULL NULL NULL +drop view v1; +drop table t1, t2, t3, t4; +call verify_vtq_dummy(34); +No A B C D +1 1 1 1 1 +2 1 1 1 1 +3 1 1 1 1 +4 1 1 1 1 +5 1 1 1 1 +6 1 1 1 1 +7 1 1 1 1 +8 1 1 1 1 +9 1 1 1 1 +10 1 1 1 1 +11 1 1 1 1 +12 1 1 1 1 +13 1 1 1 1 +14 1 1 1 1 +15 1 1 1 1 +16 1 1 1 1 +17 1 1 1 1 +18 1 1 1 1 +19 1 1 1 1 +20 1 1 1 1 +21 1 1 1 1 +22 1 1 1 1 +23 1 1 1 1 +24 1 1 1 1 +25 1 1 1 1 +26 1 1 1 1 +27 1 1 1 1 +28 1 1 1 1 +29 1 1 1 1 +30 1 1 1 1 +31 1 1 1 1 +32 1 1 1 1 +33 1 1 1 1 +34 1 1 1 1 diff --git a/mysql-test/suite/versioning/r/select2,myisam.rdiff b/mysql-test/suite/versioning/r/select2,myisam.rdiff new file mode 100644 index 00000000000..b24682fbb9f --- /dev/null +++ b/mysql-test/suite/versioning/r/select2,myisam.rdiff @@ -0,0 +1,38 @@ +--- suite/versioning/r/select_sp.result ++++ suite/versioning/r/select_sp.result +@@ -22,8 +22,6 @@ + delete from t1 where x > 7; + insert into t1(x, y) values(3, 33); + select sys_start from t1 where x = 3 and y = 33 into @t1; +-set @x1= @t1; +-select vtq_commit_ts(@x1) into @t1; + select x, y from t1; + x y + 0 100 +@@ -84,7 +82,7 @@ + 8 108 + 9 109 + 3 33 +-select x as ASOF2_x, y from t1 for system_time as of @x0; ++select x as ASOF2_x, y from t1 for system_time as of @t0; + ASOF2_x y + 0 100 + 1 101 +@@ -96,7 +94,7 @@ + 7 107 + 8 108 + 9 109 +-select x as FROMTO2_x, y from t1 for system_time from @x0 to @x1; ++select x as FROMTO2_x, y from t1 for system_time from '0-0-0 0:0:0' to @t1; + FROMTO2_x y + 0 100 + 1 101 +@@ -108,7 +106,7 @@ + 7 107 + 8 108 + 9 109 +-select x as BETWAND2_x, y from t1 for system_time between transaction @x0 and transaction @x1; ++select x as BETWAND2_x, y from t1 for system_time between timestamp '0-0-0 0:0:0' and timestamp @t1; + BETWAND2_x y + 0 100 + 1 101 diff --git a/mysql-test/suite/versioning/r/select2.result b/mysql-test/suite/versioning/r/select2.result new file mode 100644 index 00000000000..79c4416a291 --- /dev/null +++ b/mysql-test/suite/versioning/r/select2.result @@ -0,0 +1,338 @@ +create table t1( +x int unsigned, +y int unsigned, +sys_start SYS_TYPE as row start invisible, +sys_end SYS_TYPE as row end invisible, +period for system_time (sys_start, sys_end)) +with system versioning engine=ENGINE; +insert into t1 (x, y) values +(0, 100), +(1, 101), +(2, 102), +(3, 103), +(4, 104), +(5, 105), +(6, 106), +(7, 107), +(8, 108), +(9, 109); +set @t0= now(6); +select sys_start from t1 limit 1 into @x0; +delete from t1 where x = 3; +delete from t1 where x > 7; +insert into t1(x, y) values(3, 33); +select sys_start from t1 where x = 3 and y = 33 into @t1; +set @x1= @t1; +select vtq_commit_ts(@x1) into @t1; +select x, y from t1; +x y +0 100 +1 101 +2 102 +4 104 +5 105 +6 106 +7 107 +3 33 +select x as ASOF_x, y from t1 for system_time as of timestamp @t0; +ASOF_x y +0 100 +1 101 +2 102 +3 103 +4 104 +5 105 +6 106 +7 107 +8 108 +9 109 +select x as FROMTO_x, y from t1 for system_time from '0-0-0 0:0:0' to timestamp @t1; +FROMTO_x y +0 100 +1 101 +2 102 +3 103 +4 104 +5 105 +6 106 +7 107 +8 108 +9 109 +select x as BETWAND_x, y from t1 for system_time between '0-0-0 0:0:0' and timestamp @t1; +BETWAND_x y +0 100 +1 101 +2 102 +3 103 +4 104 +5 105 +6 106 +7 107 +8 108 +9 109 +3 33 +select x as ALL_x, y from t1 for system_time all; +ALL_x y +0 100 +1 101 +2 102 +3 103 +4 104 +5 105 +6 106 +7 107 +8 108 +9 109 +3 33 +select x as ASOF2_x, y from t1 for system_time as of @x0; +ASOF2_x y +0 100 +1 101 +2 102 +3 103 +4 104 +5 105 +6 106 +7 107 +8 108 +9 109 +select x as FROMTO2_x, y from t1 for system_time from @x0 to @x1; +FROMTO2_x y +0 100 +1 101 +2 102 +3 103 +4 104 +5 105 +6 106 +7 107 +8 108 +9 109 +select x as BETWAND2_x, y from t1 for system_time between transaction @x0 and transaction @x1; +BETWAND2_x y +0 100 +1 101 +2 102 +3 103 +4 104 +5 105 +6 106 +7 107 +8 108 +9 109 +3 33 +drop table t1; +create table t1( +x int, +y int, +sys_start SYS_TYPE as row start invisible, +sys_end SYS_TYPE as row end invisible, +period for system_time (sys_start, sys_end)) +with system versioning engine=ENGINE; +create table t2 like t1; +insert into t1 values (1, 1), (1, 2), (1, 3), (4, 4), (5, 5); +insert into t2 values (1, 2), (2, 1), (3, 1); +set @t0= now(6); +select t1.x as IJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 inner join t2 on t1.x = t2.x; +IJ1_x1 y1 x2 y2 +1 1 1 2 +1 2 1 2 +1 3 1 2 +select t1.x as LJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 left join t2 on t1.x = t2.x; +LJ1_x1 y1 x2 y2 +1 1 1 2 +1 2 1 2 +1 3 1 2 +4 4 NULL NULL +5 5 NULL NULL +select t1.x as RJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 right join t2 on t1.x = t2.x; +RJ1_x1 y1 x2 y2 +1 1 1 2 +1 2 1 2 +1 3 1 2 +NULL NULL 2 1 +NULL NULL 3 1 +delete from t1; +delete from t2; +select IJ2_x1,y1,x2,y2 from (select t1.x as IJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 inner join t2 on t1.x = t2.x) +for system_time as of timestamp @t0 as t; +IJ2_x1 y1 x2 y2 +1 1 1 2 +1 2 1 2 +1 3 1 2 +select LJ2_x1,y1,x2,y2 from (select t1.x as LJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 left join t2 on t1.x = t2.x) +for system_time as of timestamp @t0 as t; +LJ2_x1 y1 x2 y2 +1 1 1 2 +1 2 1 2 +1 3 1 2 +4 4 NULL NULL +5 5 NULL NULL +select RJ2_x1,y1,x2,y2 from (select t1.x as RJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 right join t2 on t1.x = t2.x) +for system_time as of timestamp @t0 as t; +RJ2_x1 y1 x2 y2 +1 1 1 2 +1 2 1 2 +1 3 1 2 +NULL NULL 2 1 +NULL NULL 3 1 +drop table t1; +drop table t2; +# MDEV-14686 Server crashes in Item_field::used_tables on 2nd call of SP [#422] +create or replace table t1 (called int, bad int) with system versioning; +create or replace procedure bad() select * from t1 where bad in (select called from t1); +called bad +called bad +called bad +called bad +called bad +called bad +called bad +called bad +# bad() is good. +# MDEV-14751 Server crashes in TABLE::versioned on 2nd execution of SP [#431] +create or replace table t1 (called_bad int); +create or replace table t2 (b int); +create or replace procedure bad() select * from t1 where ( 5, 6 ) in ( select b, b from t2 ) and called_bad in ( select max(b) from t2 ); +called_bad +called_bad +called_bad +called_bad +called_bad +called_bad +called_bad +called_bad +# bad() is good. +# MDEV-14786 Server crashes in Item_cond::transform on 2nd execution of SP querying from a view [#436] +create or replace table t1 (called_bad int) with system versioning; +create or replace view v1 as select called_bad from t1 where called_bad < 5; +create or replace procedure bad() select called_bad from v1; +called_bad +called_bad +called_bad +called_bad +called_bad +called_bad +called_bad +called_bad +# bad() is good. +# wildcard expansion on hidden fields. +create or replace table t1( +A int +) with system versioning; +insert into t1 values(1); +select * from t1; +A +1 +create or replace table t1 (x int); +insert into t1 values (1); +select * from t1 for system_time all; +ERROR HY000: Table `t1` is not system-versioned +create or replace table t1 (x int) with system versioning; +insert into t1 values (1); +select * from t1 for system_time as of now() for update; +x +1 +create or replace table t1 (a int not null auto_increment primary key) with system versioning; +select * from (t1 as t2 left join t1 as t3 using (a)) natural left join t1; +a +create or replace table t1 (a int) with system versioning; +create or replace table t2 (a int) with system versioning; +insert into t1 values(1); +insert into t2 values(1); +create or replace view v1 as select * from t2 inner join t1 using (a); +select * from v1; +a +1 +drop view v1; +create or replace table t1 (a int) with system versioning; +insert into t1 values (1); +create view vt1 as select a from t1; +select * from t1 natural join vt1; +a +1 +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 +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; +select @end; +@end +MAX_RESULT +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); +insert into t2 values (2); +select * from (select * from t1 cross join t2) as tmp; +a b +1 2 +select * from (select * from (select * from t1 cross join t2) as tmp1) as tmp2; +a b +1 2 +select * from (select * from t1 cross join t2 for system_time as of timestamp '0-0-0') as tmp; +a b +create or replace table t1(a1 int) with system versioning; +create or replace table t2(a2 int) with system versioning; +insert into t1 values(1),(2); +insert into t2 values(1),(2); +select * from t1 for system_time all natural left join t2 for system_time all; +a1 a2 +1 1 +2 1 +1 2 +2 2 +create or replace table t1(a1 int) with system versioning; +create or replace table t2(a2 int) with system versioning; +insert into t1 values(1),(2); +insert into t2 values(1),(2); +create or replace view v1 as select a1 from t1; +select * from v1 natural join t2; +a1 a2 +1 1 +2 1 +1 2 +2 2 +select * from v1 natural left join t2; +a1 a2 +1 1 +2 1 +1 2 +2 2 +select * from v1 natural right join t2; +a2 a1 +1 1 +2 1 +1 2 +2 2 +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); +select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1; +a a +2 1 +3 1 +2 2 +3 2 +2 3 +3 3 +1 NULL +create or replace table t1 (x int) with system versioning; +create or replace table t2 (y int) with system versioning; +insert into t1 values (1), (2), (3); +delete from t1 where x = 3; +insert into t2 values (1); +select * from t1, t2 for system_time all; +x y +1 1 +2 1 +select * from (select * from t1 for system_time all, t2 for system_time all) for system_time all as t; +ERROR HY000: Table `t` is not system-versioned +select * from (t1 for system_time all join t2 for system_time all) for system_time all; +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 '' at line 1 +drop view v1; +drop table t1, t2; diff --git a/mysql-test/suite/versioning/r/simple.result b/mysql-test/suite/versioning/r/simple.result new file mode 100644 index 00000000000..f6a1ba37f53 --- /dev/null +++ b/mysql-test/suite/versioning/r/simple.result @@ -0,0 +1,73 @@ +set default_storage_engine=innodb; +create or replace table dept ( +dept_id int(10) primary key, +name varchar(100) +) +with system versioning; +create or replace table emp ( +emp_id int(10) primary key, +dept_id int(10), +name varchar(100), +salary int(10), +constraint `dept-emp-fk` + foreign key (dept_id) references dept (dept_id) +on delete cascade +on update restrict +) +with system versioning; +select now() into @ts_0; +insert into dept (dept_id, name) values (10, "accounting"); +commit; +select row_start into @ts_1 from dept where dept_id=10; +insert into emp (emp_id, name, salary, dept_id) values (1, "bill", 1000, 10); +commit; +select row_start into @ts_2 from emp where name="bill"; +select * from emp; +emp_id dept_id name salary +1 10 bill 1000 +update emp set salary=2000 where name="bill"; +commit; +select row_start into @ts_3 from emp where name="bill"; +select * from emp; +emp_id dept_id name salary +1 10 bill 2000 +select * from emp for system_time as of timestamp @ts_2; +emp_id dept_id name salary +1 10 bill 1000 +select * from emp for system_time as of timestamp @ts_3; +emp_id dept_id name salary +1 10 bill 2000 +select * from emp e, dept d +where d.dept_id = 10 +and d.dept_id = e.dept_id; +emp_id dept_id name salary dept_id name +1 10 bill 2000 10 accounting +select * from +emp for system_time from timestamp @ts_1 to timestamp @ts_2 e, +dept for system_time from timestamp @ts_1 to timestamp @ts_2 d +where d.dept_id = 10 +and d.dept_id = e.dept_id; +emp_id dept_id name salary dept_id name +set statement system_versioning_asof=@ts_0 for +select * from emp e, dept d +where d.dept_id = 10 +and d.dept_id = e.dept_id; +emp_id dept_id name salary dept_id name +set statement system_versioning_asof=@ts_1 for +select * from emp e, dept d +where d.dept_id = 10 +and d.dept_id = e.dept_id; +emp_id dept_id name salary dept_id name +set statement system_versioning_asof=@ts_2 for +select * from emp e, dept d +where d.dept_id = 10 +and d.dept_id = e.dept_id; +emp_id dept_id name salary dept_id name +1 10 bill 1000 10 accounting +set statement system_versioning_asof=@ts_3 for +select * from emp e, dept d +where d.dept_id = 10 +and d.dept_id = e.dept_id; +emp_id dept_id name salary dept_id name +1 10 bill 2000 10 accounting +drop table emp, dept; diff --git a/mysql-test/suite/versioning/r/sysvars.result b/mysql-test/suite/versioning/r/sysvars.result new file mode 100644 index 00000000000..22f53ca6fbe --- /dev/null +++ b/mysql-test/suite/versioning/r/sysvars.result @@ -0,0 +1,129 @@ +create table t (a int) with system versioning; +insert into t values (1); +update t set a= 2; +show global variables like 'system_versioning_asof'; +Variable_name Value +system_versioning_asof DEFAULT +show variables like 'system_versioning_asof'; +Variable_name Value +system_versioning_asof DEFAULT +select * from t; +a +2 +set system_versioning_asof= '2031-1-1 0:0:0'; +show variables like 'system_versioning_asof'; +Variable_name Value +system_versioning_asof 2031-01-01 00:00:00.000000 +select * from t; +a +2 +set system_versioning_asof= '2011-1-1 0:0:0'; +show variables like 'system_versioning_asof'; +Variable_name Value +system_versioning_asof 2011-01-01 00:00:00.000000 +select * from t; +a +set global system_versioning_asof= 'alley'; +ERROR 42000: Variable 'system_versioning_asof' can't be set to the value of 'alley' +set global system_versioning_asof= null; +ERROR 42000: Variable 'system_versioning_asof' can't be set to the value of 'NULL' +set global system_versioning_asof= 1; +ERROR 42000: Incorrect argument type to variable 'system_versioning_asof' +set global system_versioning_asof= 1.1; +ERROR 42000: Incorrect argument type to variable 'system_versioning_asof' +set system_versioning_asof= 'alley'; +ERROR 42000: Variable 'system_versioning_asof' can't be set to the value of 'alley' +set system_versioning_asof= null; +ERROR 42000: Variable 'system_versioning_asof' can't be set to the value of 'NULL' +set system_versioning_asof= 1; +ERROR 42000: Incorrect argument type to variable 'system_versioning_asof' +set system_versioning_asof= 1.1; +ERROR 42000: Incorrect argument type to variable 'system_versioning_asof' +# GLOBAL @@system_versioning_asof +set global system_versioning_asof= '1911-11-11 11:11:11.1111119'; +Warnings: +Note 1292 Truncated incorrect datetime value: '1911-11-11 11:11:11.1111119' +Note 1292 Truncated incorrect datetime value: '1911-11-11 11:11:11.1111119' +show global variables like 'system_versioning_asof'; +Variable_name Value +system_versioning_asof 1911-11-11 11:11:11.111111 +set global system_versioning_asof= '1900-01-01 00:00:00'; +show global variables like 'system_versioning_asof'; +Variable_name Value +system_versioning_asof 1900-01-01 00:00:00.000000 +set global system_versioning_asof= timestamp'1911-11-11 11:11:11.1111119'; +Warnings: +Note 1292 Truncated incorrect datetime value: '1911-11-11 11:11:11.1111119' +show global variables like 'system_versioning_asof'; +Variable_name Value +system_versioning_asof 1911-11-11 11:11:11.111111 +set @ts= timestamp'1900-01-01 00:00:00'; +set global system_versioning_asof= @ts; +show global variables like 'system_versioning_asof'; +Variable_name Value +system_versioning_asof 1900-01-01 00:00:00.000000 +set global system_versioning_asof= default; +select @@global.system_versioning_asof; +@@global.system_versioning_asof +DEFAULT +# SESSION @@system_versioning_asof +set system_versioning_asof= '1911-11-11 11:11:11.1111119'; +Warnings: +Note 1292 Truncated incorrect datetime value: '1911-11-11 11:11:11.1111119' +Note 1292 Truncated incorrect datetime value: '1911-11-11 11:11:11.1111119' +show variables like 'system_versioning_asof'; +Variable_name Value +system_versioning_asof 1911-11-11 11:11:11.111111 +set system_versioning_asof= '1900-01-01 00:00:00'; +show variables like 'system_versioning_asof'; +Variable_name Value +system_versioning_asof 1900-01-01 00:00:00.000000 +set system_versioning_asof= timestamp'1911-11-11 11:11:11.1111119'; +Warnings: +Note 1292 Truncated incorrect datetime value: '1911-11-11 11:11:11.1111119' +show variables like 'system_versioning_asof'; +Variable_name Value +system_versioning_asof 1911-11-11 11:11:11.111111 +set @ts= timestamp'1900-01-01 00:00:00'; +set system_versioning_asof= @ts; +show variables like 'system_versioning_asof'; +Variable_name Value +system_versioning_asof 1900-01-01 00:00:00.000000 +# DEFAULT: value is copied from GLOBAL to SESSION +set global system_versioning_asof= timestamp'1911-11-11 11:11:11.111111'; +set system_versioning_asof= '1900-01-01 00:00:00'; +select @@global.system_versioning_asof != @@system_versioning_asof as different; +different +1 +set system_versioning_asof= default; +select @@global.system_versioning_asof = @@system_versioning_asof as equal; +equal +1 +set global system_versioning_asof= DEFAULT; +set system_versioning_asof= DEFAULT; +select @@global.system_versioning_asof, @@system_versioning_asof; +@@global.system_versioning_asof @@system_versioning_asof +DEFAULT DEFAULT +select * from t for system_time all; +a +2 +1 +select * from t; +a +2 +select * from t for system_time as of timestamp current_timestamp(6); +a +2 +select * from t for system_time all; +a +2 +1 +select * from t for system_time from '0-0-0' to current_timestamp(6); +a +2 +1 +select * from t for system_time between '0-0-0' and current_timestamp(6); +a +2 +1 +drop table t; diff --git a/mysql-test/suite/versioning/r/truncate.result b/mysql-test/suite/versioning/r/truncate.result new file mode 100644 index 00000000000..48b7fbbcf55 --- /dev/null +++ b/mysql-test/suite/versioning/r/truncate.result @@ -0,0 +1,71 @@ +create table t (a int); +delete history from t before system_time now(); +ERROR HY000: Table `t` is not system-versioned +create or replace table t (a int) with system versioning; +insert into t values (1); +update t set a=2; +set @test = 'correct'; +create trigger trg_before before delete on t for each row set @test = 'incorrect'; +create trigger trg_after after delete on t for each row set @test = 'incorrect'; +delete history from t; +select @test from t; +@test +correct +drop table t; +create table t (a int) with system versioning; +insert into t values (1), (2); +update t set a=11 where a=1; +set @ts1=now(6); +update t set a=22 where a=2; +select * from t for system_time all; +a +11 +22 +1 +2 +delete history from t before system_time timestamp @ts1; +select * from t for system_time all; +a +11 +22 +2 +prepare stmt from 'delete history from t'; +execute stmt; +drop prepare stmt; +select * from t for system_time all; +a +11 +22 +delete from t; +create or replace procedure truncate_sp() +begin +delete history from t before system_time timestamp now(6); +end~~ +call truncate_sp; +select * from t for system_time all; +a +drop procedure truncate_sp; +### Issue #399, truncate partitioned table is now unimplemented +create or replace table t (a int) +with system versioning +engine myisam +partition by system_time ( +partition p0 history, +partition pn current); +delete history from t; +ERROR 42000: The used command is not allowed with this MariaDB version +create or replace table t (i int) with system versioning; +delete history from t; +create or replace view v as select * from t; +delete history from v; +ERROR HY000: DELETE HISTORY from VIEW is prohibited +create or replace table t (i int); +delete history from t; +ERROR HY000: Table `t` is not system-versioned +create or replace view v as select * from t; +delete history from v; +ERROR HY000: DELETE HISTORY from VIEW is prohibited +prepare stmt from 'delete history from t'; +ERROR HY000: Table `t` is not system-versioned +drop table t; +drop view v; diff --git a/mysql-test/suite/versioning/r/truncate_privilege.result b/mysql-test/suite/versioning/r/truncate_privilege.result new file mode 100644 index 00000000000..e378407afde --- /dev/null +++ b/mysql-test/suite/versioning/r/truncate_privilege.result @@ -0,0 +1,33 @@ +connect root,localhost,root,,test; +connection root; +create database mysqltest; +create user mysqltest_1@localhost; +connect user1,localhost,mysqltest_1,,test; +connection user1; +connection root; +create table mysqltest.t (a int) with system versioning; +connection user1; +show grants; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' +delete history from mysqltest.t before system_time now(); +ERROR 42000: DELETE VERSIONING ROWS command denied to user 'mysqltest_1'@'localhost' for table 't' +connection root; +grant delete history on mysqltest.* to mysqltest_1@localhost; +grant delete history on mysqltest.t to mysqltest_1@localhost; +connection user1; +show grants; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' +GRANT DELETE VERSIONING ROWS ON `mysqltest`.* TO 'mysqltest_1'@'localhost' +GRANT DELETE VERSIONING ROWS ON `mysqltest`.`t` TO 'mysqltest_1'@'localhost' +delete history from mysqltest.t before system_time now(); +connection root; +grant all on *.* to mysqltest_1@localhost; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT ALL PRIVILEGES ON *.* TO 'mysqltest_1'@'localhost' +GRANT DELETE VERSIONING ROWS ON `mysqltest`.* TO 'mysqltest_1'@'localhost' +GRANT DELETE VERSIONING ROWS ON `mysqltest`.`t` TO 'mysqltest_1'@'localhost' +drop user mysqltest_1@localhost; +drop database mysqltest; diff --git a/mysql-test/suite/versioning/r/trx_id.result b/mysql-test/suite/versioning/r/trx_id.result new file mode 100644 index 00000000000..a88ba7eec2b --- /dev/null +++ b/mysql-test/suite/versioning/r/trx_id.result @@ -0,0 +1,72 @@ +create or replace table t1 ( +x int, +sys_trx_start bigint(20) unsigned as row start invisible, +sys_trx_end bigint(20) unsigned as row end invisible, +period for system_time (sys_trx_start, sys_trx_end) +) with system versioning engine innodb; +insert into t1 (x) values (1); +# ALTER ADD SYSTEM VERSIONING should write to mysql.transaction_registry +create function check_result (cond boolean) +returns char(50) deterministic +return if(cond = 1, '[CORRECT]', '[INCORRECT]'); +set @@system_versioning_alter_history=keep; +create or replace table t1 (x int) engine innodb; +insert into t1 values (1); +alter table t1 +add column s bigint unsigned as row start, +add column e bigint unsigned as row end, +add period for system_time(s, e), +add system versioning, +algorithm=inplace; +select s from t1 into @trx_start; +select check_result(count(*) = 1) from mysql.transaction_registry where transaction_id = @trx_start; +check_result(count(*) = 1) +[CORRECT] +create or replace table t1 (x int) engine innodb; +select count(*) from mysql.transaction_registry into @tmp; +alter table t1 +add column s bigint unsigned as row start, +add column e bigint unsigned as row end, +add period for system_time(s, e), +add system versioning, +algorithm=inplace; +select check_result(count(*) = @tmp) from mysql.transaction_registry; +check_result(count(*) = @tmp) +[CORRECT] +create or replace table t1 (x int) engine innodb; +insert into t1 values (1); +alter table t1 +add column s bigint unsigned as row start, +add column e bigint unsigned as row end, +add period for system_time(s, e), +add system versioning, +algorithm=copy; +select s from t1 into @trx_start; +select check_result(count(*) = 1) from mysql.transaction_registry where transaction_id = @trx_start; +check_result(count(*) = 1) +[CORRECT] +create or replace table t1 (x int) engine innodb; +select count(*) from mysql.transaction_registry into @tmp; +alter table t1 +add column s bigint unsigned as row start, +add column e bigint unsigned as row end, +add period for system_time(s, e), +add system versioning, +algorithm=copy; +select check_result(count(*) = @tmp) from mysql.transaction_registry; +check_result(count(*) = @tmp) +[CORRECT] +# TRX_ID to TIMESTAMP versioning switch +create or replace table t1 ( +x int, +sys_start bigint unsigned as row start invisible, +sys_end bigint unsigned as row end invisible, +period for system_time (sys_start, sys_end) +) engine innodb with system versioning; +insert into t1 values (1); +alter table t1 drop column sys_start, drop column sys_end; +select sys_end = 18446744073709551615 as transaction_based from t1 for system_time all; +transaction_based +1 +drop table t1; +drop function check_result; diff --git a/mysql-test/suite/versioning/r/update.result b/mysql-test/suite/versioning/r/update.result new file mode 100644 index 00000000000..e0daf1d6588 --- /dev/null +++ b/mysql-test/suite/versioning/r/update.result @@ -0,0 +1,625 @@ +create procedure test_01( +sys_type varchar(255), +engine varchar(255), +fields varchar(255)) +begin +set @str= concat(' + create table t1( + x int unsigned, + y int unsigned, + sys_trx_start ', sys_type, ' as row start invisible, + sys_trx_end ', sys_type, ' as row end invisible, + period for system_time (sys_trx_start, sys_trx_end)) + with system versioning + engine ', engine); +prepare stmt from @str; execute stmt; drop prepare stmt; +insert into t1(x, y) values +(1, 1000), +(2, 2000), +(3, 3000), +(4, 4000), +(5, 5000), +(6, 6000), +(7, 7000), +(8, 8000), +(9, 9000); +select x, y from t1; +update t1 set y = y + 1 where x > 7; +select x, y from t1; +select x, y from t1 for system_time +between timestamp '0000-0-0 0:0:0' + and timestamp '2038-01-19 04:14:07'; +drop table t1; +end~~ +create procedure test_02( +sys_type varchar(255), +engine varchar(255), +fields varchar(255)) +begin +set @str= concat(' + create table t1 ( + id bigint primary key, + x int, + y int without system versioning, + sys_trx_start ', sys_type, ' as row start invisible, + sys_trx_end ', sys_type, ' as row end invisible, + period for system_time (sys_trx_start, sys_trx_end)) + with system versioning + engine ', engine); +prepare stmt from @str; execute stmt; drop prepare stmt; +insert into t1 values(1, 1, 1); +set @ins_t= now(6); +select sys_trx_start into @tmp1 from t1; +update t1 set x= 11, y= 11 where id = 1; +select @tmp1 < sys_trx_start as A1, x, y from t1; +select sys_trx_start into @tmp1 from t1; +update t1 set y= 1 where id = 1; +select @tmp1 = sys_trx_start as A2, x from t1; +drop table t1; +end~~ +create procedure test_03( +sys_type varchar(255), +engine varchar(255), +fields varchar(255)) +begin +set @str= concat(' + create table t1 ( + x int, + y int, + sys_trx_start bigint unsigned as row start invisible, + sys_trx_end bigint unsigned as row end invisible, + period for system_time (sys_trx_start, sys_trx_end) + ) with system versioning + engine ', engine); +prepare stmt from @str; execute stmt; drop prepare stmt; +insert into t1 (x, y) values (1, 1), (2, 1), (3, 1), (4, 1), (5, 1); +start transaction; +update t1 set y= y + 1 where x = 3; +update t1 set y= y + 1 where x = 2; +update t1 set y= y + 1 where x = 3; +update t1 set y= y + 1 where x > 3; +update t1 set y= y + 1 where x > 4; +commit; +select x, y, sys_trx_end = 18446744073709551615 as current from t1 for system_time all; +drop table t1; +end~~ +create procedure test_04( +sys_type varchar(255), +engine varchar(255), +fields varchar(255)) +begin +set @str= concat(' + create table t1 ( + id int primary key auto_increment, + x int, + sys_trx_start ', sys_type, ' as row start invisible, + sys_trx_end ', sys_type, ' as row end invisible, + period for system_time (sys_trx_start, sys_trx_end)) + with system versioning + engine ', engine); +prepare stmt from @str; execute stmt; drop prepare stmt; +set @t0= now(6); +insert into t1 (x) values (1); +set @t1= now(6); +update t1 set x= 2 where id = 1; +set @t2= now(6); +update t1 set x= 3 where id = 1; +select x from t1 for system_time as of timestamp @t0; +select x from t1 for system_time as of timestamp @t1; +select x from t1 for system_time as of timestamp @t2; +select x from t1 for system_time as of timestamp now(6); +drop table t1; +end~~ +create procedure test_05( +sys_type varchar(255), +engine varchar(255), +fields varchar(255)) +begin +set @str= concat(' + create table t1( + x int unsigned, + sys_trx_end ', sys_type, ' as row end invisible, + sys_trx_start ', sys_type, ' as row start invisible, + y int unsigned, + period for system_time (sys_trx_start, sys_trx_end), + primary key(x, y)) + with system versioning + engine ', engine); +prepare stmt from @str; execute stmt; drop prepare stmt; +insert into t1(x, y) values +(1, 1000), +(3, 3000), +(4, 4000), +(5, 5000); +insert into t1(x, y) values(3, 3000) on duplicate key update y = y+1; +insert into t1(x, y) values(4, 4444) on duplicate key update y = y+1; +select x, y from t1 for system_time all; +select x, y from t1; +drop table t1; +end~~ +create procedure test_06( +sys_type varchar(255), +engine varchar(255), +fields varchar(255)) +begin +set @str= concat('( + x int unsigned, + y int unsigned, + sys_trx_start ', sys_type, ' as row start invisible, + sys_trx_end ', sys_type, ' as row end invisible, + period for system_time (sys_trx_start, sys_trx_end)) + with system versioning + engine ', engine); +set @str2= concat('create table t1', @str); +prepare stmt from @str2; execute stmt; drop prepare stmt; +set @str2= concat('create table t2', @str); +prepare stmt from @str2; execute stmt; drop prepare stmt; +insert into t1(x, y) values +(1, 1000), +(2, 2000), +(3, 3000), +(4, 4000), +(5, 5000), +(6, 6000), +(7, 7000), +(8, 8000), +(9, 9000); +insert into t2(x, y) values +(1, 1010), +(2, 2010), +(3, 3010), +(4, 4010), +(5, 5010), +(6, 6010), +(7, 7010), +(8, 8010), +(9, 9010); +update t1, t2 set t1.y = t1.x + t1.y, t2.y = t2.x + t2.y where t1.x > 7 and t2.x < 7; +select x, y from t1 for system_time between timestamp '0-0-0 0:0:0' and timestamp '9999-1-1 0:0:0'; +select x, y from t1; +select x, y from t2 for system_time between timestamp '0-0-0 0:0:0' and timestamp '9999-1-1 0:0:0'; +select x, y from t2; +drop table t1; +drop table t2; +end~~ +create procedure test_07( +sys_type varchar(255), +engine varchar(255), +fields varchar(255)) +begin +set @str= concat('( + id bigint primary key without system versioning, + name varchar(128), + salary bigint without system versioning, + sys_trx_start ', sys_type, ' as row start invisible, + sys_trx_end ', sys_type, ' as row end invisible, + period for system_time (sys_trx_start, sys_trx_end)) + with system versioning + engine ', engine); +set @str2= concat('create table t1', @str); +prepare stmt from @str2; execute stmt; drop prepare stmt; +set @str2= concat('create table t2', @str); +prepare stmt from @str2; execute stmt; drop prepare stmt; +insert into t1 values (1, "Jeremy", 3000); +insert into t2 values (1, "Jeremy", 4000); +select sys_trx_start into @tmp1 from t1; +select sys_trx_start into @tmp2 from t2; +update t1, t2 set t1.name= "Jerry", t2.name= "Jerry" where t1.id = t2.id and t1.name = "Jeremy"; +select @tmp1 < sys_trx_start as A1, name from t1; +select @tmp2 < sys_trx_start as A2, name from t2; +select sys_trx_start into @tmp1 from t1; +select sys_trx_start into @tmp2 from t2; +update t1, t2 set t1.salary= 2500, t2.salary= 2500 where t1.id = t2.id and t1.name = "Jerry"; +select @tmp1 = sys_trx_start as B1, salary from t1; +select @tmp2 = sys_trx_start as B2, salary from t2; +drop table t1; +drop table t2; +end~~ +call test_01('timestamp(6)', 'myisam', 'sys_trx_end'); +x y +1 1000 +2 2000 +3 3000 +4 4000 +5 5000 +6 6000 +7 7000 +8 8000 +9 9000 +x y +1 1000 +2 2000 +3 3000 +4 4000 +5 5000 +6 6000 +7 7000 +8 8001 +9 9001 +x y +1 1000 +2 2000 +3 3000 +4 4000 +5 5000 +6 6000 +7 7000 +8 8001 +9 9001 +8 8000 +9 9000 +call test_01('timestamp(6)', 'innodb', 'vtq_commit_ts(sys_trx_end)'); +x y +1 1000 +2 2000 +3 3000 +4 4000 +5 5000 +6 6000 +7 7000 +8 8000 +9 9000 +x y +1 1000 +2 2000 +3 3000 +4 4000 +5 5000 +6 6000 +7 7000 +8 8001 +9 9001 +x y +1 1000 +2 2000 +3 3000 +4 4000 +5 5000 +6 6000 +7 7000 +8 8001 +9 9001 +8 8000 +9 9000 +call test_01('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_trx_end)'); +x y +1 1000 +2 2000 +3 3000 +4 4000 +5 5000 +6 6000 +7 7000 +8 8000 +9 9000 +x y +1 1000 +2 2000 +3 3000 +4 4000 +5 5000 +6 6000 +7 7000 +8 8001 +9 9001 +x y +1 1000 +2 2000 +3 3000 +4 4000 +5 5000 +6 6000 +7 7000 +8 8001 +9 9001 +8 8000 +9 9000 +call verify_vtq; +No A B C D +1 1 1 1 1 +2 1 1 1 1 +call test_02('timestamp(6)', 'myisam', 'sys_trx_end'); +A1 x y +1 11 11 +A2 x +1 11 +call test_02('timestamp(6)', 'innodb', 'vtq_commit_ts(sys_trx_end)'); +A1 x y +1 11 11 +A2 x +1 11 +call test_02('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_trx_end)'); +A1 x y +1 11 11 +A2 x +1 11 +call verify_vtq; +No A B C D +1 1 1 1 1 +2 1 1 1 1 +# Multiple UPDATE of same rows in single transaction create historical +# rows only once (applicable to transaction-based only). +call test_03('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_trx_end)'); +x y current +1 1 1 +2 2 1 +3 3 1 +4 2 1 +5 3 1 +3 1 0 +2 1 0 +4 1 0 +5 1 0 +call verify_vtq; +No A B C D +1 1 1 1 1 +2 1 1 1 1 +call test_04('timestamp(6)', 'myisam', 'sys_trx_end'); +x +x +1 +x +2 +x +3 +call test_04('timestamp(6)', 'innodb', 'vtq_commit_ts(sys_trx_end)'); +x +x +1 +x +2 +x +3 +call test_04('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_trx_end)'); +x +x +1 +x +2 +x +3 +call verify_vtq; +No A B C D +1 1 1 1 1 +2 1 1 1 1 +3 1 1 1 1 +call test_05('timestamp(6)', 'myisam', 'sys_trx_end'); +x y +1 1000 +3 3000 +3 3001 +4 4000 +4 4444 +5 5000 +x y +1 1000 +3 3001 +4 4000 +4 4444 +5 5000 +call test_05('timestamp(6)', 'innodb', 'vtq_commit_ts(sys_trx_end)'); +x y +1 1000 +3 3000 +3 3001 +4 4000 +4 4444 +5 5000 +x y +1 1000 +3 3001 +4 4000 +4 4444 +5 5000 +call test_05('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_trx_end)'); +x y +1 1000 +3 3000 +3 3001 +4 4000 +4 4444 +5 5000 +x y +1 1000 +3 3001 +4 4000 +4 4444 +5 5000 +call verify_vtq; +No A B C D +1 1 1 1 1 +2 1 1 1 1 +3 1 1 1 1 +call test_06('timestamp(6)', 'myisam', 'sys_trx_end'); +x y +1 1000 +2 2000 +3 3000 +4 4000 +5 5000 +6 6000 +7 7000 +8 8008 +9 9009 +8 8000 +9 9000 +x y +1 1000 +2 2000 +3 3000 +4 4000 +5 5000 +6 6000 +7 7000 +8 8008 +9 9009 +x y +1 1011 +2 2012 +3 3013 +4 4014 +5 5015 +6 6016 +7 7010 +8 8010 +9 9010 +1 1010 +2 2010 +3 3010 +4 4010 +5 5010 +6 6010 +x y +1 1011 +2 2012 +3 3013 +4 4014 +5 5015 +6 6016 +7 7010 +8 8010 +9 9010 +call test_06('timestamp(6)', 'innodb', 'vtq_commit_ts(sys_trx_end)'); +x y +1 1000 +2 2000 +3 3000 +4 4000 +5 5000 +6 6000 +7 7000 +8 8008 +9 9009 +8 8000 +9 9000 +x y +1 1000 +2 2000 +3 3000 +4 4000 +5 5000 +6 6000 +7 7000 +8 8008 +9 9009 +x y +1 1011 +2 2012 +3 3013 +4 4014 +5 5015 +6 6016 +7 7010 +8 8010 +9 9010 +1 1010 +2 2010 +3 3010 +4 4010 +5 5010 +6 6010 +x y +1 1011 +2 2012 +3 3013 +4 4014 +5 5015 +6 6016 +7 7010 +8 8010 +9 9010 +call test_06('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_trx_end)'); +x y +1 1000 +2 2000 +3 3000 +4 4000 +5 5000 +6 6000 +7 7000 +8 8008 +9 9009 +8 8000 +9 9000 +x y +1 1000 +2 2000 +3 3000 +4 4000 +5 5000 +6 6000 +7 7000 +8 8008 +9 9009 +x y +1 1011 +2 2012 +3 3013 +4 4014 +5 5015 +6 6016 +7 7010 +8 8010 +9 9010 +1 1010 +2 2010 +3 3010 +4 4010 +5 5010 +6 6010 +x y +1 1011 +2 2012 +3 3013 +4 4014 +5 5015 +6 6016 +7 7010 +8 8010 +9 9010 +call verify_vtq; +No A B C D +1 1 1 1 1 +2 1 1 1 1 +3 1 1 1 1 +# Optimized fields +call test_07('timestamp(6)', 'myisam', 'sys_trx_end'); +A1 name +1 Jerry +A2 name +1 Jerry +B1 salary +1 2500 +B2 salary +1 2500 +call test_07('timestamp(6)', 'innodb', 'vtq_commit_ts(sys_trx_end)'); +A1 name +1 Jerry +A2 name +1 Jerry +B1 salary +1 2500 +B2 salary +1 2500 +call test_07('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_trx_end)'); +A1 name +1 Jerry +A2 name +1 Jerry +B1 salary +1 2500 +B2 salary +1 2500 +call verify_vtq; +No A B C D +1 1 1 1 1 +2 1 1 1 1 +3 1 1 1 1 +### Issue #365, bug 7 (duplicate of historical row) +create or replace table t1 (a int primary key, b int) +with system versioning engine myisam; +insert into t1 (a) values (1); +replace t1 values (1,2),(1,3),(2,4); +ERROR 23000: Duplicate entry '1-YYYY-MM-DD hh:mm:ss.uuuuuu' for key 'PRIMARY' +drop database test; +create database test; diff --git a/mysql-test/suite/versioning/r/view.result b/mysql-test/suite/versioning/r/view.result new file mode 100644 index 00000000000..209a7aa77a1 --- /dev/null +++ b/mysql-test/suite/versioning/r/view.result @@ -0,0 +1,120 @@ +create or replace table t1 (x int) with system versioning; +insert into t1 values (1); +select now(6) into @t1; +update t1 set x= 2; +select now(6) into @t2; +delete from t1; +set @vt1= concat("create or replace view vt1 as select * from t1 for system_time as of timestamp '", @t1, "'"); +prepare stmt from @vt1; +execute stmt; +drop prepare stmt; +set @vt2= concat("create or replace view vt2 as select *, row_end from t1 for system_time as of timestamp '", @t2, "'"); +prepare stmt from @vt2; +execute stmt; +drop prepare stmt; +select * from t1; +x +create or replace view vt1 as select * from t1; +show create view vt1; +View Create View character_set_client collation_connection +vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`x` AS `x` from `t1` FOR SYSTEM_TIME ALL where `t1`.`row_end` = MAX_RESULT or `t1`.`row_end` is null latin1 latin1_swedish_ci +drop view vt1; +drop view vt2; +create or replace view vt1 as select * from t1 for system_time all; +select * from vt1; +x +2 +1 +prepare stmt from 'select * from vt1'; +execute stmt; +x +2 +1 +drop prepare stmt; +set @str= concat('create or replace view vt1 as +select * from t1 for system_time as of timestamp "', @t1, '"'); +prepare stmt from @str; +execute stmt; +drop prepare stmt; +select * from t1 for system_time as of timestamp @t1; +x +1 +select * from vt1; +x +1 +insert into vt1 values (3); +select * from t1; +x +3 +select * from vt1; +x +1 +create or replace table t1 (x int) with system versioning; +insert into t1 values (1), (2); +set @t1=now(6); +delete from t1 where x=2; +set @t2=now(6); +delete from t1 where x=1; +set @t3=now(6); +set @tmp= concat("create or replace view vt1 as select * from t1 for system_time as of timestamp '", @t1, "'"); +prepare stmt from @tmp; +execute stmt; +drop prepare stmt; +select * from vt1; +x +1 +2 +# VIEW with parameters [#151] +create or replace table t1 (x int) with system versioning; +create or replace view vt1(c) as select x from t1; +show create view vt1; +View Create View character_set_client collation_connection +vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`x` AS `c` from `t1` FOR SYSTEM_TIME ALL where `t1`.`row_end` = MAX_RESULT or `t1`.`row_end` is null latin1 latin1_swedish_ci +# VIEW over JOIN of versioned tables [#153] +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); +insert into t2 values (2); +create or replace view vt12 as select * from t1 cross join t2; +select * from vt12; +a b +1 2 +create or replace view vt12 as select * from t1 for system_time as of timestamp '0-0-0' cross join t2; +select * from vt12; +a b +# VIEW improvements [#183] +create or replace table t3 (x int); +create or replace view vt1 as select * from t1, t2, t3; +show create view vt1; +View Create View character_set_client collation_connection +vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`a` AS `a`,`t2`.`b` AS `b`,`t3`.`x` AS `x` from ((`t1` FOR SYSTEM_TIME ALL join `t2` FOR SYSTEM_TIME ALL) join `t3`) where (`t1`.`row_end` = MAX_RESULT or `t1`.`row_end` is null) and (`t2`.`row_end` = MAX_RESULT or `t2`.`row_end` is null) latin1 latin1_swedish_ci +create or replace view vt1 as select * from t3, t2, t1; +show create view vt1; +View Create View character_set_client collation_connection +vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t3`.`x` AS `x`,`t2`.`b` AS `b`,`t1`.`a` AS `a` from ((`t3` join `t2` FOR SYSTEM_TIME ALL) join `t1` FOR SYSTEM_TIME ALL) where (`t2`.`row_end` = MAX_RESULT or `t2`.`row_end` is null) and (`t1`.`row_end` = MAX_RESULT or `t1`.`row_end` is null) latin1 latin1_swedish_ci +create or replace view vt1 as select a, t2.row_end as endo from t3, t1, t2; +show create view vt1; +View Create View character_set_client collation_connection +vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`a` AS `a`,`t2`.`row_end` AS `endo` from ((`t3` join `t1` FOR SYSTEM_TIME ALL) join `t2` FOR SYSTEM_TIME ALL) where (`t1`.`row_end` = MAX_RESULT or `t1`.`row_end` is null) and (`t2`.`row_end` = MAX_RESULT or `t2`.`row_end` is null) latin1 latin1_swedish_ci +# VIEW over UNION [#269] +create or replace view vt1 as select * from t1 union select * from t1; +select * from vt1; +a +1 +# VIEW over UNION with non-versioned [#393] +create or replace table t2 (a int); +create or replace view vt1 as select * from t1 union select * from t2; +select * from vt1; +a +1 +# MDEV-14689 crash on second PS execute +create or replace table t1 (a int); +create or replace view v1 as select * from t1; +create or replace table t2 (b int) with system versioning; +prepare stmt from 'select a from v1 inner join t2 group by a order by a'; +execute stmt; +a +execute stmt; +a +drop database test; +create database test; diff --git a/mysql-test/suite/versioning/r/vtmd.result b/mysql-test/suite/versioning/r/vtmd.result new file mode 100644 index 00000000000..ece5f5af61a --- /dev/null +++ b/mysql-test/suite/versioning/r/vtmd.result @@ -0,0 +1,365 @@ +create or replace procedure drop_archives (in vtmd_name varchar(64)) +begin +declare archive_name varchar(64); +declare cur_done bool default false; +declare cur cursor for +select cur_tmp.archive_name from cur_tmp; +declare continue handler for not found set cur_done = true; +set @tmp= concat(' + create or replace temporary table + cur_tmp as + select vtmd.archive_name from ', vtmd_name, ' + for system_time all as vtmd + where vtmd.archive_name is not null + group by vtmd.archive_name'); +prepare stmt from @tmp; execute stmt; drop prepare stmt; +open cur; +fetch_loop: loop +fetch cur into archive_name; +if cur_done then +leave fetch_loop; +end if; +set @tmp= concat('drop table ', archive_name); +prepare stmt from @tmp; execute stmt; drop prepare stmt; +end loop; +drop table cur_tmp; +end~~ +create or replace procedure check_vtmd (in vtmd_name varchar(64)) +begin +set @tmp= concat(' + create or replace temporary table + tmp_vtmd with system versioning as + select * from ', vtmd_name, ' + for system_time all as vtmd'); +prepare stmt from @tmp; execute stmt; drop prepare stmt; +set @inf= 0xFFFFFFFFFFFFFFFF + 0; +set @start= null; +select start from tmp_vtmd for system_time all order by start limit 1 into @start; +select @start > 0 and @start < @inf; +select +start >= @start as A_start, +(@start:= end) and end = @inf as B_end, +name, +substr(archive_name, 1, instr(archive_name, '_')) as C_archive_name +from tmp_vtmd for system_time all; +drop table tmp_vtmd; +end~~ +create or replace procedure show_tables() +begin +show tables; +select table_name, table_schema from information_schema.tables +where table_schema not in ('mysql', 'performance_schema', 'information_schema', 'mtr') +order by table_name; +end~~ +set versioning_alter_history= keep; +create table t0 (z int) with system versioning; +show tables; +Tables_in_test +t0 +set versioning_alter_history= survive; +create or replace table t0 (y int) with system versioning; +show tables; +Tables_in_test +t0 +t0_vtmd +show create table t0_vtmd; +Table Create Table +t0_vtmd CREATE TABLE `t0_vtmd` ( + `start` bigint(20) unsigned GENERATED ALWAYS AS ROW START COMMENT 'TRX_ID of table lifetime start', + `end` bigint(20) unsigned GENERATED ALWAYS AS ROW END NOT NULL COMMENT 'TRX_ID of table lifetime end', + `name` varchar(64) COLLATE utf8_bin NOT NULL COMMENT 'Table name during current lifetime period', + `archive_name` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT 'Name of archive table', + `col_renames` blob DEFAULT NULL COMMENT 'Column name mappings from previous lifetime', + PRIMARY KEY (`end`), + KEY `archive_name` (`archive_name`), + PERIOD FOR SYSTEM_TIME (`start`, `end`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin STATS_PERSISTENT=0 WITH SYSTEM VERSIONING +call check_vtmd('t0_vtmd'); +@start > 0 and @start < @inf +1 +A_start B_end name C_archive_name +1 1 t0 NULL +set versioning_alter_history= keep; +drop table t0; +set versioning_alter_history= survive; +create table t0 (x int) with system versioning; +ERROR HY000: VTMD error: `test.t0_vtmd` exists and not empty! +drop table t0_vtmd; +create table t0 (y int) with system versioning; +create or replace table t0 (x int) with system versioning; +insert into t0 values (1); +set @t0= now(6); +alter table t0 add column (y int); +select * from t0 for system_time as of @t0; +x +1 +select * from t0; +x y +1 NULL +call check_vtmd('t0_vtmd'); +@start > 0 and @start < @inf +1 +A_start B_end name C_archive_name +1 0 t0 t0_ +1 0 t0 t0_ +1 1 t0 NULL +call drop_archives('t0_vtmd'); +drop table t0_vtmd; +alter table t0 drop column y; +call check_vtmd('t0_vtmd'); +@start > 0 and @start < @inf +1 +A_start B_end name C_archive_name +1 1 t0 t0_ +call drop_archives('t0_vtmd'); +set versioning_alter_history= keep; +drop tables t0, t0_vtmd; +set versioning_alter_history= survive; +set versioning_alter_history= keep; +create or replace table x0 (x int) with system versioning; +set versioning_alter_history= survive; +rename table x0 to d0; +show tables; +Tables_in_test +d0 +set versioning_alter_history= keep; +drop table d0; +set versioning_alter_history= survive; +create or replace table x0 (x int) with system versioning; +rename table x0 to d0; +show tables; +Tables_in_test +d0 +d0_vtmd +call check_vtmd('d0_vtmd'); +@start > 0 and @start < @inf +1 +A_start B_end name C_archive_name +1 0 x0 NULL +1 1 d0 NULL +set versioning_alter_history= keep; +drop table d0; +set versioning_alter_history= survive; +create or replace table x0 (x int) with system versioning; +rename table x0 to d0; +ERROR HY000: VTMD error: `test.d0_vtmd` table already exists! +show tables; +Tables_in_test +d0_vtmd +x0 +x0_vtmd +drop table x0_vtmd; +rename table x0 to d0; +Warnings: +Warning 4122 `test.d0_vtmd` table already exists! +show tables; +Tables_in_test +d0 +d0_vtmd +rename table d0 to duck; +rename table duck to bay; +rename table bay to sheer; +rename table sheer to t0; +call check_vtmd('t0_vtmd'); +@start > 0 and @start < @inf +1 +A_start B_end name C_archive_name +1 0 x0 NULL +1 0 d0 NULL +1 0 duck NULL +1 0 bay NULL +1 0 sheer NULL +1 1 t0 NULL +alter table t0 add column (y int); +call check_vtmd('t0_vtmd'); +@start > 0 and @start < @inf +1 +A_start B_end name C_archive_name +1 0 x0 t0_ +1 0 d0 t0_ +1 0 duck t0_ +1 0 bay t0_ +1 0 sheer t0_ +1 0 t0 t0_ +1 1 t0 NULL +alter table t0 add column (z int); +alter table t0 drop column y; +alter table t0 drop column z; +create database db0; +rename table t0 to db0.t0; +show tables; +Tables_in_test +use db0; +show tables; +Tables_in_db0 +t0 +t0_vtmd +call test.check_vtmd('db0.t0_vtmd'); +@start > 0 and @start < @inf +1 +A_start B_end name C_archive_name +1 0 x0 t0_ +1 0 d0 t0_ +1 0 duck t0_ +1 0 bay t0_ +1 0 sheer t0_ +1 0 t0 t0_ +1 0 t0 t0_ +1 0 t0 t0_ +1 0 t0 t0_ +1 1 t0 NULL +create database db1; +rename table t0 to db1.other_name; +show tables; +Tables_in_db0 +use db1; +show tables; +Tables_in_db1 +other_name +other_name_vtmd +call test.check_vtmd('db1.other_name_vtmd'); +@start > 0 and @start < @inf +1 +A_start B_end name C_archive_name +1 0 x0 t0_ +1 0 d0 t0_ +1 0 duck t0_ +1 0 bay t0_ +1 0 sheer t0_ +1 0 t0 t0_ +1 0 t0 t0_ +1 0 t0 t0_ +1 0 t0 t0_ +1 0 t0 NULL +1 1 other_name NULL +alter table other_name rename to t1; +call test.check_vtmd('db1.t1_vtmd'); +@start > 0 and @start < @inf +1 +A_start B_end name C_archive_name +1 0 x0 t0_ +1 0 d0 t0_ +1 0 duck t0_ +1 0 bay t0_ +1 0 sheer t0_ +1 0 t0 t0_ +1 0 t0 t0_ +1 0 t0 t0_ +1 0 t0 t0_ +1 0 t0 NULL +1 0 other_name NULL +1 1 t1 NULL +alter table t1 rename to test.t2, add column (y int); +use test; +show tables; +Tables_in_test +t2 +t2_vtmd +call check_vtmd('t2_vtmd'); +@start > 0 and @start < @inf +1 +A_start B_end name C_archive_name +1 0 x0 t0_ +1 0 d0 t0_ +1 0 duck t0_ +1 0 bay t0_ +1 0 sheer t0_ +1 0 t0 t0_ +1 0 t0 t0_ +1 0 t0 t0_ +1 0 t0 t0_ +1 0 t0 t1_ +1 0 other_name t1_ +1 0 t1 t1_ +1 1 t2 NULL +create or replace table t3 (x int) with system versioning; +alter table t3 change x x bigint; +alter table t3 change x x bigint after sys_trx_start; +call check_vtmd('t3_vtmd'); +@start > 0 and @start < @inf +1 +A_start B_end name C_archive_name +1 0 t3 t3_ +1 0 t3 t3_ +1 1 t3 NULL +set versioning_hide= auto; +call show_tables(); +Tables_in_test +t2 +t2_vtmd +t3 +t3_vtmd +table_name table_schema +t2 test +t2_vtmd test +t3 test +t3_vtmd test +set versioning_hide= implicit; +call show_tables(); +Tables_in_test +t2 +t2_vtmd +t3 +t3_vtmd +table_name table_schema +t2 test +t2_vtmd test +t3 test +t3_vtmd test +set versioning_hide= full; +call show_tables(); +Tables_in_test +t2 +t2_vtmd +t3 +t3_vtmd +table_name table_schema +t2 test +t2_vtmd test +t3 test +t3_vtmd test +set versioning_hide= never; +call show_tables(); +Tables_in_test +t0_TIMESTAMP_SUFFIX +t0_TIMESTAMP_SUFFIX +t0_TIMESTAMP_SUFFIX +t0_TIMESTAMP_SUFFIX +t2 +t2_vtmd +t3 +t3_TIMESTAMP_SUFFIX +t3_TIMESTAMP_SUFFIX +t3_vtmd +table_name table_schema +t0_TIMESTAMP_SUFFIX test +t0_TIMESTAMP_SUFFIX test +t0_TIMESTAMP_SUFFIX test +t0_TIMESTAMP_SUFFIX test +t1_TIMESTAMP_SUFFIX db1 +t2 test +t2_vtmd test +t3 test +t3_TIMESTAMP_SUFFIX test +t3_TIMESTAMP_SUFFIX test +t3_vtmd test +set versioning_hide= auto; +create or replace table u0_vtmd (x int) with system versioning; +show tables; +Tables_in_test +t2 +t2_vtmd +t3 +t3_vtmd +u0_vtmd +u0_vtmd_vtmd +Warnings: +Warning 4122 Table `test.u0_vtmd` is not a VTMD table +set versioning_alter_history= survive; +create or replace table t (x int) with system versioning; +select * from t for system_time all; +x sys_trx_start sys_trx_end +drop database db0; +drop database db1; +drop database test; +create database test; diff --git a/mysql-test/suite/versioning/r/vtmd_show.result b/mysql-test/suite/versioning/r/vtmd_show.result new file mode 100644 index 00000000000..4c77182c5de --- /dev/null +++ b/mysql-test/suite/versioning/r/vtmd_show.result @@ -0,0 +1,229 @@ +create or replace procedure drop_archives (in vtmd_name varchar(64)) +begin +declare archive_name varchar(64); +declare cur_done bool default false; +declare cur cursor for +select cur_tmp.archive_name from cur_tmp; +declare continue handler for not found set cur_done = true; +set @tmp= concat(' + create or replace temporary table + cur_tmp as + select vtmd.archive_name from ', vtmd_name, ' + for system_time all as vtmd + where vtmd.archive_name is not null + group by vtmd.archive_name'); +prepare stmt from @tmp; execute stmt; drop prepare stmt; +open cur; +fetch_loop: loop +fetch cur into archive_name; +if cur_done then +leave fetch_loop; +end if; +set @tmp= concat('drop table ', archive_name); +prepare stmt from @tmp; execute stmt; drop prepare stmt; +end loop; +drop table cur_tmp; +end~~ +create procedure test_01(in engine varchar(64)) +begin +set @tmp = concat('create table t (a int) with system versioning engine ', engine); +prepare stmt from @tmp; execute stmt; drop prepare stmt; +set @tm1 = now(6); +alter table t add column b int; +set @tm2 = now(6); +alter table t add column c int; +show create table t for system_time as of timestamp @tm1; +show create table t for system_time as of timestamp @tm2; +show create table t for system_time as of now; +show create table t for system_time as of timestamp now(6); +show create table t; +set @tm3 = now(6); +rename table t to tt; +show create table tt for system_time as of timestamp @tm3; +set @tm4 = now(6); +alter table tt add column d int; +show create table tt for system_time as of timestamp @tm3; +show create table tt for system_time as of timestamp @tm4; +show create table tt; +drop table tt; +call drop_archives('tt_vtmd'); +drop table tt_vtmd; +end~~ +create table t (a int) with system versioning; +show create table t for system_time as of now; +ERROR HY000: VTMD error: Table 'test.t_vtmd' doesn't exist +set versioning_alter_history=survive; +create or replace table t (a int) with system versioning; +show create table t for system_time between timestamp @tm1 and timestamp @tm1; +ERROR HY000: SYSTEM_TIME range selector is prohibited +show create table t for system_time from timestamp @tm1 to timestamp @tm1; +ERROR HY000: SYSTEM_TIME range selector is prohibited +show create table t for system_time as of timestamp '01-01-1990'; +ERROR HY000: VTMD error: Table 'test.t' doesn't exist +show create table t for system_time as of timestamp '01-01-2020'; +ERROR HY000: VTMD error: Table 'test.t' doesn't exist +drop table t; +call drop_archives('t_vtmd'); +drop table t_vtmd; +call test_01('myisam'); +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL, + `sys_trx_start` timestamp(6) GENERATED ALWAYS AS ROW START, + `sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END, + PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL, + `sys_trx_start` timestamp(6) GENERATED ALWAYS AS ROW START, + `sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END, + `b` int(11) DEFAULT NULL, + PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL, + `sys_trx_start` timestamp(6) GENERATED ALWAYS AS ROW START, + `sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL, + `sys_trx_start` timestamp(6) GENERATED ALWAYS AS ROW START, + `sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL, + `sys_trx_start` timestamp(6) GENERATED ALWAYS AS ROW START, + `sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +Table Create Table +tt CREATE TABLE `tt` ( + `a` int(11) DEFAULT NULL, + `sys_trx_start` timestamp(6) GENERATED ALWAYS AS ROW START, + `sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +Table Create Table +tt CREATE TABLE `tt` ( + `a` int(11) DEFAULT NULL, + `sys_trx_start` timestamp(6) GENERATED ALWAYS AS ROW START, + `sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +Table Create Table +tt CREATE TABLE `tt` ( + `a` int(11) DEFAULT NULL, + `sys_trx_start` timestamp(6) GENERATED ALWAYS AS ROW START, + `sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +Table Create Table +tt CREATE TABLE `tt` ( + `a` int(11) DEFAULT NULL, + `sys_trx_start` timestamp(6) GENERATED ALWAYS AS ROW START, + `sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + `d` int(11) DEFAULT NULL, + PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +call test_01('innodb'); +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL, + `sys_trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START, + `sys_trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END, + PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL, + `sys_trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START, + `sys_trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END, + `b` int(11) DEFAULT NULL, + PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL, + `sys_trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START, + `sys_trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL, + `sys_trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START, + `sys_trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL, + `sys_trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START, + `sys_trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +Table Create Table +tt CREATE TABLE `tt` ( + `a` int(11) DEFAULT NULL, + `sys_trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START, + `sys_trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +Table Create Table +tt CREATE TABLE `tt` ( + `a` int(11) DEFAULT NULL, + `sys_trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START, + `sys_trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +Table Create Table +tt CREATE TABLE `tt` ( + `a` int(11) DEFAULT NULL, + `sys_trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START, + `sys_trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +Table Create Table +tt CREATE TABLE `tt` ( + `a` int(11) DEFAULT NULL, + `sys_trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START, + `sys_trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + `d` int(11) DEFAULT NULL, + PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +drop procedure test_01; +drop procedure drop_archives; diff --git a/mysql-test/suite/versioning/t/alter.test b/mysql-test/suite/versioning/t/alter.test new file mode 100644 index 00000000000..5e4efb036c6 --- /dev/null +++ b/mysql-test/suite/versioning/t/alter.test @@ -0,0 +1,395 @@ +select @@system_versioning_alter_history; + +create table t( + a int +); +show create table t; +--error ER_VERS_NOT_VERSIONED +alter table t drop system versioning; + +alter table t add system versioning; +show create table t; + +--error ER_VERS_ALTER_NOT_ALLOWED +alter table t add column y int; +--error ER_VERS_ALTER_ENGINE_PROHIBITED +alter table t engine innodb; + +alter table t drop system versioning; +show create table t; + +set system_versioning_alter_history= keep; + +--error ER_VERS_FIELD_WRONG_TYPE +alter table t + add column trx_start bigint(20) unsigned as row start invisible, + add column trx_end bigint(20) unsigned as row end invisible, + add period for system_time(trx_start, trx_end), + add system versioning; + +--error ER_VERS_FIELD_WRONG_TYPE +alter table t + add column trx_start timestamp as row start invisible, + add column trx_end timestamp as row end invisible, + add period for system_time(trx_start, trx_end), + add system versioning; + +--error ER_PARSE_ERROR +alter table t + add column trx_start timestamp(6) not null as row start invisible, + add column trx_end timestamp(6) not null as row end invisible, + add period for system_time(trx_start, trx_end), + add system versioning; + +alter table t + add column trx_start timestamp(6) as row start invisible, + add column trx_end timestamp(6) as row end invisible, + add period for system_time(trx_start, trx_end), + add system versioning; +show create table t; + +alter table t drop column trx_start, drop column trx_end; +alter table t drop system versioning; +show create table t; + +alter table t add system versioning; +show create table t; + +alter table t add column b int; +show create table t; + +alter table t add column c int; +show create table t; + +alter table t add column d int first; +show create table t; + +alter table t add column e int after d; +show create table t; + +alter table t drop column a; +show create table t; + +create or replace table t ( + a int, + row_start timestamp(6) as row start invisible, + row_end timestamp(6) as row end invisible, + period for system_time(row_start, row_end)) +with system versioning; + +select * from t for system_time all; +--error ER_MISSING +alter table t drop column row_start; +--error ER_MISSING +alter table t drop column row_end; +alter table t drop column row_start, drop column row_end; +select * from t for system_time all; + +--error ER_CANT_DROP_FIELD_OR_KEY +alter table t drop column row_start; +--error ER_CANT_DROP_FIELD_OR_KEY +alter table t drop column row_end; + +create or replace table t ( + a int, + row_start timestamp(6) as row start invisible, + row_end timestamp(6) as row end invisible, + period for system_time(row_start, row_end)) +with system versioning; + +select * from t for system_time all; +alter table t drop column row_start, drop column row_end; +select * from t for system_time all; + +create or replace table t( + a int +); +insert into t values(1); +alter table t add system versioning; +show create table t; +insert into t values(2); +select * from t for system_time all; +select * from t; + +update t set a=3 where a=1; +select * from t; +select * from t for system_time all; +select row_start from t where a=3 into @tm; +alter table t add column b int; +select @tm=row_start from t where a=3; +show create table t; +select * from t; +select * from t for system_time all; + +alter table t drop system versioning; +select * from t; +show create table t; + +--error ER_VERS_NOT_VERSIONED +alter table t modify a int with system versioning; +--error ER_VERS_NOT_VERSIONED +alter table t modify a int without system versioning; + +alter table t add system versioning; + +alter table t modify a int without system versioning; +show create table t; + +alter table t modify a int with system versioning; +show create table t; + +# TODO: move TRX_ID cases to separate test +-- source suite/versioning/common.inc +create or replace table t( + a int +) engine=innodb; + +alter table t + add column trx_start timestamp(6) as row start invisible, + add column trx_end timestamp(6) as row end invisible, + add period for system_time(trx_start, trx_end), + add system versioning; + +show create table t; +--echo # Issue #211: drop of system columns required before drop system versioning +alter table t drop column trx_start, drop column trx_end; +show create table t; + +alter table t drop system versioning; + +insert into t values(1); + +call verify_vtq; +alter table t + add column trx_start bigint(20) unsigned as row start invisible, + add column trx_end bigint(20) unsigned as row end invisible, + add period for system_time(trx_start, trx_end), + add system versioning; +call verify_vtq; + +show create table t; +alter table t drop column trx_start, drop column trx_end; + +call verify_vtq; +alter table t drop system versioning, algorithm=copy; +call verify_vtq; + +alter table t add system versioning, algorithm=copy; +call verify_vtq; + +show create table t; + +update t set a= 2; +select * from t for system_time all; + +alter table t add column b int, algorithm=copy; +show create table t; +select * from t; +call verify_vtq; + +alter table t drop column b, algorithm=copy; +show create table t; +select * from t for system_time all; +call verify_vtq; + +## FIXME: #414 IB: inplace for VERS_TIMESTAMP versioning +if (0) +{ +alter table t drop system versioning, algorithm=inplace; +call verify_vtq; + +alter table t add system versioning, algorithm=inplace; +call verify_vtq; +show create table t; + +update t set a= 1; +select * from t for system_time all; +call verify_vtq; + +alter table t add column b int, algorithm=inplace; +show create table t; +select * from t; +call verify_vtq; + +alter table t drop column b, algorithm=inplace; +show create table t; +select * from t for system_time all; +} +## FIXME END + +alter table t drop system versioning, algorithm=copy; +show create table t; +call verify_vtq; + +# nullable autoinc test w/o versioning +create or replace table t (a int); +insert t values (1),(2),(3),(4); +alter table t add b int auto_increment null unique; +select * from t; +drop table t; + +create or replace table t (a int) with system versioning engine=innodb; +insert into t values (1), (2), (3); +delete from t where a<3; +--error ER_DUP_ENTRY, ER_DUP_ENTRY +alter table t add b int not null unique; +--error ER_UNSUPPORTED_EXTENSION, ER_UNSUPPORTED_EXTENSION +alter table t add b int auto_increment unique; +alter table t add b int auto_increment null unique; +select * from t; +select * from t for system_time all; +insert into t values (4, 0); +select * from t for system_time all; + +create or replace table t (a int) with system versioning; +insert into t values (1), (2), (3); +delete from t where a<3; +--error ER_DUP_ENTRY, ER_DUP_ENTRY +alter table t add b int not null unique; +--error ER_UNSUPPORTED_EXTENSION, ER_UNSUPPORTED_EXTENSION +alter table t add b int auto_increment unique; +alter table t add b int auto_increment null unique; +select * from t; +select * from t for system_time all; +insert into t values (4, 0); +select * from t for system_time all; + +create or replace table t ( + a int, + row_start timestamp(6) as row start invisible, + row_end timestamp(6) as row end invisible, + period for system_time(row_start, row_end) +) with system versioning; +--error ER_VERS_ALTER_SYSTEM_FIELD +alter table t change column row_start asdf timestamp(6); +insert into t values (1); +--error ER_VERS_ALTER_SYSTEM_FIELD +alter table t modify column row_start bigint unsigned; + +## These experimental options are now disabled + +--error ER_WRONG_VALUE_FOR_VAR +set system_versioning_alter_history= SURVIVE; + +--error ER_WRONG_VALUE_FOR_VAR +set system_versioning_alter_history= 'DROP'; + +if (0) +{ +create or replace table t (a int) with system versioning engine innodb; +insert into t values (1); +update t set a = 2; +select * from t for system_time all; +alter table t add column b int; +select * from t for system_time all; + +create or replace table t (a int) with system versioning engine myisam; +insert into t values (1); +update t set a = 2; +select * from t for system_time all; +alter table t add column b int; +select * from t for system_time all; + +create or replace table non_empty ( + a int, + row_start bigint(20) unsigned, + row_end bigint(20) unsigned +) engine innodb; +insert into non_empty values (1, 100, 200); + +--error ER_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN +alter table non_empty + change column row_start row_start bigint(20) unsigned as row start invisible; +--error ER_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN +alter table non_empty + change column row_end row_end bigint(20) unsigned as row end invisible; +drop table non_empty; + +create or replace table t (a int primary key) with system versioning; +insert into t values (1); +update t set a=2; +alter table t drop primary key, add primary key (a), drop system versioning; +select * from t; +--replace_result InnoDB INNODB_OR_MYISAM MyISAM INNODB_OR_MYISAM +show create table t; + +create or replace table t (a int primary key) with system versioning; +insert into t values (1); +update t set a=2; +alter table t drop system versioning; +select * from t; +--replace_result InnoDB INNODB_OR_MYISAM MyISAM INNODB_OR_MYISAM +show create table t; + + +call verify_vtq; +} + +create or replace table t (a int) with system versioning; +--error ER_VERS_ALREADY_VERSIONED +alter table t add system versioning; +--error ER_VERS_ALREADY_VERSIONED +alter table t add system versioning, drop system versioning; + +set @@system_versioning_alter_history=keep; +create or replace table t(x int, y int) with system versioning engine=innodb; +alter table t modify y int without system versioning; +insert into t values(1, 1); +update t set y=2; + +--echo # MDEV-14681 Bogus ER_UNSUPPORTED_EXTENSION +create or replace table t1 (pk int auto_increment unique) with system versioning; +insert into t1 values (1); +delete from t1; +alter table t1 engine=myisam; + +--echo # MDEV-14692 crash in MDL_context::upgrade_shared_lock() +create or replace temporary table t (a int); +--error ER_VERS_TEMPORARY +alter table t change column if exists b c bigint unsigned generated always as row start; +--error ER_VERS_TEMPORARY +alter table t change column if exists b c bigint unsigned generated always as row end; +--error ER_VERS_TEMPORARY +alter table t add system versioning; +drop table t; + +--echo # MDEV-14744 trx_id-based and transaction-based mixup in assertion +create or replace table t (c text) engine=innodb with system versioning; +show create table t; +alter table t add fulltext key (c); + +create or replace table t (a int) with system versioning; +--error ER_VERS_TABLE_MUST_HAVE_COLUMNS +alter table t drop column a; +--error ER_CANT_DROP_FIELD_OR_KEY +alter table t drop column a, drop column a; + +create or replace table t1 (row_start int); +--error ER_DUP_FIELDNAME +alter table t1 with system versioning; + +create or replace table t1 (row_end int); +--error ER_DUP_FIELDNAME +alter table t1 with system versioning; + +--error ER_DUP_FIELDNAME +create or replace table t1 (a int, row_start int) with system versioning; + +create or replace table t1 (a int) with system versioning; + +--error ER_DUP_FIELDNAME +set statement system_versioning_alter_history=keep for +alter table t1 add column row_start int; + +--error ER_DUP_FIELDNAME +set statement system_versioning_alter_history=keep for +alter table t1 add column row_start timestamp(6); + +--echo # MDEV-14798 Add, drop system versioning semantic and syntax +create or replace table t (a int) with system versioning; + +--error ER_VERS_ALREADY_VERSIONED +alter table t add period for system_time(sys_trx_start, sys_trx_end); + +drop database test; +create database test; diff --git a/mysql-test/suite/versioning/t/auto_increment.test b/mysql-test/suite/versioning/t/auto_increment.test new file mode 100644 index 00000000000..6108f6d9818 --- /dev/null +++ b/mysql-test/suite/versioning/t/auto_increment.test @@ -0,0 +1,68 @@ +-- source suite/versioning/common.inc + +delimiter ~~; +create procedure test_01( + sys_type varchar(255), + engine varchar(255), + fields varchar(255)) +begin + set @str= concat(' + create table t1( + id int unsigned auto_increment primary key, + x int unsigned, + y int unsigned, + sys_start ', sys_type, ' as row start invisible, + sys_end ', sys_type, ' as row end invisible, + period for system_time (sys_start, sys_end)) + with system versioning + engine ', engine); + prepare stmt from @str; execute stmt; drop prepare stmt; + + set @str= concat(' + create table t2( + id int unsigned auto_increment primary key, + x int unsigned, + y int unsigned) + engine ', engine); + prepare stmt from @str; execute stmt; drop prepare stmt; + + insert into t1(x, y) values(1, 11); + insert into t2(x, y) values(1, 11); + insert into t1(x, y) values(2, 12); + insert into t2(x, y) values(2, 12); + insert into t1(x, y) values(3, 13); + insert into t2(x, y) values(3, 13); + insert into t1(x, y) values(4, 14); + insert into t2(x, y) values(4, 14); + insert into t1(x, y) values(5, 15); + insert into t2(x, y) values(5, 15); + insert into t1(x, y) values(6, 16); + insert into t2(x, y) values(6, 16); + insert into t1(x, y) values(7, 17); + insert into t2(x, y) values(7, 17); + insert into t1(x, y) values(8, 18); + insert into t2(x, y) values(8, 18); + insert into t1(x, y) values(9, 19); + insert into t2(x, y) values(9, 19); + + select t1.x = t2.x and t1.y = t2.y as A, t1.x, t1.y, t2.x, t2.y from t1 inner join t2 on t1.id = t2.id; + delete from t1 where x = 2; + delete from t2 where x = 2; + + select t1.x = t2.x and t1.y = t2.y as A, t1.x, t1.y, t2.x, t2.y from t1 inner join t2 on t1.id = t2.id; + delete from t1 where x > 7; + delete from t2 where x > 7; + + select t1.x = t2.x and t1.y = t2.y as A, t1.x, t1.y, t2.x, t2.y from t1 inner join t2 on t1.id = t2.id; + drop table t1; + drop table t2; +end~~ +delimiter ;~~ + +call test_01('timestamp(6)', 'myisam', 'sys_end'); +call test_01('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_end)'); +call verify_vtq; + +drop procedure test_01; + +-- source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/t/commit_id.test b/mysql-test/suite/versioning/t/commit_id.test new file mode 100644 index 00000000000..66a9db64e10 --- /dev/null +++ b/mysql-test/suite/versioning/t/commit_id.test @@ -0,0 +1,94 @@ +-- source suite/versioning/common.inc + +create table t1( + id int auto_increment primary key, + sys_trx_start bigint unsigned as row start invisible, + sys_trx_end bigint unsigned as row end invisible, + period for system_time (sys_trx_start, sys_trx_end) +) +with system versioning +engine innodb; + + +# VTQ_TRX_ID, VTQ_COMMIT_ID, VTQ_TRX_SEES # + +insert into t1 values (); + +--real_sleep 0.01 +set @ts0= now(6); +insert into t1 values (); +select sys_trx_start from t1 where id = last_insert_id() into @tx0; +select transaction_id = @tx0 from mysql.transaction_registry +order by transaction_id desc limit 1; + +set @ts1= now(6); +insert into t1 values (); +select sys_trx_start from t1 where id = last_insert_id() into @tx1; +select transaction_id = @tx1 from mysql.transaction_registry +order by transaction_id desc limit 1; + +set @ts2= now(6); +insert into t1 values (); +select sys_trx_start from t1 where id = last_insert_id() into @tx2; +select transaction_id = @tx2 from mysql.transaction_registry +order by transaction_id desc limit 1; + +set @ts3= now(6); + +select + vtq_trx_id(@ts0) < @tx0 as A, + vtq_trx_id(@ts0, true) = @tx0 as B, + vtq_trx_id(@ts1) = @tx0 as C, + vtq_trx_id(@ts1, true) = @tx1 as D, + vtq_trx_id(@ts2) = @tx1 as E, + vtq_trx_id(@ts2, true) = @tx2 as F, + vtq_trx_id(@ts3) = @tx2 as G, + vtq_trx_id(@ts3, true) is null as H; + +select + vtq_commit_id(@ts0) < @tx0 as A, + vtq_commit_id(@ts0, true) = vtq_commit_id(null, @tx0) as B, + vtq_commit_id(@ts1) = vtq_commit_id(null, @tx0) as C, + vtq_commit_id(@ts1, true) = vtq_commit_id(null, @tx1) as D, + vtq_commit_id(@ts2) = vtq_commit_id(null, @tx1) as E, + vtq_commit_id(@ts2, true) = vtq_commit_id(null, @tx2) as F, + vtq_commit_id(@ts3) = vtq_commit_id(null, @tx2) as G, + vtq_commit_id(@ts3, true) is null as H; + +select + vtq_trx_sees(@tx1, @tx0) as A, + not vtq_trx_sees(@tx0, @tx1) as B, + vtq_trx_sees_eq(@tx1, @tx1) as C, + not vtq_trx_sees(@tx1, @tx1) as D, + vtq_trx_sees(@tx2, 0) as E, + vtq_trx_sees(0, @tx2) is null as F, + vtq_trx_sees(-1, @tx2) as H; + + +# VTQ_ISO_LEVEL # + +set transaction isolation level read uncommitted; +insert into t1 values (); +select sys_trx_start from t1 where id = last_insert_id() into @tx3; +select isolation_level = 'READ-UNCOMMITTED' from mysql.transaction_registry where transaction_id = @tx3; + +set transaction isolation level read committed; +insert into t1 values (); +select sys_trx_start from t1 where id = last_insert_id() into @tx4; +select isolation_level = 'READ-COMMITTED' from mysql.transaction_registry where transaction_id = @tx4; + +set transaction isolation level serializable; +insert into t1 values (); +select sys_trx_start from t1 where id = last_insert_id() into @tx5; +select isolation_level = 'SERIALIZABLE' from mysql.transaction_registry where transaction_id = @tx5; + +set transaction isolation level repeatable read; +insert into t1 values (); +select sys_trx_start from t1 where id = last_insert_id() into @tx6; +select isolation_level = 'REPEATABLE-READ' from mysql.transaction_registry where transaction_id = @tx6; + + +drop table t1; +call verify_vtq; + +-- source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/t/create.test b/mysql-test/suite/versioning/t/create.test new file mode 100644 index 00000000000..24d8d335020 --- /dev/null +++ b/mysql-test/suite/versioning/t/create.test @@ -0,0 +1,367 @@ +--source suite/versioning/engines.inc +--source suite/versioning/common.inc + +--disable_warnings +drop table if exists t1; +--enable_warnings + +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype_expl SYS_DATATYPE NULL '' +eval create table t1 ( + x1 int unsigned, + Sys_start $sys_datatype_expl as row start invisible comment 'start', + Sys_end $sys_datatype_expl as row end invisible comment 'end', + period for system_time (Sys_start, Sys_end) +) with system versioning; +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype_expl SYS_DATATYPE +show create table t1; + +--query_vertical select table_catalog,table_schema,table_name,table_type,version,table_rows,avg_row_length,data_free,auto_increment,check_time,table_collation,checksum,create_options,table_comment from information_schema.tables where table_name='t1' +--query_vertical select table_catalog,table_schema,table_name,column_name,ordinal_position,column_default,character_maximum_length,character_octet_length,character_set_name,collation_name,column_key,extra,column_comment,is_generated,generation_expression from information_schema.columns where table_name='t1' + +--echo # Implicit fields test +create or replace table t1 ( + x2 int unsigned +) with system versioning; +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE +show create table t1; + +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE +--error ER_VERS_PERIOD_COLUMNS +eval create or replace table t1 ( + x3 int unsigned, + Sys_start $sys_datatype as row start invisible, + Sys_end $sys_datatype as row end invisible, + period for system_time (x, Sys_end) +) with system versioning; + +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE +--error ER_VERS_PERIOD_COLUMNS +eval create or replace table t1 ( + x4 int unsigned, + Sys_start $sys_datatype as row start invisible, + Sys_end2 $sys_datatype as row end invisible, + period for system_time (Sys_start, Sys_end) +) with system versioning; + +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE +--error ER_VERS_PERIOD_COLUMNS +eval create or replace table t1 ( + x5 int unsigned, + Sys_start $sys_datatype as row start invisible, + Sys_end $sys_datatype as row end invisible, + period for system_time (Sys_start, x) +) with system versioning; + +--error ER_MISSING +create or replace table t1 ( + x6 int unsigned, + period for system_time (Sys_start, Sys_end) +) with system versioning; + +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE +--error ER_MISSING +eval create or replace table t1 ( + x7 int unsigned, + Sys_start $sys_datatype as row start invisible, + Sys_end $sys_datatype as row end invisible, + period for system_time (Sys_start, Sys_end) +); + +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE +--error ER_VERS_PERIOD_COLUMNS +eval create or replace table t1 ( + x8 int unsigned, + Sys_start $sys_datatype as row start invisible, + Sys_end $sys_datatype as row end invisible, + period for system_time (sys_insert, sys_remove) +) with system versioning; + +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE +--error ER_MISSING +eval create or replace table t1 ( + x9 int unsigned, + Sys_start $sys_datatype as row start invisible, + Sys_end $sys_datatype as row end invisible, + period for system_time (Sys_start, Sys_end) +); + +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE +--error ER_MISSING +eval create or replace table t1 ( + x10 int unsigned, + Sys_start $sys_datatype as row start invisible, + Sys_end $sys_datatype as row end invisible, + period for system_time (Sys_start, Sys_start) +); + +--error ER_VERS_FIELD_WRONG_TYPE, ER_VERS_FIELD_WRONG_TYPE +create or replace table t1 ( + x11 int unsigned, + Sys_start bigint unsigned as row start invisible, + Sys_end timestamp(6) as row end invisible, + period for system_time (Sys_start, Sys_end) +) with system versioning; + +--error ER_VERS_FIELD_WRONG_TYPE, ER_VERS_FIELD_WRONG_TYPE +create or replace table t1 ( + x12 int unsigned, + Sys_start timestamp(6) as row start invisible, + Sys_end bigint unsigned as row end invisible, + period for system_time (Sys_start, Sys_end) +) with system versioning; + +--error ER_VERS_FIELD_WRONG_TYPE +create or replace table t1 ( + x13 int unsigned, + Sys_start bigint as row start invisible, + Sys_end bigint unsigned as row end invisible, + period for system_time (Sys_start, Sys_end) +) with system versioning engine innodb; + +--error ER_VERS_FIELD_WRONG_TYPE +create or replace table t1 ( + x14 int unsigned, + Sys_start bigint unsigned as row start invisible, + Sys_end bigint as row end invisible, + period for system_time (Sys_start, Sys_end) +) with system versioning engine innodb; + +# columns with/without system versioning + +create or replace table t1 ( + x15 int with system versioning, + B int +); +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE +show create table t1; + +create or replace table t1 ( + x16 int with system versioning, + B int +) with system versioning; +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE +show create table t1; + +create or replace table t1 ( + x17 int, + B int without system versioning +); + +create or replace table t1 ( + x18 int, + B int without system versioning +) with system versioning; +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE +show create table t1; + +create or replace table t1 ( + x19 int with system versioning, + B int without system versioning +); +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE +show create table t1; + +create or replace table t1 ( + x20 int with system versioning, + B int without system versioning +) with system versioning; +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE +show create table t1; + +create or replace table t1 ( + x21 int without system versioning +); + +--error ER_VERS_TABLE_MUST_HAVE_COLUMNS +create or replace table t1 ( + x22 int without system versioning +) with system versioning; + +# CREATE TABLE ... LIKE +create or replace table t1 (a int) with system versioning; +create table tt1 like t1; +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE +show create table tt1; +drop table tt1; +create temporary table tt1 like t1; +--echo # Temporary is stripped from versioning +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE +show create table tt1; + +--echo # CREATE TABLE ... SELECT +create or replace table t1 (x23 int) with system versioning; +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE +eval create or replace table t0( + y int, + st $sys_datatype as row start, + en $sys_datatype as row end, + period for system_time (st, en) +) with system versioning; + +--echo ## For non-versioned table: +--echo ### 1. invisible fields are not included +create or replace table t2 as select * from t1; +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE +show create table t2; + +--echo ### 2. all visible fields are included +create or replace table t3 as select * from t0; +select * from t0; +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE $sys_datatype_null SYS_DATATYPE $sys_datatype_not_null SYS_DATATYPE $sys_datatype_default_null SYS_DATATYPE +show create table t3; + +--echo ## For versioned table +insert into t1 values (1); +select row_start from t1 into @row_start; +insert into t0 (y) values (2); +select st from t0 into @st; + +create or replace table t2 with system versioning as select * from t1; +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE +show create table t2; +--echo #### invisible fields are not copied +select * from t2; +select * from t2 where row_start <= @row_start; + +--echo ### 2. source table with visible system fields, target with invisible +create or replace table t3 with system versioning as select * from t0; +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE $sys_datatype_null SYS_DATATYPE $sys_datatype_not_null SYS_DATATYPE $sys_datatype_default_null SYS_DATATYPE +show create table t3; +select * from t3 where y > 2; +select y from t3 where st = @st and row_start > @st; + +--echo ### 3. source and target table with visible system fields +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE +eval create or replace table t3 ( + st $sys_datatype as row start invisible, + en $sys_datatype as row end invisible, + period for system_time (st, en) +) with system versioning as select * from t0; +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE $sys_datatype_null SYS_DATATYPE $sys_datatype_not_null SYS_DATATYPE $sys_datatype_default_null SYS_DATATYPE +show create table t3; +select y from t3; +select y from t3 where st = @st; + +--echo ### 4. system fields not or wrongly selected +create or replace table t3 with system versioning select x23 from t1; +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE $sys_datatype_null SYS_DATATYPE $sys_datatype_not_null SYS_DATATYPE $sys_datatype_default_null SYS_DATATYPE +show create table t3; +select * from t3; +--error ER_MISSING +create or replace table t3 with system versioning select x23, row_start from t1; +--error ER_MISSING +create or replace table t3 with system versioning select x23, row_end from t1; + +--echo # Prepare checking for historical row +delete from t1; +select row_end from t1 for system_time all into @row_end; +delete from t0; +select en from t0 for system_time all into @en; + +--echo ## Combinations of versioned + non-versioned +create or replace table t2 (y int); +insert into t2 values (3); +create or replace table t3 with system versioning select * from t1 for system_time all, t2; +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE +show create table t3; +select * from t3 for system_time all; +select * from t3 for system_time all where row_start = @row_start and row_end = @row_end; + +create or replace table t2 like t0; +insert into t2 (y) values (1), (2); +delete from t2 where y = 2; + +create or replace table t3 select * from t2 for system_time all; +select st, en from t3 where y = 1 into @st, @en; +select y from t2 for system_time all where st = @st and en = @en; +select st, en from t3 where y = 2 into @st, @en; +select y from t2 for system_time all where st = @st and en = @en; + +--echo ## Default engine detection +--replace_result $non_default_engine NON_DEFAULT_ENGINE $sys_datatype SYS_DATATYPE +eval create or replace table t1 (x25 int) with system versioning engine $non_default_engine; +create or replace table t2 +as select x25, row_start, row_end from t1 for system_time all; +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE $sys_datatype_null SYS_DATATYPE +show create table t2; + +create or replace table t2 with system versioning +as select x25, row_start, row_end from t1; +--replace_result $non_default_engine NON_DEFAULT_ENGINE $sys_datatype SYS_DATATYPE +show create table t2; + +create or replace table t1 ( + x26 int, + st bigint unsigned as row start, + en bigint unsigned as row end, + period for system_time (st, en) +) with system versioning engine innodb; +--error ER_VERS_FIELD_WRONG_TYPE +create or replace table t2 with system versioning engine myisam +as select * from t1; + +--replace_result $non_default_engine NON_DEFAULT_ENGINE +eval create or replace table t1 (x27 int, id int) with system versioning engine $non_default_engine; +create or replace table t2 (b int, id int); +create or replace table t3 with system versioning +as select t2.b, t1.x27, t1.row_start, t1.row_end from t2 inner join t1 on t2.id=t1.id; +--replace_result $non_default_engine NON_DEFAULT_ENGINE $sys_datatype SYS_DATATYPE $sys_datatype_null SYS_DATATYPE +show create table t3; + +--echo ## Errors + +--error ER_VERS_TEMPORARY +create or replace temporary table t (x28 int) with system versioning; + +--error ER_VERS_DUPLICATE_ROW_START_END +create or replace table t1 ( + x29 int unsigned, + Sys_start0 timestamp(6) as row start invisible, + Sys_start timestamp(6) as row start invisible, + Sys_end timestamp(6) as row end invisible, + period for system_time (Sys_start, Sys_end) +) with system versioning; + +--error ER_VERS_DUPLICATE_ROW_START_END +create or replace table t1 ( + x29 int unsigned, + Sys_end0 timestamp(6) as row end invisible, + Sys_start timestamp(6) as row start invisible, + Sys_end timestamp(6) as row end invisible, + period for system_time (Sys_start, Sys_end) +) with system versioning; + +--echo ## System fields detection +create or replace table t1 (x30 int) with system versioning; +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE +eval create or replace table t2 ( + y int, + st $sys_datatype as row start invisible, + en $sys_datatype as row end invisible, + period for system_time (st, en) +) with system versioning; + +create or replace table t3 +as select x30, y, row_start, row_end, st, en from t1, t2; +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE $sys_datatype_null SYS_DATATYPE $sys_datatype_not_null SYS_DATATYPE $sys_datatype_default_null SYS_DATATYPE +show create table t3; + +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE +eval create or replace table t3 ( + y int, + st $sys_datatype as row start invisible, + en $sys_datatype as row end invisible, + period for system_time (st, en) +) with system versioning +as select x30, y, row_start, row_end, st, en from t1, t2; +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE $sys_datatype_null SYS_DATATYPE $sys_datatype_not_null SYS_DATATYPE $sys_datatype_default_null SYS_DATATYPE +show create table t3; + +--echo # MDEV-14828 Server crashes in JOIN::prepare / setup_fields on 2nd execution of PS [#437] +create or replace table t1 (x int) with system versioning; +prepare bad from 'create or replace table t2 with system versioning as select * from t1'; +execute bad; execute bad; execute bad; execute bad; execute bad; execute bad; execute bad; execute bad; +--echo # bad is good. + +drop database test; +create database test; diff --git a/mysql-test/suite/versioning/t/cte.test b/mysql-test/suite/versioning/t/cte.test new file mode 100644 index 00000000000..9df0bb3dfba --- /dev/null +++ b/mysql-test/suite/versioning/t/cte.test @@ -0,0 +1,101 @@ +-- source include/have_innodb.inc +set default_storage_engine=innodb; +create or replace table dept ( + dept_id int(10) primary key, + name varchar(100) +) +with system versioning; + +create or replace table emp ( + emp_id int(10) primary key, + dept_id int(10) not null, + name varchar(100) not null, + mgr int(10), + salary int(10) not null, + constraint `dept-emp-fk` + foreign key (dept_id) references dept (dept_id) + on delete cascade + on update restrict, + constraint `mgr-fk` + foreign key (mgr) references emp (emp_id) + on delete restrict + on update restrict +) +with system versioning; + +insert into dept (dept_id, name) values (10, "accounting"); + +insert into emp (emp_id, name, salary, dept_id, mgr) values +(1, "bill", 1000, 10, null), +(20, "john", 500, 10, 1), +(30, "jane", 750, 10,1 ); + +select max(sys_trx_start) into @ts_1 from emp; + +update emp set mgr=30 where name ="john"; +select sys_trx_start into @ts_2 from emp where name="john"; + +/* All report to 'Bill' */ +with recursive +ancestors +as +( + select e.emp_id, e.name, e.mgr, e.salary + from emp for system_time as of timestamp @ts_1 as e + where name = 'bill' + union + select e.emp_id, e.name, e.mgr, e.salary + from emp for system_time as of timestamp @ts_1 as e, + ancestors as a + where e.mgr = a.emp_id +) +select * from ancestors; + +/* Expected 3 rows */ +with recursive +ancestors +as +( + select e.emp_id, e.name, e.mgr, e.salary + from emp for system_time as of timestamp @ts_2 as e + where name = 'bill' + union + select e.emp_id, e.name, e.mgr, e.salary + from emp for system_time as of timestamp @ts_2 as e, + ancestors as a + where e.mgr = a.emp_id +) +select * from ancestors; + +create or replace table emp ( emp_id int, name varchar(127), mgr int) with system versioning; +create or replace table addr ( emp_id int, address varchar(100)) with system versioning; +insert emp values (1, 'bill', 0), (2, 'bill', 1), (3, 'kate', 1); +insert addr values (1, 'Moscow'), (2, 'New York'), (3, 'London'); +set @ts=now(6); +delete from emp; +delete from addr; + +with recursive +ancestors +as +( + select e.emp_id, e.name, e.mgr + from emp for system_time as of timestamp @ts as e + where name = 'bill' + union + select ee.emp_id, ee.name, ee.mgr + from emp for system_time as of timestamp @ts as ee, ancestors as a + where ee.mgr = a.emp_id +) +select * from ancestors; + +insert emp values (4, 'john', 1); +insert addr values (4, 'Paris'); +with ancestors as (select * from emp natural join addr) select * from ancestors; +with ancestors as (select * from emp natural join addr) select * from ancestors for system_time all; +with ancestors as (select * from (select * from emp natural join addr) for system_time all as t) select * from ancestors; +select * from (select * from emp natural join addr) for system_time all as t; + +drop table emp; +drop table dept; +drop table addr; diff --git a/mysql-test/suite/versioning/t/ddl.test b/mysql-test/suite/versioning/t/ddl.test new file mode 100644 index 00000000000..5be62281a6d --- /dev/null +++ b/mysql-test/suite/versioning/t/ddl.test @@ -0,0 +1,105 @@ +-- source suite/versioning/common.inc + +delimiter ~~; +create function get_archive_table_name() +returns varchar(255) +begin + return (select archive_name from t_vtmd for system_time all where archive_name is not NULL + order by start desc limit 1); +end~~ + +create procedure drop_last_archive() +begin + call concat_exec2('drop table ', get_archive_table_name()); +end~~ +delimiter ;~~ + +set versioning_alter_history= survive; + +create or replace table t (a int) with system versioning; +insert into t values (1); +update t set a=2 where a=1; +select sys_trx_start from t where a=2 into @tm; +alter table t add column b int; + +select * from t; +call concat_exec3('select * from ', get_archive_table_name(), ' for system_time all'); + +call concat_exec3('select @tm=sys_trx_start from ', get_archive_table_name(), ' for system_time all where a=2'); +select @tm<sys_trx_start from t where a=2; +select sys_trx_start from t where a=2 into @tm; +call concat_exec3('select @tm=sys_trx_end from ', get_archive_table_name(), ' for system_time all where a=2'); + +call drop_last_archive(); + + +set versioning_alter_history= keep; +drop table t_vtmd; +drop table t; +set versioning_alter_history= survive; + +# same for INNODB ALGORITHM=COPY +create or replace table t (a int) with system versioning; +insert into t values (1); +update t set a=2 where a=1; +select sys_trx_start from t where a=2 into @tm; +alter table t add column b int; + +select * from t; +call concat_exec3('select * from ', get_archive_table_name(), ' for system_time all'); + +call concat_exec3('select @tm=sys_trx_start from ', get_archive_table_name(), ' for system_time all where a=2'); +select @tm<sys_trx_start from t where a=2; +select sys_trx_start from t where a=2 into @tm; +call concat_exec3('select @tm=sys_trx_end from ', get_archive_table_name(), ' for system_time all where a=2'); + +call drop_last_archive(); + + +set versioning_alter_history= keep; +drop table t_vtmd; +drop table t; +set versioning_alter_history= survive; + +# same for INNODB default ALGORITHM +create or replace table t (a int) with system versioning engine innodb; +insert into t values (1); +update t set a=2 where a=1; +select sys_trx_start from t where a=2 into @tm; +alter table t add column b int; + +select * from t; +call concat_exec3('select * from ', get_archive_table_name(), ' for system_time all'); + +call concat_exec3('select @tm=sys_trx_start from ', get_archive_table_name(), ' for system_time all where a=2'); +select @tm<sys_trx_start from t where a=2; +select sys_trx_start from t where a=2 into @tm; +call concat_exec3('select @tm=sys_trx_end from ', get_archive_table_name(), ' for system_time all where a=2'); + +call drop_last_archive(); + + +set versioning_alter_history= keep; +drop table t_vtmd; +drop table t; +set versioning_alter_history= survive; + +# no DDL for INNODB explicit ALGORITHM=INPLACE +create or replace table t (a int) with system versioning engine innodb; +insert into t values (1); +update t set a=2 where a=1; +alter table t add column b int, algorithm=inplace; + +set versioning_alter_history = keep; + +drop function get_archive_table_name; +drop procedure drop_last_archive; + +select * from mysql.vtmd_template; +show create table mysql.vtmd_template; + +call verify_vtq; +drop table t; +drop table t_vtmd; + +-- source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/t/debug.test b/mysql-test/suite/versioning/t/debug.test new file mode 100644 index 00000000000..c6d5bd60861 --- /dev/null +++ b/mysql-test/suite/versioning/t/debug.test @@ -0,0 +1,35 @@ +--source include/have_debug.inc + +create table t1 (a int); +show create table t1; + +--error ER_VERS_TEMPORARY +create temporary table tt1 (a int) with system versioning; + +set @old_dbug=@@global.debug_dbug; +set global debug_dbug='+d,sysvers_force'; + +create table t2 (a int); +show create table t2; + +create temporary table tt2 (a int) with system versioning; +show create table tt2; + +--connect con1, localhost, root + +create table t3 (a int); +show create table t3; + +create temporary table tt3 (a int) with system versioning; +show create table tt3; +--disconnect con1 +--connection default + +set debug_dbug='+d,sysvers_show'; + +show create table t3; +create table t4 (a int); +show create table t4; + +set global debug_dbug=@old_dbug; +drop table t1, t2, t3, t4; diff --git a/mysql-test/suite/versioning/t/delete.test b/mysql-test/suite/versioning/t/delete.test new file mode 100644 index 00000000000..55420a21185 --- /dev/null +++ b/mysql-test/suite/versioning/t/delete.test @@ -0,0 +1,129 @@ +-- source suite/versioning/common.inc + +delimiter ~~; +create or replace procedure test_01( + sys_type varchar(255), + engine varchar(255), + fields varchar(255)) +begin + set @str= concat(' + create or replace table t1( + XNo int unsigned, + sys_start ', sys_type, ' as row start invisible, + sys_end ', sys_type, ' as row end invisible, + period for system_time (sys_start, sys_end)) + with system versioning + engine ', engine); + prepare stmt from @str; execute stmt; drop prepare stmt; + insert into t1(XNo) values(0); + insert into t1(XNo) values(1); + insert into t1(XNo) values(2); + insert into t1(XNo) values(3); + insert into t1(XNo) values(4); + insert into t1(XNo) values(5); + insert into t1(XNo) values(6); + insert into t1(XNo) values(7); + insert into t1(XNo) values(8); + insert into t1(XNo) values(9); + set @str= concat('select XNo, ', + fields, " < '2038-01-19 03:14:07' + from t1 for system_time + between timestamp '0000-0-0 0:0:0' + and timestamp '2038-01-19 04:14:07'"); + prepare stmt from @str; execute stmt; + delete from t1 where XNo = 0; + select "Deleted 0"; + execute stmt; + delete from t1 where XNo = 1; + select "Deleted 1"; + execute stmt; + delete from t1 where XNo > 5; + select "Deleted >5"; + create view vt1 as select XNo from t1; + select XNo as XNo_vt1 from vt1; + delete from vt1 where XNo = 3; + select "Deleted from VIEW 3"; + select XNo as XNo_vt1 from vt1; + execute stmt; drop prepare stmt; + drop view vt1; + drop table t1; +end~~ + +create or replace procedure test_02( + sys_type varchar(255), + engine varchar(255), + fields varchar(255)) +begin + set @str= concat('create or replace table t1 ( + x int, + sys_start ', sys_type, ' as row start invisible, + sys_end ', sys_type, ' as row end invisible, + period for system_time (sys_start, sys_end)) + with system versioning + engine ', engine); + prepare stmt from @str; execute stmt; drop prepare stmt; + insert into t1(x) values (1); + select sys_start into @sys_start from t1; + delete from t1; + select * from t1; + select x = 1 as A, sys_start = @sys_start as B, sys_end > sys_start as C + from t1 for system_time between timestamp '0-0-0' and timestamp '2038-01-19 04:14:07'; + drop table t1; +end~~ + +create or replace procedure test_03( + sys_type varchar(255), + engine varchar(255), + fields varchar(255)) +begin + set @str0= concat('( + x int, + y int, + sys_start ', sys_type, ' as row start invisible, + sys_end ', sys_type, ' as row end invisible, + period for system_time (sys_start, sys_end)) + with system versioning + engine ', engine); + set @str= concat('create or replace table t1', @str0); + prepare stmt from @str; execute stmt; drop prepare stmt; + set @str= concat('create or replace table t2', @str0); + prepare stmt from @str; execute stmt; drop prepare stmt; + insert into t1(x, y) values (1, 1), (2, 2), (3, 3), (14, 4); + insert into t2(x, y) values (11, 1), (12, 2), (13, 32), (14, 4); + delete t1, t2 from t1 join t2 where t1.y = 3 and t2.y = 32; + select x as t1_x from t1; + select x as t2_x from t2; + delete t1, t2 from t1 join t2 where t1.x = t2.x; + select x as t1_x from t1; + select x as t2_x from t2; + select x as t1_x_all from t1 for system_time between timestamp '0-0-0' and timestamp '2038-01-19 04:14:07'; + select x as t2_x_all from t2 for system_time between timestamp '0-0-0' and timestamp '2038-01-19 04:14:07'; + drop table t1; + drop table t2; +end~~ +delimiter ;~~ + +--echo # Basic + delete from view +call test_01('timestamp(6)', 'myisam', 'sys_end'); +call test_01('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_end)'); +call verify_vtq; + +--echo # Check sys_start, sys_end +call test_02('timestamp(6)', 'myisam', 'sys_end'); +call test_02('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_end)'); +call verify_vtq; + +--echo # Multi-delete +call test_03('timestamp(6)', 'myisam', 'sys_end'); +call test_03('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_end)'); +call verify_vtq; + +--echo # Update + delete +create or replace table t1 (x int) with system versioning; +insert into t1 values (1); +update t1 set x= 2; +delete from t1; +select x from t1 for system_time all; + +drop database test; +create database test; diff --git a/mysql-test/suite/versioning/t/derived.test b/mysql-test/suite/versioning/t/derived.test new file mode 100644 index 00000000000..9784a4a0d2f --- /dev/null +++ b/mysql-test/suite/versioning/t/derived.test @@ -0,0 +1,236 @@ +create table emp +( + emp_id int, + name varchar(127), + mgr int +) with system versioning; + +insert into emp values (1, 'bill', 0), + (2, 'bill', 1), + (3, 'kate', 1); +set @ts=now(6); +delete from emp; +insert into emp values (4, 'john', 1); + +with ancestors as (select * from emp) select * from ancestors; +set @tmp= "with ancestors as (select * from emp) select * from ancestors"; +prepare stmt from @tmp; execute stmt; drop prepare stmt; + +with ancestors as (select * from emp for system_time all) select * from ancestors; +set @tmp= "with ancestors as (select * from emp for system_time all) select * from ancestors"; +prepare stmt from @tmp; execute stmt; drop prepare stmt; + +with recursive ancestors as (select * from emp) select * from ancestors; +set @tmp= "with recursive ancestors as (select * from emp) select * from ancestors"; +prepare stmt from @tmp; execute stmt; drop prepare stmt; + +select emp_id from (select emp_id from emp where row_end>'2031-1-1') as tmp; +set @tmp= "select emp_id from (select emp_id from emp where row_end>'2031-1-1') as tmp"; +prepare stmt from @tmp; execute stmt; drop prepare stmt; + +with recursive +ancestors +as +( + select e.emp_id, e.name, e.mgr + from emp as e + where name = 'john' + union + select ee.emp_id, ee.name, ee.mgr + from emp as ee, ancestors as a + where ee.mgr = a.emp_id +) +select * from ancestors; +set @tmp= " +with recursive +ancestors +as +( + select e.emp_id, e.name, e.mgr + from emp as e + where name = 'john' + union + select ee.emp_id, ee.name, ee.mgr + from emp as ee, ancestors as a + where ee.mgr = a.emp_id +) +select * from ancestors"; +prepare stmt from @tmp; execute stmt; drop prepare stmt; + +#385 +with recursive +ancestors +as +( + select e.emp_id, e.name, e.mgr + from emp for system_time as of timestamp @ts as e + where name = 'bill' + union + select ee.emp_id, ee.name, ee.mgr + from emp for system_time as of timestamp @ts as ee, + ancestors as a + where ee.mgr = a.emp_id +) +select * from ancestors; +set @tmp= " +with recursive +ancestors +as +( + select e.emp_id, e.name, e.mgr + from emp for system_time as of timestamp @ts as e + where name = 'bill' + union + select ee.emp_id, ee.name, ee.mgr + from emp for system_time as of timestamp @ts as ee, + ancestors as a + where ee.mgr = a.emp_id +) +select * from ancestors"; +prepare stmt from @tmp; execute stmt; drop prepare stmt; + +drop table emp; + +create or replace table t1 (x int) with system versioning; +create or replace table t2 (y int) with system versioning; +insert into t1 values (1); +set @t0= now(6); +delete from t1; +insert into t1 values (2); +insert into t2 values (10); + +--replace_column 2 # 3 # +select * from (select *, t1.row_end, t1.row_end as endo from t1) as s0; +--replace_column 3 # 4 # +select * from (select *, t1.row_end, t2.row_start from t1, t2) as s0; + +--echo # SYSTEM_TIME propagation from inner to outer +select * from (select * from t1 for system_time as of timestamp @t0, t2) as s0; +with s1 as (select * from t1 for system_time as of timestamp @t0, t2) select * from s1; +--echo # leading table selection +--replace_column 3 # +select * from (select *, t1.row_end from t2, t1 for system_time as of timestamp @t0) as s2; +--replace_column 3 # +with s3 as (select *, t1.row_end from t2, t1 for system_time as of timestamp @t0) select * from s3; + +--echo ### VIEW instead of t1 +set @q= concat("create view vt1 as select * from t1 for system_time as of timestamp '", @t0, "'"); +prepare q from @q; execute q; drop prepare q; +create view vt2 as select * from t1; + +--echo # SYSTEM_TIME propagation from view +select * from vt1; +--echo # SYSTEM_TIME propagation from inner to outer +select * from (select * from vt1, t2) as s0; + +--echo ### SYSTEM_TIME clash +--error ER_VERS_NOT_VERSIONED +select * from (select * from t1 for system_time all) for system_time all as dt0; +--error ER_VERS_NOT_VERSIONED +select * from vt1 for system_time all; +--error ER_VERS_NOT_VERSIONED +with dt1 as (select * from t1 for system_time all) +select * from dt1 for system_time all; + +--echo ### UNION +set @t1= now(6); +delete from t2; +insert into t2 values (3); +--echo # SYSTEM_TIME is not propagated +select x from t1 union +select y from t2; +select x from t1 for system_time as of @t0 union +select y from t2; +select x from t1 union +select y from t2 for system_time as of @t1; +select x from t1 for system_time as of @t0 union +select y from t2 for system_time as of @t1; + +--echo # LEFT/RIGHT JOIN +create or replace table t1 (x int, y int) with system versioning; +create or replace table t2 (x int, y int) with system versioning; + +insert into t1 values (1, 1), (1, 2), (1, 3), (4, 4), (5, 5); +insert into t2 values (1, 2), (2, 1), (3, 1); + +--echo ## Outer or inner SYSTEM_TIME produces same expression + +--disable_warnings +--disable_query_log +explain extended +select * from ( + select t1.x, t1.y as y1, t2.x as x2, t2.y as y2 + from t1 join t2 on t1.x = t2.x) for system_time as of now() as t; + +let $a=`show warnings`; +--echo Query A: +echo $a; + +explain extended +select * from ( + select t1.x, t1.y as y1, t2.x as x2, t2.y as y2 + from t1 for system_time as of now() + join t2 for system_time as of now() on t1.x = t2.x) as t; + +let $b=`show warnings`; +--echo Query B: +echo $b; + +if ($a == $b) +{ + --echo Fine result: queries A and B are equal. +} +--enable_query_log +--enable_warnings + +--echo ## LEFT JOIN: t1, t2 versioned +select * from ( + select t1.x as LJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 + from t1 left join t2 on t1.x = t2.x) +as derived; + +alter table t2 drop system versioning; + +--echo ## LEFT JOIN: t1 versioned +select * from ( + select t1.x as LJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 + from t1 left join t2 on t1.x = t2.x) +as derived; + +alter table t1 drop system versioning; +alter table t2 add system versioning; + +--echo ## LEFT JOIN: t2 versioned +select * from ( + select t1.x as LJ3_x1, t1.y as y1, t2.x as x2, t2.y as y2 + from t1 left join t2 on t1.x = t2.x) +as derived; + +alter table t1 add system versioning; + +--echo ## RIGHT JOIN: t1, t2 versioned +select * from ( + select t1.x as RJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 + from t1 right join t2 on t1.x = t2.x) +as derived; + +alter table t2 drop system versioning; + +--echo ## RIGHT JOIN: t1 versioned +select * from ( + select t1.x as RJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 + from t1 right join t2 on t1.x = t2.x) +as derived; + +alter table t1 drop system versioning; +alter table t2 add system versioning; + +--echo ## RIGHT JOIN: t2 versioned +select * from ( + select t1.x as RJ3_x1, t1.y as y1, t2.x as x2, t2.y as y2 + from t1 right join t2 on t1.x = t2.x) +as derived; + +drop table t1, t2; +drop view vt1, vt2; + diff --git a/mysql-test/suite/versioning/t/engines.combinations b/mysql-test/suite/versioning/t/engines.combinations new file mode 100644 index 00000000000..561c5656929 --- /dev/null +++ b/mysql-test/suite/versioning/t/engines.combinations @@ -0,0 +1,8 @@ +[timestamp] +default-storage-engine=innodb + +[trx_id] +default-storage-engine=innodb + +[myisam] +default-storage-engine=myisam diff --git a/mysql-test/suite/versioning/t/foreign.combinations b/mysql-test/suite/versioning/t/foreign.combinations new file mode 100644 index 00000000000..1a0812cfafe --- /dev/null +++ b/mysql-test/suite/versioning/t/foreign.combinations @@ -0,0 +1,5 @@ +[timestamp] +default-storage-engine=innodb + +[trx_id] +default-storage-engine=innodb diff --git a/mysql-test/suite/versioning/t/foreign.test b/mysql-test/suite/versioning/t/foreign.test new file mode 100644 index 00000000000..81d1caa2594 --- /dev/null +++ b/mysql-test/suite/versioning/t/foreign.test @@ -0,0 +1,282 @@ +--source suite/versioning/common.inc + +--echo ################# +--echo # Test RESTRICT # +--echo ################# + +create table parent( + id int unique key +) engine innodb; + +--replace_result $sys_datatype_expl SYS_DATATYPE +eval create table child( + parent_id int, + sys_start $sys_datatype_expl as row start invisible, + sys_end $sys_datatype_expl as row end invisible, + period for system_time(sys_start, sys_end), + foreign key(parent_id) references parent(id) + on delete restrict + on update restrict +) engine innodb with system versioning; + +insert into parent values(1); +insert into child values(1); + +-- error ER_ROW_IS_REFERENCED_2 +delete from parent where id = 1; +delete from child where parent_id = 1; +delete from parent where id = 1; + +insert into parent values(1); +insert into child values(1); +-- error ER_ROW_IS_REFERENCED_2 +update parent set id=id+1; +delete from child; +update parent set id=id+1; +select * from child for system_time from timestamp '1-1-1' to timestamp now(6); + +drop table child; +drop table parent; + +--echo ############################################## +--echo # Test when clustered index is a foreign key # +--echo ############################################## + +create table parent( + id int(10) unsigned unique key +) engine innodb; + +--replace_result $sys_datatype_expl SYS_DATATYPE +eval create table child( + parent_id int(10) unsigned primary key, + sys_start $sys_datatype_expl as row start invisible, + sys_end $sys_datatype_expl as row end invisible, + period for system_time(sys_start, sys_end), + foreign key(parent_id) references parent(id) +) engine innodb with system versioning; + +insert into parent values(1); +insert into child values(1); + +-- error ER_ROW_IS_REFERENCED_2 +delete from parent where id = 1; + +drop table child; +drop table parent; + +--echo ################ +--echo # Test CASCADE # +--echo ################ + +create table parent( + id int unique key +) engine innodb; + +--replace_result $sys_datatype_expl SYS_DATATYPE +eval create table child( + parent_id int, + sys_start $sys_datatype_expl as row start invisible, + sys_end $sys_datatype_expl as row end invisible, + period for system_time(sys_start, sys_end), + foreign key(parent_id) references parent(id) + on delete cascade + on update cascade +) engine innodb with system versioning; + +insert into parent values(1); +insert into child values(1); + +--echo ## FIXME: #415 update of foreign constraints is disabled +call mtr.add_suppression("foreign key constraints in timestamp-based temporal table"); +--error ER_UNSUPPORTED_EXTENSION +delete from parent where id = 1; +delete from child where parent_id = 1; +--echo ## FIXME END +delete from parent where id = 1; +select * from child; +select * from child for system_time all; + +insert into parent values(1); +insert into child values(1); +update parent set id = id + 1; +select * from child; +select * from child for system_time all; + +drop table child; +drop table parent; + +--replace_result $sys_datatype_expl SYS_DATATYPE +eval create or replace table parent ( + id int primary key, + sys_start $sys_datatype_expl as row start invisible, + sys_end $sys_datatype_expl as row end invisible, + period for system_time(sys_start, sys_end) +) with system versioning +engine innodb; + +create or replace table child ( + x int, + parent_id int not null, + constraint `parent-fk` + foreign key (parent_id) references parent (id) + on delete cascade + on update restrict +) +engine innodb; + +insert into parent (id) values (2); +insert into child (x, parent_id) values (2, 2); +delete from parent; +select * from child; + +drop table child; +drop table parent; + +create or replace table parent ( + id int primary key +) +engine innodb; + +create or replace table child ( + id int primary key, + parent_id int not null, + constraint `parent-fk` + foreign key (parent_id) references parent (id) + on delete cascade + on update restrict +) with system versioning +engine innodb; + +insert into parent (id) values (3); +insert into child (id, parent_id) values (3, 3); +--echo ## FIXME: #415 update of foreign constraints is disabled +delete from child; +--echo ## FIXME END +delete from parent; +select * from child; +select * from child for system_time all; + +drop table child; +drop table parent; + +--echo ################# +--echo # Test SET NULL # +--echo ################# + +create table parent( + id int unique key +) engine innodb; + +--replace_result $sys_datatype_expl SYS_DATATYPE +eval create table child( + parent_id int, + sys_start $sys_datatype_expl as row start invisible, + sys_end $sys_datatype_expl as row end invisible, + period for system_time(sys_start, sys_end), + foreign key(parent_id) references parent(id) + on delete set null + on update set null +) engine innodb with system versioning; + +insert into parent values(1); +insert into child values(1); +delete from child; +insert into child values(1); + +--echo ## FIXME: #415 update of foreign constraints is disabled +delete from child where parent_id = 1; +--echo ## FIXME END +delete from parent where id = 1; +select * from child; +select * from child for system_time from timestamp '1-1-1' to timestamp now(6); +delete from child; + +insert into parent values(1); +insert into child values(1); +## FIXME: #415 update of foreign constraints is disabled +if (0) +{ +update parent set id=id+1; +select * from child; +select * from child for system_time from timestamp '1-1-1' to timestamp now(6); +} +## FIXME END + +drop table child; +drop table parent; + +--echo ########################### +--echo # Parent table is foreign # +--echo ########################### + +--replace_result $sys_datatype_expl SYS_DATATYPE +eval create or replace table parent( + id int unique key, + sys_start $sys_datatype_expl as row start invisible, + sys_end $sys_datatype_expl as row end invisible, + period for system_time(sys_start, sys_end) +) engine innodb with system versioning; + +create or replace table child( + parent_id int, + foreign key(parent_id) references parent(id) +) engine innodb; + +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 +update parent set id=2; + +delete from child; +delete from parent; + +-- error ER_NO_REFERENCED_ROW_2 +insert into child values(1); + +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 +update parent set id=2; + +drop table child; +drop table parent; + +--echo ################### +--echo # crash on DELETE # +--echo ################### + +--replace_result $sys_datatype_expl SYS_DATATYPE +eval create or replace table a ( + cola int(10) primary key, + v_cola int(10) as (cola mod 10) virtual, + sys_start $sys_datatype_expl as row start invisible, + sys_end $sys_datatype_expl as row end invisible, + period for system_time(sys_start, sys_end) +) engine=innodb with system versioning; + +create index v_cola on a (v_cola); + +--replace_result $sys_datatype_expl SYS_DATATYPE +eval create or replace table b( + cola int(10), + v_cola int(10), + sys_start $sys_datatype_expl as row start invisible, + sys_end $sys_datatype_expl as row end invisible, + period for system_time(sys_start, sys_end) +) engine=innodb with system versioning; + +alter table b add constraint `v_cola_fk` +foreign key (v_cola) references a (v_cola); + +insert into a(cola) values (12); +insert into b(cola, v_cola) values (10,2); +--error ER_ROW_IS_REFERENCED_2 +delete from a; + +drop table b, a; + +--source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/t/insert.test b/mysql-test/suite/versioning/t/insert.test new file mode 100644 index 00000000000..482f0dd77ce --- /dev/null +++ b/mysql-test/suite/versioning/t/insert.test @@ -0,0 +1,266 @@ +-- source suite/versioning/common.inc + +delimiter ~~; +create procedure test_01( + sys_type varchar(255), + engine varchar(255), + fields varchar(255)) +begin + set @str= concat(' + create table t1( + x int unsigned, + y int unsigned, + sys_start ', sys_type, ' as row start invisible, + sys_end ', sys_type, ' as row end invisible, + period for system_time (sys_start, sys_end)) + with system versioning + engine ', engine); + prepare stmt from @str; execute stmt; drop prepare stmt; + insert into t1(x, y) values(3, 4); + insert delayed into t1(x, y) values(2, 3); + insert into t1 values(40, 33); + set @str= concat('select x, y, ', fields, ' from t1'); + prepare stmt from @str; execute stmt; drop prepare stmt; + drop table t1; +end~~ + +create procedure test_02( + sys_type varchar(255), + engine varchar(255), + fields varchar(255)) +begin + set @str= concat(' + create table t1( + id int unsigned auto_increment primary key, + x int unsigned, + y int unsigned, + sys_start ', sys_type, ' as row start invisible, + sys_end ', sys_type, ' as row end invisible, + period for system_time (sys_start, sys_end)) + with system versioning + engine ', engine); + prepare stmt from @str; execute stmt; drop prepare stmt; + insert into t1(x, y) values(33, 44); + insert into t1(id, x, y) values(20, 33, 44); + insert into t1 values(40, 33, 44); + set @str= concat('select id, x, y, ', fields, ' from t1'); + prepare stmt from @str; execute stmt; drop prepare stmt; + drop table t1; +end~~ + +create procedure test_03( + sys_type varchar(255), + engine varchar(255), + fields varchar(255)) +begin + set @str= concat(' + create table t1( + x int unsigned, + y int unsigned, + sys_start ', sys_type, ' as row start invisible, + sys_end ', sys_type, ' as row end invisible, + period for system_time (sys_start, sys_end)) + with system versioning + engine ', engine); + prepare stmt from @str; execute stmt; drop prepare stmt; + create view vt1_1 as select x, y from t1; + insert into t1(x, y) values(8001, 9001); + insert into vt1_1(x, y) values(1001, 2001); + insert into vt1_1 values(1002, 2002); + set @str= concat('select x, y, ', fields, ' from t1'); + prepare stmt from @str; execute stmt; drop prepare stmt; + select x, y from vt1_1; +end~~ + +create procedure test_04( + sys_type varchar(255), + engine varchar(255), + fields varchar(255)) +begin + set @str= concat(' + create table t1( + id bigint primary key, + a int, + b int) + with system versioning + engine ', engine); + prepare stmt from @str; execute stmt; drop prepare stmt; + insert into t1 values(1, 1, 1); + select row_start, row_end from t1 into @sys_start, @sys_end; + select id, a, b from t1; + insert into t1 values(2, 2, 2); + select id, a, b, row_start > @sys_start as C, row_end = @sys_end as D from t1 where id = 2; + drop table t1; +end~~ + +create procedure test_05( + sys_type varchar(255), + engine varchar(255), + fields varchar(255)) +begin + set @str= concat('( + x int unsigned, + y int unsigned, + sys_start ', sys_type, ' as row start invisible, + sys_end ', sys_type, ' as row end invisible, + period for system_time (sys_start, sys_end)) + with system versioning + engine ', engine); + set @str2= concat('create table t1', @str); + prepare stmt from @str2; execute stmt; drop prepare stmt; + set @str2= concat('create table t2', @str); + prepare stmt from @str2; execute stmt; drop prepare stmt; + insert into t1(x, y) values + (1, 1000), + (2, 2000), + (3, 3000), + (4, 4000), + (5, 5000), + (6, 6000), + (7, 7000), + (8, 8000), + (9, 9000); + delete from t1 where x >= 1; + insert into t1(x, y) values + (1, 1001), + (2, 2001), + (3, 3001), + (4, 4001), + (5, 5001), + (6, 6001); + insert into t1(x, y, sys_start) values + (7, 7001, DEFAULT); + insert into t1(x, y, sys_end) values + (8, 8001, DEFAULT); + insert into t1(x, y, sys_start, sys_end) values + (9, 9001, DEFAULT, DEFAULT); + insert into t2 select x, y from t1 for system_time between timestamp '0000-0-0 0:0:0' and timestamp '9999-1-1 0:0:0'; + select x, y from t1; + select x, y from t2; + drop table t1; + drop table t2; +end~~ +delimiter ;~~ + +call test_01('timestamp(6)', 'myisam', 'sys_end'); +call test_01('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_end)'); + +call test_02('timestamp(6)', 'myisam', 'sys_end'); +call test_02('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_end)'); + +call test_03('timestamp(6)', 'myisam', 'sys_end'); +drop table t1; +drop view vt1_1; + +call test_03('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_end)'); +drop table t1; +drop view vt1_1; + +call test_04('timestamp(6)', 'myisam', 'sys_end'); +call test_04('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_end)'); + +call test_05('timestamp(6)', 'myisam', 'sys_end'); +call test_05('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_end)'); + +# VTQ test + +call verify_vtq; + +create table t1( + x int unsigned, + sys_start bigint unsigned as row start invisible, + sys_end bigint unsigned as row end invisible, + period for system_time (sys_start, sys_end)) +with system versioning engine=innodb; + +create table t2(x int unsigned) engine=innodb; + +start transaction; +insert into t1(x) values(1); +commit; +call verify_vtq; + +start transaction; +insert into t2(x) values(1); +savepoint a; +insert into t1(x) values(1); +rollback to a; +commit; +call verify_vtq; + +insert into t2(x) values (1); + +# virtual columns +create or replace table t1 ( + x int, + y int as (x) virtual, + sys_trx_start bigint unsigned as row start invisible, + sys_trx_end bigint unsigned as row end invisible, + period for system_time (sys_trx_start, sys_trx_end) +) engine=innodb with system versioning; +insert into t1 values (1, null); +update t1 set x= x + 1; +select x, y, sys_trx_end = 18446744073709551615 as current from t1 for system_time all; + +create or replace table t1 (x int) with system versioning engine innodb; +insert into t1 values (1), (2); +--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN +insert into t1 (row_start) select row_end from t1; +set sql_mode=''; +insert into t1 (row_start, row_end) values (DEFAULT, 1); +set sql_mode=default; +select @@sql_mode into @saved_mode; +set sql_mode= ''; +insert into t1 (x, row_start, row_end) values (3, 4, 5); +set sql_mode= @saved_mode; +insert into t1 (row_start, row_end) values (DEFAULT, DEFAULT); +select * from t1; + +--echo # MDEV-14792 INSERT without column list into table with explicit versioning columns produces bad data +create or replace table t1 ( + i int, + s timestamp(6) as row start, + e timestamp(6) as row end, + c varchar(8), + period for system_time(s, e)) +with system versioning; +insert into t1 values (1, null, null, 'foo'); +select i, c, current_row(e) from t1; + +drop table t1; +drop table t2; + +drop procedure test_01; +drop procedure test_02; +drop procedure test_03; +drop procedure test_04; +drop procedure test_05; + +-- source suite/versioning/common_finish.inc + +# +# MDEV-14788 System versioning cannot be based on local timestamps, as it is now +# +set timestamp=1000000019; +select now() < sysdate(); +create table t1 (a int) with system versioning; +insert t1 values (1); + +--source suite/versioning/wait_system_clock.inc +set @a=sysdate(6); + +select * from t1 for system_time as of now(6); +select * from t1 for system_time as of sysdate(6); +update t1 set a=2; +delete from t1; +--sorted_result +select *, row_start > @a, row_end > @a from t1 for system_time all; + +--echo # +--echo # MDEV-14871 Server crashes in fill_record / fill_record_n_invoke_before_triggers upon inserting into versioned table with trigger +--echo # +create or replace table t1 (pk int primary key) with system versioning; +create trigger tr before insert on t1 for each row select 1 into @a; +insert into t1 values (1),(2); + +drop table t1; diff --git a/mysql-test/suite/versioning/t/online.test b/mysql-test/suite/versioning/t/online.test new file mode 100644 index 00000000000..4fbd5d85100 --- /dev/null +++ b/mysql-test/suite/versioning/t/online.test @@ -0,0 +1,42 @@ +--source include/have_innodb.inc + +set system_versioning_alter_history=keep; + +create or replace table t (a int, b int) engine=innodb; + +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +alter table t add system versioning, lock=none; +alter table t add system versioning, lock=shared; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +alter table t drop column b, lock=none; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +alter table t drop column b, algorithm=inplace; +alter table t add index idx(a), lock=none; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +alter table t drop system versioning, lock=none; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +alter table t drop system versioning, algorithm=inplace; + + +create or replace table t (a int, b int) engine=innodb; + +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +alter table t + add s bigint unsigned as row start, + add e bigint unsigned as row end, + add period for system_time(s, e), + add system versioning, + lock=none; +alter table t + add s bigint unsigned as row start, + add e bigint unsigned as row end, + add period for system_time(s, e), + add system versioning; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +alter table t drop column b, lock=none; +alter table t add index idx(a), lock=none; +alter table t drop column s, drop column e; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +alter table t drop system versioning, lock=none; + +drop table t; diff --git a/mysql-test/suite/versioning/t/optimized.test b/mysql-test/suite/versioning/t/optimized.test new file mode 100644 index 00000000000..93dd6ed6fc6 --- /dev/null +++ b/mysql-test/suite/versioning/t/optimized.test @@ -0,0 +1,33 @@ +create table t ( + a int, + b int without system versioning +) with system versioning; + +insert into t values(1, 2); +insert into t values(3, 4); +select * from t; +select a from t for system_time as of timestamp now(6); +select a, b, b+0 from t for system_time as of timestamp now(6); +select * from t for system_time as of timestamp now(6); +select count(*) from t for system_time as of timestamp now(6) group by b; +select * from t for system_time as of timestamp now(6) order by b asc; +select * from t for system_time as of timestamp now(6) order by b desc; +select * from t for system_time as of timestamp now(6) group by a having a=2; +select * from t for system_time as of timestamp now(6) group by b having b=2; +select a from t for system_time as of timestamp now(6) where b=2; +select a from t for system_time as of timestamp now(6) where b=NULL; +select a from t for system_time as of timestamp now(6) where b is NULL; +select count(*), b from t for system_time as of timestamp now(6) group by b having b=NULL; +select a, b from t; + +create or replace table t ( + a int, + b int not null without system versioning +) with system versioning; + +insert into t values (1, 2), (3, 4); + +select * from t for system_time as of timestamp now(6); +select * from t for system_time as of timestamp now(6) where b is NULL; + +drop table t; diff --git a/mysql-test/suite/versioning/t/partition.combinations b/mysql-test/suite/versioning/t/partition.combinations new file mode 100644 index 00000000000..4d73ef5a5ea --- /dev/null +++ b/mysql-test/suite/versioning/t/partition.combinations @@ -0,0 +1,5 @@ +[timestamp] +default-storage-engine=innodb + +[myisam] +default-storage-engine=myisam diff --git a/mysql-test/suite/versioning/t/partition.opt b/mysql-test/suite/versioning/t/partition.opt new file mode 100644 index 00000000000..71be6744916 --- /dev/null +++ b/mysql-test/suite/versioning/t/partition.opt @@ -0,0 +1 @@ +--system-versioning-alter-history=keep diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test new file mode 100644 index 00000000000..1dea9f7c69c --- /dev/null +++ b/mysql-test/suite/versioning/t/partition.test @@ -0,0 +1,373 @@ +-- source include/have_partition.inc +-- source suite/versioning/common.inc + +--echo # Check conventional partitioning on temporal tables + +create table t1 (x int) +with system versioning +partition by range columns (x) ( + partition p0 values less than (100), + partition p1 values less than (1000)); + +insert into t1 values (3), (300); +select * from t1; +select * from t1 partition (p0); +select * from t1 partition (p1); + +delete from t1; +select * from t1; +select * from t1 partition (p0); +select * from t1 partition (p1); +select * from t1 for system_time all; +select * from t1 partition (p0) for system_time all; +select * from t1 partition (p1) for system_time all; + +--echo # Engine change native <-> non-native versioning prohibited +--replace_result $default_engine DEFAULT_ENGINE +eval create or replace table t1 (i int) engine=$default_engine with system versioning partition by hash(i); +--replace_result $non_default_engine NON_DEFAULT_ENGINE +--error ER_VERS_ALTER_ENGINE_PROHIBITED +eval alter table t1 engine=$non_default_engine; + + +--echo ## CREATE TABLE + +--error ER_VERS_ENGINE_UNSUPPORTED +create or replace table t1 (x int) +partition by system_time ( + partition p0 history, + partition pn current); + +create or replace table t1 (x int); +--error ER_VERS_ENGINE_UNSUPPORTED,ER_VERS_ENGINE_UNSUPPORTED +alter table t1 +partition by system_time ( + partition p0 history, + partition pn current); + +--error ER_VERS_WRONG_PARTS +create or replace table t1 (x int) +with system versioning +partition by system_time ( + partition p0 current); + +--error ER_VERS_WRONG_PARTS +create or replace table t1 (x int) +with system versioning +partition by system_time ( + partition p0 current, + partition p1 current); + +--error ER_VERS_WRONG_PARTS +create or replace table t1 (x int) +with system versioning +partition by system_time ( + partition p0 history, + partition p1 history); + +--error ER_VERS_WRONG_PARTS +create or replace table t1 (x int) +with system versioning +partition by system_time ( + partition pn current, + partition p0 history); + +--error ER_VERS_WRONG_PARTS +create or replace table t1 (x int) +with system versioning +partition by system_time ( + partition p0, + partition pn current); + +create or replace table t1 (x int) +with system versioning +partition by system_time ( + partition p0 history, + partition pn current); + + +--echo ## ALTER TABLE + +--error ER_VERS_WRONG_PARTS +alter table t1 add partition ( + partition p1 current); + +alter table t1 add partition ( + partition p1 history); + +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE +show create table t1; + +insert into t1 values (1), (2); + +--error ER_VERS_WRONG_PARTS +alter table t1 drop partition pn; +alter table t1 drop partition p1; +--error ER_VERS_WRONG_PARTS +alter table t1 drop partition p0; + +select x from t1; + +--echo # Bug #260: incorrect IB partitioning warning +create or replace table t1 (x int) +with system versioning +partition by system_time limit 1 ( + partition p0 history, + partition pn current); +alter table t1 change x big int; + +create or replace table t1 (i int) engine myisam partition by hash(i) partitions 2; +--error ER_PARTITION_WRONG_TYPE +alter table t1 add partition (partition px history); + + +--echo ## INSERT, UPDATE, DELETE + +create or replace table t1 (x int) +with system versioning +partition by system_time ( + partition p0 history, + partition pn current); + +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)'); +prepare select_pn from @str; + +execute select_p0; +execute select_pn; + +--echo ## pruning check +--replace_regex /\d/N/ /ALL/system/ /Using where// +explain partitions select * from t1; + +set @str= concat('select row_start from t1 partition (pn) into @ts0'); +prepare stmt from @str; execute stmt; drop prepare stmt; + +--source suite/versioning/wait_system_clock.inc + +set @now= now(6); +delete from t1; +execute select_p0; +execute select_pn; + +set @str= concat('select row_start from t1 partition (p0) into @ts1'); +prepare stmt from @str; execute stmt; drop prepare stmt; + +select @ts0 = @ts1; + +set @now= now(6); +insert into t1 values (2); + +--source suite/versioning/wait_system_clock.inc + +execute select_p0; +execute select_pn; + +set @str= concat('select row_start from t1 partition (pn) into @ts0'); +prepare stmt from @str; execute stmt; drop prepare stmt; + +set @now= now(6); +update t1 set x = x + 1; + +--source suite/versioning/wait_system_clock.inc + +execute select_p0; +execute select_pn; + +drop prepare select_p0; +drop prepare select_pn; + +set @str= concat('select row_start from t1 partition (p0) where x = 2 into @ts1'); +prepare stmt from @str; execute stmt; drop prepare stmt; +set @str= concat('select row_end from t1 partition (p0) where x = 2 into @ts2'); +prepare stmt from @str; execute stmt; drop prepare stmt; +set @str= concat('select row_start from t1 partition (pn) into @ts3'); +prepare stmt from @str; execute stmt; drop prepare stmt; + +select @ts0 = @ts1; +select @ts2 = @ts3; + +--echo ## rotation by LIMIT +--error ER_PART_WRONG_VALUE +create or replace table t1 (x int) +with system versioning +partition by system_time limit 0 ( + partition p0 history, + partition p1 history, + partition pn current); + +create or replace table t1 (x int) +with system versioning +partition by system_time limit 2 ( + partition p0 history, + partition p1 history, + partition pn current); + +--replace_result $default_engine DEFAULT_ENGINE $sys_datatype SYS_DATATYPE +show create table t1; + +--error ER_DROP_PARTITION_NON_EXISTENT +alter table t1 drop partition non_existent; + +insert into t1 values (1), (2), (3); +select * from t1 partition (pn); +--echo ### warn about partition switching +delete from t1; +select * from t1 partition (p0); +select * from t1 partition (p1); + +insert into t1 values (4), (5); +--echo ### warn about full partition +delete from t1; +select * from t1 partition (p1) order by x; + +--echo ### Assertion in ALTER on warning from partitioning LIMIT [#446] +create or replace table t1 (x int) with system versioning; +insert into t1 values (1), (2); +delete from t1; +alter table t1 partition by system_time limit 1 ( + partition p1 history, + partition pn current); + +--echo ## rotation by INTERVAL +--error ER_PART_WRONG_VALUE +create or replace table t1 (x int) +with system versioning +partition by system_time interval 0 second ( + partition p0 history, + partition p1 history, + partition pn current); + +create or replace table t1 (x int) +with system versioning +partition by system_time interval 1 second ( + partition p0 history, + partition p1 history, + partition pn current); + +insert into t1 values (1), (2), (3); +select * from t1 partition (pn); +delete from t1; +select * from t1 partition (p0); + +--sleep 2 +insert into t1 values (4); +delete from t1; +select * from t1 partition (p1); + +--echo ## Subpartitions +create or replace table t1 (x int) +with system versioning +partition by system_time limit 2 +subpartition by key (x) +subpartitions 2 ( + partition p0 history, + partition p1 history, + partition pn current); + +insert into t1 (x) values (1), (2), (3), (4), (5); +select * from t1 partition (pnsp0); +select * from t1 partition (pnsp1); + +--echo ### warn about partition switching and about full partition +delete from t1; +select * from t1 partition (p0sp0); +select * from t1 partition (p0sp1); +select * from t1 partition (p1sp0); +select * from t1 partition (p1sp1); + +create or replace table t1 (a bigint) +with system versioning +partition by range (a) +(partition p0 values less than (20) engine innodb, + partition p1 values less than maxvalue engine innodb); +insert into t1 values (1); + +create or replace table t1 ( + f_int1 integer default 0 +) with system versioning +partition by range(f_int1) +subpartition by hash(f_int1) +( partition part1 values less than (1000) +(subpartition subpart11 storage engine = 'innodb', +subpartition subpart12 storage engine = 'innodb')); +insert into t1 values (1); + +create or replace table t1 (i int) engine=innodb partition by key(i); +alter table t1 add system versioning; +insert into t1 values(); + +--echo # MDEV-14722 Assertion in ha_commit_trans for sub-statement +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 day ( + partition p1 history, + partition pc current); +create or replace table t2 (f int); +create or replace trigger tr before insert on t2 +for each row select table_rows from information_schema.tables +where table_name = 't1' into @a; +insert into t2 values (1); + +--echo # MDEV-14740 Locking assertion for system_time partitioning +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 week ( + partition p1 history, + partition pn current); +create or replace table t2 (f int); +create or replace trigger tr before insert on t2 +for each row select count(*) from t1 into @a; +insert into t2 values (1); + +--echo # MDEV-14741 Assertion `(trx)->start_file == 0' failed in row_truncate_table_for_mysql() +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 hour ( + partition p1 history, + partition pn current); +set autocommit= off; +truncate table t1; +set autocommit= on; + +--echo # MDEV-14747 ALTER PARTITION BY SYSTEM_TIME after LOCK TABLES +create or replace table t1 (x int) with system versioning; +lock table t1 write; +alter table t1 partition by system_time interval 1 week ( + partition p1 history, + partition pn current); +unlock tables; + +--echo # MDEV-14748 Assertion in ha_myisammrg::attach_children() +create or replace table t1 (x int) engine=myisam with system versioning + partition by system_time interval 1 month (partition p1 history, partition pn current); +create or replace table t2 (x int) engine=myisam; +create or replace table t3 (x int) engine=merge union=(t2); +create or replace table t4 (x int) engine=myisam; +create or replace trigger tr after insert on t4 for each row insert into t2 + ( select x from t3 ) union ( select x from t1 ); +insert into t4 values (1); + +--echo # MDEV-14821 Assertion failure +create or replace table t1 (x int) with system versioning; +insert into t1 values (0), (1); +update t1 set x= x + 1; +alter table t1 partition by system_time limit 1 ( + partition p1 history, + partition p2 history, + partition pn current); +delete from t1 where x = 1; +delete from t1 where x = 2; + +--echo # MDEV-14923 Assertion upon INSERT into locked versioned partitioned table +create or replace table t1 (x int) with system versioning +partition by system_time (partition p1 history, partition pn current); +lock table t1 write; +--error ER_SAME_NAME_PARTITION +alter table t1 add partition (partition p1 history); +insert into t1 values (1); +unlock tables; + +--echo # Test cleanup +drop database test; +create database test; diff --git a/mysql-test/suite/versioning/t/replace.test b/mysql-test/suite/versioning/t/replace.test new file mode 100644 index 00000000000..8f1c2d8d637 --- /dev/null +++ b/mysql-test/suite/versioning/t/replace.test @@ -0,0 +1,13 @@ +--source suite/versioning/common.inc +--source suite/versioning/key_type.inc +--source suite/versioning/engines.inc + +call create_table('t', 'x int'); + +insert t values (1, 2); +replace t values (1, 3); +select *, current_row(row_end) as current from t for system_time all +order by x; + +drop database test; +create database test; diff --git a/mysql-test/suite/versioning/t/rpl.test b/mysql-test/suite/versioning/t/rpl.test new file mode 100644 index 00000000000..342d58626b7 --- /dev/null +++ b/mysql-test/suite/versioning/t/rpl.test @@ -0,0 +1,108 @@ +--source include/master-slave.inc + +if ($MTR_COMBINATION_STMT) +{ + --source include/have_binlog_format_statement.inc +} +if ($MTR_COMBINATION_ROW) +{ + --source include/have_binlog_format_row.inc +} +if ($MTR_COMBINATION_MIX) +{ + --source include/have_binlog_format_mixed.inc +} +--source suite/versioning/engines.inc + +#BUG#12662190 - COM_COMMIT IS NOT INCREMENTED FROM THE BINARY LOGS ON SLAVE, COM_BEGIN IS +#Testing command counters -BEFORE. +#Storing the before counts of Slave +connection slave; +let $slave_com_commit_before= query_get_value(SHOW GLOBAL STATUS LIKE 'com_commit', Value, 1); +let $slave_com_insert_before= query_get_value(SHOW GLOBAL STATUS LIKE 'com_insert', Value, 1); +let $slave_com_delete_before= query_get_value(SHOW GLOBAL STATUS LIKE 'com_delete', Value, 1); +let $slave_com_update_before= query_get_value(SHOW GLOBAL STATUS LIKE 'com_update', Value, 1); + +connection master; +CREATE TABLE t1 (x int) with system versioning; +insert into t1 values (1); +SELECT * FROM t1; +delete from t1; +select * from t1; +select * from t1 for system_time all; +sync_slave_with_master; +select * from t1; +select * from t1 for system_time all; + +connection master; +insert into t1 values (2); +sync_slave_with_master; +select * from t1; + +connection master; +update t1 set x = 3; +sync_slave_with_master; +select * from t1; +select * from t1 for system_time all; + +# check unversioned -> versioned replication +connection master; +create or replace table t1 (x int primary key); +sync_slave_with_master; +alter table t1 with system versioning; + +connection master; +insert into t1 values (1); +sync_slave_with_master; +select * from t1; +select * from t1 for system_time all; + +connection master; +update t1 set x= 2 where x = 1; +sync_slave_with_master; +select * from t1; +select * from t1 for system_time all; + +connection master; +delete from t1; +sync_slave_with_master; +select * from t1; +select * from t1 for system_time all; + +# same thing (UPDATE, DELETE), but without PK +connection master; +create or replace table t1 (x int); +sync_slave_with_master; +alter table t1 with system versioning; + +connection master; +insert into t1 values (1); +update t1 set x= 2 where x = 1; +sync_slave_with_master; +select * from t1; +select * from t1 for system_time all; + +connection master; +delete from t1; +sync_slave_with_master; +select * from t1; +select * from t1 for system_time all; + +# multi-update +connection master; +create or replace table t1 (x int) with system versioning; +create or replace table t2 (x int) with system versioning; +insert into t1 values (1); +insert into t2 values (2); +update t1, t2 set t1.x=11, t2.x=22; +sync_slave_with_master; +select * from t1; +select * from t2; +select * from t1 for system_time all; +select * from t2 for system_time all; + + +connection master; +drop table t1, t2; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/versioning/t/select.test b/mysql-test/suite/versioning/t/select.test new file mode 100644 index 00000000000..356406e0947 --- /dev/null +++ b/mysql-test/suite/versioning/t/select.test @@ -0,0 +1,306 @@ +--source suite/versioning/engines.inc +--source suite/versioning/common.inc + +# test_01 + +--replace_result $sys_datatype_expl SYS_DATATYPE +eval create or replace table t1 ( + x int unsigned, + y int unsigned, + sys_trx_start $sys_datatype_expl as row start invisible, + sys_trx_end $sys_datatype_expl as row end invisible, + period for system_time (sys_trx_start, sys_trx_end) +) with system versioning; + +insert into t1 (x, y) values + (0, 100), + (1, 101), + (2, 102), + (3, 103), + (4, 104), + (5, 105), + (6, 106), + (7, 107), + (8, 108), + (9, 109); + +set @t0= now(6); +if ($MTR_COMBINATION_TRX_ID) +{ +--disable_query_log + select sys_trx_start from t1 limit 1 into @x0; +--enable_query_log +} + +delete from t1 where x = 3; +delete from t1 where x > 7; + +insert into t1(x, y) values(3, 33); +select sys_trx_start from t1 where x = 3 and y = 33 into @t1; +if ($MTR_COMBINATION_TRX_ID) +{ +--disable_query_log + set @x1= @t1; + select vtq_commit_ts(@x1) into @t1; +--enable_query_log +} + +select x, y from t1; +select x as ASOF_x, y from t1 for system_time as of timestamp @t0; +select x as FROMTO_x, y from t1 for system_time from timestamp '0-0-0 0:0:0' to timestamp @t1; +select x as BETWAND_x, y from t1 for system_time between timestamp '0-0-0 0:0:0' and timestamp @t1; +select x as ALL_x, y from t1 for system_time all; + +--disable_query_log +if ($MTR_COMBINATION_TRX_ID) +{ + select x as ASOF2_x, y from t1 for system_time as of @x0; + select x as FROMTO2_x, y from t1 for system_time from @x0 to @x1; + select x as BETWAND2_x, y from t1 for system_time between transaction @x0 and transaction @x1; +} +if ($MTR_COMBINATION_TIMESTAMP) +{ + select x as ASOF2_x, y from t1 for system_time as of @t0; + select x as FROMTO2_x, y from t1 for system_time from timestamp '0-0-0 0:0:0' to timestamp @t1; + select x as BETWAND2_x, y from t1 for system_time between timestamp '0-0-0 0:0:0' and timestamp @t1; +} +--enable_query_log + +# test_02 + +create or replace table t1 ( + x int unsigned, + y int unsigned +) with system versioning; +create or replace table t2 ( + x int unsigned, + y int unsigned +) with system versioning; + +insert into t1 values (1, 1), (1, 2), (1, 3), (4, 4), (5, 5); +insert into t2 values (1, 2), (2, 1), (3, 1); +set @t0= now(6); + +select t1.x as IJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 inner join t2 on t1.x = t2.x; +select t1.x as LJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 left join t2 on t1.x = t2.x; +select t1.x as RJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 right join t2 on t1.x = t2.x; + +delete from t1; +delete from t2; + +#384 +explain extended select * from (select t1.x as IJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 inner join t2 on t1.x = t2.x) +for system_time as of timestamp @t0 as t; +explain extended select * from (select t1.x as LJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 left join t2 on t1.x = t2.x) +for system_time as of timestamp @t0 as t; +#383 +explain extended select * from (select t1.x as RJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 right join t2 on t1.x = t2.x) +for system_time as of timestamp @t0 as t; + +select * from (select t1.x as IJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 inner join t2 on t1.x = t2.x) +for system_time as of timestamp @t0 as t; +select * from (select t1.x as LJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 left join t2 on t1.x = t2.x) +for system_time as of timestamp @t0 as t; +select * from (select t1.x as RJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 right join t2 on t1.x = t2.x) +for system_time as of timestamp @t0 as t; + +drop table t1; +drop table t2; + +# Wildcard expansion on hidden fields + +create table t1( + A int +) with system versioning; +insert into t1 values(1); +select * from t1; + +create or replace table t1 (x int); +insert into t1 values (1); +--error ER_VERS_NOT_VERSIONED +select * from t1 for system_time all; + +create or replace table t1 (x int) with system versioning; +insert into t1 values (1); +select * from t1 for system_time all for update; + +create or replace table t1 (a int not null auto_increment primary key) with system versioning; +select * from (t1 as t2 left join t1 as t3 using (a)) natural left join t1; + +create or replace table t1 (a int) with system versioning; +create or replace table t2 (a int) with system versioning; +insert into t1 values(1); +insert into t2 values(1); +create view v1 as select * from t2 inner join t1 using (a); +select * from v1; +drop view v1; + +create or replace table t1 (a int) with system versioning; +insert into t1 values (1); +create view vt1 as select a from t1; +select * from t1 natural join vt1; +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; + +# @end should be max +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 +select @end; + +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); +insert into t2 values (2); +select * from (select * from t1 cross join t2) as tmp; +select * from (select * from (select * from t1 cross join t2) as tmp1) as tmp2; +select * from (select * from t1 cross join t2 for system_time as of timestamp '0-0-0') as tmp; + +create or replace table t1(a1 int) with system versioning; +create or replace table t2(a2 int) with system versioning; +insert into t1 values(1),(2); +insert into t2 values(1),(2); +select * from t1 for system_time all natural left join t2 for system_time all; + +# natural join of a view and table +create or replace table t1(a1 int) with system versioning; +create or replace table t2(a2 int) with system versioning; +insert into t1 values(1),(2); +insert into t2 values(1),(2); +create or replace view v1 as select a1 from t1; + +select * from v1 natural join t2; +select * from v1 natural left join t2; +select * from v1 natural right join t2; + +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); +select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1; + +create or replace table t1 (x int) with system versioning; +create or replace table t2 (y int) with system versioning; +insert into t1 values (1), (2), (3); +delete from t1 where x = 3; +insert into t2 values (1); +select * from t1, t2 for system_time all; + +--error ER_VERS_NOT_VERSIONED +select * from (select * from t1 for system_time all, t2 for system_time all) +for system_time all as t; + +--echo # TRANSACTION/TIMESTAMP specifier in SYSTEM_TIME [MDEV-14645, Issue #396] +create or replace table t1 (x int) with system versioning engine myisam; +--error ER_VERS_ENGINE_UNSUPPORTED +select * from t1 for system_time as of transaction 1; + +create or replace table t1 ( + x int, + sys_trx_start bigint unsigned as row start invisible, + sys_trx_end bigint unsigned as row end invisible, + period for system_time (sys_trx_start, sys_trx_end) +) with system versioning engine innodb; +insert into t1 values (1); +set @ts= now(6); +delete from t1; +select sys_trx_start from t1 for system_time all into @trx_start; + +--echo ## ensure @trx_start is much lower than unix timestamp +select @trx_start < unix_timestamp(@ts) - 100 as trx_start_good; + +--echo ## TIMESTAMP specifier +select x from t1 for system_time as of timestamp @ts; +select x from t1 for system_time as of timestamp unix_timestamp(@ts); +select x from t1 for system_time as of timestamp @trx_start; + +set @ts= timestamp'1-1-1 0:0:0'; + +--echo ## TRANSACTION specifier +select x from t1 for system_time as of transaction @ts; +select x from t1 for system_time as of transaction unix_timestamp(@ts); +select x from t1 for system_time as of transaction @trx_start; + +--echo ## no specifier (auto-detection) +select x from t1 for system_time as of @ts; +select x from t1 for system_time as of unix_timestamp(@ts); +select x from t1 for system_time as of @trx_start; + + +--echo ### Issue #365, bug 4 (related to #226, optimized fields) +create or replace table t1 (i int, b int) with system versioning; +insert into t1 values (0, 0), (0, 0); +select min(i) over (partition by b) as f +from (select i + 0 as i, b from t1) as tt +order by i; + +--echo ### Issue #365, bug 5 (dangling AND) +create or replace table t1 (a int); +create or replace table t2 (b int) with system versioning; +select * from t1 +where exists (select 1 from t2 where t2.b = t1.a and t2.b = t1.a); + +--echo ### Issue #365, bug 9 (not a derived subquery) +create or replace table t1 (x int) with system versioning; +select t1.x in (select x from t1) a from t1, (select x from t1) b; + +--echo ### Issue #365, bug 10 (WHERE cond freed prematurely for PS) +create or replace table t1 (x int) with system versioning; +insert into t1 values (1); +create or replace view v1 as select x from t1 where x = 1; +prepare stmt from " +select x from t1 where x in (select x from v1);"; +execute stmt; +execute stmt; + +--echo ### Issue #365, bug 11 (WHERE cond not top level item) +create or replace table t1 (a int, b int, key idx(a)) with system versioning; +insert into t1 values (1, 1), (2, 2); +select * from t1 where (a, 2) in ((1, 1), (2, 2)) and b = 1; + +--echo ### Issue #398, NOW is now non-magic +create or replace table t1 (x int) with system versioning; +select * from t1 for system_time as of current_timestamp; +--error ER_BAD_FIELD_ERROR +select * from t1 for system_time as of now; + +--echo ### Issue #405, NATURAL JOIN failure +create or replace table t1 (a int) with system versioning; +create or replace table t2 (b int); +create or replace view v1 as select a, row_start, row_end from t1 where a > round(rand()*1000); +select * from v1 natural join t2; + +--echo ### Issue #406, MDEV-14633 Assertion on TRT read +create or replace table t1 (pk int primary key, i int, t time, key (i)) with system versioning; +insert into t1 values (1, 10, '15:01:53'), (2, 20, '00:00:00'); +delete from t1; +--disable_warnings +select * from t1 where t = '00:00:00' and i > 0 and row_end <> '2012-12-12 00:00:00'; +--enable_warnings + +--echo ### MDEV-14816 Assertion `join->best_read < double(1.797...e+308L)' failed in bool greedy_search +create or replace table t1 (f1 int) with system versioning; +create or replace table t2 (f2 int) with system versioning; +create or replace table t3 (f3 int); +create or replace table t4 (f4 int); +insert into t1 values (1), (2), (3), (4); +insert into t2 values (1), (2), (3); +insert into t3 values (1), (2); +insert into t4 values (1); +select * from + t1 as t1a + left join t2 as t2a left join (t3 as t3a inner join t1) on t2a.f2 = t3a.f3 on t1a.f1 = t2a.f2 + left join (t2 join t3 inner join t4) on t2a.f2 = t1a.f1; + + +drop view v1; +drop table t1, t2, t3, t4; + +call verify_vtq_dummy(34); + +-- source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/t/select2.test b/mysql-test/suite/versioning/t/select2.test new file mode 100644 index 00000000000..81070a960ee --- /dev/null +++ b/mysql-test/suite/versioning/t/select2.test @@ -0,0 +1,211 @@ +--source suite/versioning/engines.inc +--source suite/versioning/common.inc + +let $engine=`select default_engine()`; +let $sys_type=`select sys_datatype(default_engine())`; + +replace_result $engine ENGINE $sys_type SYS_TYPE; +eval create table t1( + x int unsigned, + y int unsigned, + sys_start $sys_type as row start invisible, + sys_end $sys_type as row end invisible, + period for system_time (sys_start, sys_end)) +with system versioning engine=$engine; + +insert into t1 (x, y) values + (0, 100), + (1, 101), + (2, 102), + (3, 103), + (4, 104), + (5, 105), + (6, 106), + (7, 107), + (8, 108), + (9, 109); +set @t0= now(6); +select sys_start from t1 limit 1 into @x0; + +delete from t1 where x = 3; +delete from t1 where x > 7; + +insert into t1(x, y) values(3, 33); +select sys_start from t1 where x = 3 and y = 33 into @t1; +if(`select '$engine' = 'innodb'`) { + set @x1= @t1; + select vtq_commit_ts(@x1) into @t1; +} + +select x, y from t1; +select x as ASOF_x, y from t1 for system_time as of timestamp @t0; +select x as FROMTO_x, y from t1 for system_time from '0-0-0 0:0:0' to timestamp @t1; +select x as BETWAND_x, y from t1 for system_time between '0-0-0 0:0:0' and timestamp @t1; +select x as ALL_x, y from t1 for system_time all; + +if(`select '$engine' = 'innodb'`) { + select x as ASOF2_x, y from t1 for system_time as of @x0; + select x as FROMTO2_x, y from t1 for system_time from @x0 to @x1; + select x as BETWAND2_x, y from t1 for system_time between transaction @x0 and transaction @x1; +} +if(`select '$engine' != 'innodb'`) { + select x as ASOF2_x, y from t1 for system_time as of @t0; + select x as FROMTO2_x, y from t1 for system_time from '0-0-0 0:0:0' to @t1; + select x as BETWAND2_x, y from t1 for system_time between timestamp '0-0-0 0:0:0' and timestamp @t1; +} + +drop table t1; + +replace_result $engine ENGINE $sys_type SYS_TYPE; +eval create table t1( + x int, + y int, + sys_start $sys_type as row start invisible, + sys_end $sys_type as row end invisible, + period for system_time (sys_start, sys_end)) +with system versioning engine=$engine; + +create table t2 like t1; + +insert into t1 values (1, 1), (1, 2), (1, 3), (4, 4), (5, 5); +insert into t2 values (1, 2), (2, 1), (3, 1); +set @t0= now(6); + +select t1.x as IJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 inner join t2 on t1.x = t2.x; +select t1.x as LJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 left join t2 on t1.x = t2.x; +select t1.x as RJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 right join t2 on t1.x = t2.x; + +delete from t1; +delete from t2; + +select IJ2_x1,y1,x2,y2 from (select t1.x as IJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 inner join t2 on t1.x = t2.x) +for system_time as of timestamp @t0 as t; +select LJ2_x1,y1,x2,y2 from (select t1.x as LJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 left join t2 on t1.x = t2.x) +for system_time as of timestamp @t0 as t; +select RJ2_x1,y1,x2,y2 from (select t1.x as RJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 right join t2 on t1.x = t2.x) +for system_time as of timestamp @t0 as t; + +drop table t1; +drop table t2; + +--echo # MDEV-14686 Server crashes in Item_field::used_tables on 2nd call of SP [#422] +create or replace table t1 (called int, bad int) with system versioning; +create or replace procedure bad() select * from t1 where bad in (select called from t1); +--disable_query_log +call bad; call bad; call bad; call bad; call bad; call bad; call bad; call bad; +drop procedure bad; +--enable_query_log +--echo # bad() is good. + +--echo # MDEV-14751 Server crashes in TABLE::versioned on 2nd execution of SP [#431] +create or replace table t1 (called_bad int); +create or replace table t2 (b int); +create or replace procedure bad() select * from t1 where ( 5, 6 ) in ( select b, b from t2 ) and called_bad in ( select max(b) from t2 ); +--disable_query_log +call bad; call bad; call bad; call bad; call bad; call bad; call bad; call bad; +drop procedure bad; +--enable_query_log +--echo # bad() is good. + +--echo # MDEV-14786 Server crashes in Item_cond::transform on 2nd execution of SP querying from a view [#436] +create or replace table t1 (called_bad int) with system versioning; +create or replace view v1 as select called_bad from t1 where called_bad < 5; +create or replace procedure bad() select called_bad from v1; +--disable_query_log +call bad; call bad; call bad; call bad; call bad; call bad; call bad; call bad; +drop procedure bad; +--enable_query_log +--echo # bad() is good. + +--echo # wildcard expansion on hidden fields. +create or replace table t1( + A int +) with system versioning; +insert into t1 values(1); +select * from t1; + +create or replace table t1 (x int); +insert into t1 values (1); +--error ER_VERS_NOT_VERSIONED +select * from t1 for system_time all; + +create or replace table t1 (x int) with system versioning; +insert into t1 values (1); +select * from t1 for system_time as of now() for update; + +create or replace table t1 (a int not null auto_increment primary key) with system versioning; +select * from (t1 as t2 left join t1 as t3 using (a)) natural left join t1; + +create or replace table t1 (a int) with system versioning; +create or replace table t2 (a int) with system versioning; +insert into t1 values(1); +insert into t2 values(1); +create or replace view v1 as select * from t2 inner join t1 using (a); +select * from v1; +drop view v1; + +create or replace table t1 (a int) with system versioning; +insert into t1 values (1); +create view vt1 as select a from t1; +select * from t1 natural join vt1; +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; + +# @end should be max +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 +select @end; + +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); +insert into t2 values (2); +select * from (select * from t1 cross join t2) as tmp; +select * from (select * from (select * from t1 cross join t2) as tmp1) as tmp2; +select * from (select * from t1 cross join t2 for system_time as of timestamp '0-0-0') as tmp; + +create or replace table t1(a1 int) with system versioning; +create or replace table t2(a2 int) with system versioning; +insert into t1 values(1),(2); +insert into t2 values(1),(2); +select * from t1 for system_time all natural left join t2 for system_time all; + +# natural join of a view and table +create or replace table t1(a1 int) with system versioning; +create or replace table t2(a2 int) with system versioning; +insert into t1 values(1),(2); +insert into t2 values(1),(2); +create or replace view v1 as select a1 from t1; + +select * from v1 natural join t2; +select * from v1 natural left join t2; +select * from v1 natural right join t2; + +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); +select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1; + +create or replace table t1 (x int) with system versioning; +create or replace table t2 (y int) with system versioning; +insert into t1 values (1), (2), (3); +delete from t1 where x = 3; +insert into t2 values (1); +select * from t1, t2 for system_time all; + +--error ER_VERS_NOT_VERSIONED +select * from (select * from t1 for system_time all, t2 for system_time all) for system_time all as t; +--error ER_PARSE_ERROR +select * from (t1 for system_time all join t2 for system_time all) for system_time all; + +drop view v1; +drop table t1, t2; + +-- source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/t/simple.test b/mysql-test/suite/versioning/t/simple.test new file mode 100644 index 00000000000..3790f0b8978 --- /dev/null +++ b/mysql-test/suite/versioning/t/simple.test @@ -0,0 +1,73 @@ +-- source include/have_innodb.inc +set default_storage_engine=innodb; +create or replace table dept ( + dept_id int(10) primary key, + name varchar(100) +) +with system versioning; + +create or replace table emp ( + emp_id int(10) primary key, + dept_id int(10), + name varchar(100), + salary int(10), + constraint `dept-emp-fk` + foreign key (dept_id) references dept (dept_id) + on delete cascade + on update restrict +) +with system versioning; + +select now() into @ts_0; + +insert into dept (dept_id, name) values (10, "accounting"); +commit; + +select row_start into @ts_1 from dept where dept_id=10; + +insert into emp (emp_id, name, salary, dept_id) values (1, "bill", 1000, 10); +commit; + +select row_start into @ts_2 from emp where name="bill"; + +select * from emp; + +update emp set salary=2000 where name="bill"; +commit; + +select row_start into @ts_3 from emp where name="bill"; + +select * from emp; +select * from emp for system_time as of timestamp @ts_2; +select * from emp for system_time as of timestamp @ts_3; +select * from emp e, dept d +where d.dept_id = 10 + and d.dept_id = e.dept_id; + +select * from + emp for system_time from timestamp @ts_1 to timestamp @ts_2 e, + dept for system_time from timestamp @ts_1 to timestamp @ts_2 d +where d.dept_id = 10 + and d.dept_id = e.dept_id; + +set statement system_versioning_asof=@ts_0 for +select * from emp e, dept d +where d.dept_id = 10 + and d.dept_id = e.dept_id; + +set statement system_versioning_asof=@ts_1 for +select * from emp e, dept d +where d.dept_id = 10 + and d.dept_id = e.dept_id; + +set statement system_versioning_asof=@ts_2 for +select * from emp e, dept d +where d.dept_id = 10 + and d.dept_id = e.dept_id; + +set statement system_versioning_asof=@ts_3 for +select * from emp e, dept d +where d.dept_id = 10 + and d.dept_id = e.dept_id; + +drop table emp, dept; diff --git a/mysql-test/suite/versioning/t/sysvars.test b/mysql-test/suite/versioning/t/sysvars.test new file mode 100644 index 00000000000..08b520e959e --- /dev/null +++ b/mysql-test/suite/versioning/t/sysvars.test @@ -0,0 +1,87 @@ +create table t (a int) with system versioning; +insert into t values (1); +update t set a= 2; + +show global variables like 'system_versioning_asof'; +show variables like 'system_versioning_asof'; +select * from t; + +set system_versioning_asof= '2031-1-1 0:0:0'; +show variables like 'system_versioning_asof'; +select * from t; + +set system_versioning_asof= '2011-1-1 0:0:0'; +show variables like 'system_versioning_asof'; +select * from t; + +# global +--error ER_WRONG_VALUE_FOR_VAR +set global system_versioning_asof= 'alley'; +--error ER_WRONG_VALUE_FOR_VAR +set global system_versioning_asof= null; +--error ER_WRONG_TYPE_FOR_VAR +set global system_versioning_asof= 1; +--error ER_WRONG_TYPE_FOR_VAR +set global system_versioning_asof= 1.1; + +# session +--error ER_WRONG_VALUE_FOR_VAR +set system_versioning_asof= 'alley'; +--error ER_WRONG_VALUE_FOR_VAR +set system_versioning_asof= null; +--error ER_WRONG_TYPE_FOR_VAR +set system_versioning_asof= 1; +--error ER_WRONG_TYPE_FOR_VAR +set system_versioning_asof= 1.1; + +--echo # GLOBAL @@system_versioning_asof +set global system_versioning_asof= '1911-11-11 11:11:11.1111119'; +show global variables like 'system_versioning_asof'; + +set global system_versioning_asof= '1900-01-01 00:00:00'; +show global variables like 'system_versioning_asof'; + +set global system_versioning_asof= timestamp'1911-11-11 11:11:11.1111119'; +show global variables like 'system_versioning_asof'; + +set @ts= timestamp'1900-01-01 00:00:00'; +set global system_versioning_asof= @ts; +show global variables like 'system_versioning_asof'; + +set global system_versioning_asof= default; +select @@global.system_versioning_asof; + +--echo # SESSION @@system_versioning_asof +set system_versioning_asof= '1911-11-11 11:11:11.1111119'; +show variables like 'system_versioning_asof'; + +set system_versioning_asof= '1900-01-01 00:00:00'; +show variables like 'system_versioning_asof'; + +set system_versioning_asof= timestamp'1911-11-11 11:11:11.1111119'; +show variables like 'system_versioning_asof'; + +set @ts= timestamp'1900-01-01 00:00:00'; +set system_versioning_asof= @ts; +show variables like 'system_versioning_asof'; + +--echo # DEFAULT: value is copied from GLOBAL to SESSION +set global system_versioning_asof= timestamp'1911-11-11 11:11:11.111111'; +set system_versioning_asof= '1900-01-01 00:00:00'; +select @@global.system_versioning_asof != @@system_versioning_asof as different; +set system_versioning_asof= default; +select @@global.system_versioning_asof = @@system_versioning_asof as equal; + +set global system_versioning_asof= DEFAULT; +set system_versioning_asof= DEFAULT; +select @@global.system_versioning_asof, @@system_versioning_asof; + +select * from t for system_time all; + +select * from t; +select * from t for system_time as of timestamp current_timestamp(6); +select * from t for system_time all; +select * from t for system_time from '0-0-0' to current_timestamp(6); +select * from t for system_time between '0-0-0' and current_timestamp(6); + +drop table t; diff --git a/mysql-test/suite/versioning/t/truncate.opt b/mysql-test/suite/versioning/t/truncate.opt new file mode 100644 index 00000000000..b0c5b9c8188 --- /dev/null +++ b/mysql-test/suite/versioning/t/truncate.opt @@ -0,0 +1 @@ +--partition diff --git a/mysql-test/suite/versioning/t/truncate.test b/mysql-test/suite/versioning/t/truncate.test new file mode 100644 index 00000000000..0f9e7052511 --- /dev/null +++ b/mysql-test/suite/versioning/t/truncate.test @@ -0,0 +1,72 @@ +--source suite/versioning/engines.inc + +create table t (a int); +--error ER_VERS_NOT_VERSIONED +delete history from t before system_time now(); + +# TRUNCATE is not DELETE and trigger must not be called. +create or replace table t (a int) with system versioning; +insert into t values (1); +update t set a=2; +set @test = 'correct'; +create trigger trg_before before delete on t for each row set @test = 'incorrect'; +create trigger trg_after after delete on t for each row set @test = 'incorrect'; +delete history from t; +select @test from t; +drop table t; + +create table t (a int) with system versioning; +insert into t values (1), (2); +update t set a=11 where a=1; +--real_sleep 0.01 +set @ts1=now(6); +--real_sleep 0.01 +update t set a=22 where a=2; +select * from t for system_time all; +delete history from t before system_time timestamp @ts1; +select * from t for system_time all; +prepare stmt from 'delete history from t'; +execute stmt; drop prepare stmt; +select * from t for system_time all; +delete from t; + +delimiter ~~; +create or replace procedure truncate_sp() +begin + delete history from t before system_time timestamp now(6); +end~~ +delimiter ;~~ +call truncate_sp; +select * from t for system_time all; + +drop procedure truncate_sp; + +--echo ### Issue #399, truncate partitioned table is now unimplemented + +create or replace table t (a int) +with system versioning +engine myisam +partition by system_time ( + partition p0 history, + partition pn current); + +--error ER_NOT_ALLOWED_COMMAND +delete history from t; + +create or replace table t (i int) with system versioning; +delete history from t; +create or replace view v as select * from t; +--error ER_VERS_TRUNCATE_VIEW +delete history from v; + +create or replace table t (i int); +--error ER_VERS_NOT_VERSIONED +delete history from t; +create or replace view v as select * from t; +--error ER_VERS_TRUNCATE_VIEW +delete history from v; +--error ER_VERS_NOT_VERSIONED +prepare stmt from 'delete history from t'; + +drop table t; +drop view v; diff --git a/mysql-test/suite/versioning/t/truncate_privilege.test b/mysql-test/suite/versioning/t/truncate_privilege.test new file mode 100644 index 00000000000..dcdad59039a --- /dev/null +++ b/mysql-test/suite/versioning/t/truncate_privilege.test @@ -0,0 +1,41 @@ +# Can't test with embedded server +-- source include/not_embedded.inc + +--source include/have_innodb.inc + +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + +connect (root,localhost,root,,test); +connection root; + +--disable_warnings +create database mysqltest; +--enable_warnings + +create user mysqltest_1@localhost; +connect (user1,localhost,mysqltest_1,,test); +connection user1; + +connection root; +create table mysqltest.t (a int) with system versioning; + +connection user1; +show grants; +--error ER_TABLEACCESS_DENIED_ERROR +delete history from mysqltest.t before system_time now(); + +connection root; +grant delete history on mysqltest.* to mysqltest_1@localhost; +grant delete history on mysqltest.t to mysqltest_1@localhost; + +connection user1; +show grants; +delete history from mysqltest.t before system_time now(); + +connection root; +grant all on *.* to mysqltest_1@localhost; +show grants for mysqltest_1@localhost; + +drop user mysqltest_1@localhost; +drop database mysqltest; diff --git a/mysql-test/suite/versioning/t/trx_id.test b/mysql-test/suite/versioning/t/trx_id.test new file mode 100644 index 00000000000..ee4e927b506 --- /dev/null +++ b/mysql-test/suite/versioning/t/trx_id.test @@ -0,0 +1,75 @@ +-- source include/have_innodb.inc +-- source include/not_embedded.inc + +create or replace table t1 ( + x int, + sys_trx_start bigint(20) unsigned as row start invisible, + sys_trx_end bigint(20) unsigned as row end invisible, + period for system_time (sys_trx_start, sys_trx_end) +) with system versioning engine innodb; + +insert into t1 (x) values (1); + +--echo # ALTER ADD SYSTEM VERSIONING should write to mysql.transaction_registry +create function check_result (cond boolean) + returns char(50) deterministic + return if(cond = 1, '[CORRECT]', '[INCORRECT]'); + +set @@system_versioning_alter_history=keep; + +create or replace table t1 (x int) engine innodb; +insert into t1 values (1); +alter table t1 + add column s bigint unsigned as row start, + add column e bigint unsigned as row end, + add period for system_time(s, e), + add system versioning, + algorithm=inplace; +select s from t1 into @trx_start; +select check_result(count(*) = 1) from mysql.transaction_registry where transaction_id = @trx_start; + +create or replace table t1 (x int) engine innodb; +select count(*) from mysql.transaction_registry into @tmp; +alter table t1 + add column s bigint unsigned as row start, + add column e bigint unsigned as row end, + add period for system_time(s, e), + add system versioning, + algorithm=inplace; +select check_result(count(*) = @tmp) from mysql.transaction_registry; + +create or replace table t1 (x int) engine innodb; +insert into t1 values (1); +alter table t1 + add column s bigint unsigned as row start, + add column e bigint unsigned as row end, + add period for system_time(s, e), + add system versioning, + algorithm=copy; +select s from t1 into @trx_start; +select check_result(count(*) = 1) from mysql.transaction_registry where transaction_id = @trx_start; + +create or replace table t1 (x int) engine innodb; +select count(*) from mysql.transaction_registry into @tmp; +alter table t1 + add column s bigint unsigned as row start, + add column e bigint unsigned as row end, + add period for system_time(s, e), + add system versioning, + algorithm=copy; +select check_result(count(*) = @tmp) from mysql.transaction_registry; + + +--echo # TRX_ID to TIMESTAMP versioning switch +create or replace table t1 ( + x int, + sys_start bigint unsigned as row start invisible, + sys_end bigint unsigned as row end invisible, + period for system_time (sys_start, sys_end) +) engine innodb with system versioning; +insert into t1 values (1); +alter table t1 drop column sys_start, drop column sys_end; +select sys_end = 18446744073709551615 as transaction_based from t1 for system_time all; + +drop table t1; +drop function check_result; diff --git a/mysql-test/suite/versioning/t/update.test b/mysql-test/suite/versioning/t/update.test new file mode 100644 index 00000000000..60f20705276 --- /dev/null +++ b/mysql-test/suite/versioning/t/update.test @@ -0,0 +1,288 @@ +-- source suite/versioning/common.inc + +delimiter ~~; +create procedure test_01( + sys_type varchar(255), + engine varchar(255), + fields varchar(255)) +begin + set @str= concat(' + create table t1( + x int unsigned, + y int unsigned, + sys_trx_start ', sys_type, ' as row start invisible, + sys_trx_end ', sys_type, ' as row end invisible, + period for system_time (sys_trx_start, sys_trx_end)) + with system versioning + engine ', engine); + prepare stmt from @str; execute stmt; drop prepare stmt; + insert into t1(x, y) values + (1, 1000), + (2, 2000), + (3, 3000), + (4, 4000), + (5, 5000), + (6, 6000), + (7, 7000), + (8, 8000), + (9, 9000); + select x, y from t1; + update t1 set y = y + 1 where x > 7; + select x, y from t1; + select x, y from t1 for system_time + between timestamp '0000-0-0 0:0:0' + and timestamp '2038-01-19 04:14:07'; + drop table t1; +end~~ + +create procedure test_02( + sys_type varchar(255), + engine varchar(255), + fields varchar(255)) +begin + set @str= concat(' + create table t1 ( + id bigint primary key, + x int, + y int without system versioning, + sys_trx_start ', sys_type, ' as row start invisible, + sys_trx_end ', sys_type, ' as row end invisible, + period for system_time (sys_trx_start, sys_trx_end)) + with system versioning + engine ', engine); + prepare stmt from @str; execute stmt; drop prepare stmt; + insert into t1 values(1, 1, 1); + set @ins_t= now(6); + select sys_trx_start into @tmp1 from t1; + update t1 set x= 11, y= 11 where id = 1; + select @tmp1 < sys_trx_start as A1, x, y from t1; + + select sys_trx_start into @tmp1 from t1; + update t1 set y= 1 where id = 1; + select @tmp1 = sys_trx_start as A2, x from t1; + + drop table t1; +end~~ + +create procedure test_03( + sys_type varchar(255), + engine varchar(255), + fields varchar(255)) +begin + set @str= concat(' + create table t1 ( + x int, + y int, + sys_trx_start bigint unsigned as row start invisible, + sys_trx_end bigint unsigned as row end invisible, + period for system_time (sys_trx_start, sys_trx_end) + ) with system versioning + engine ', engine); + prepare stmt from @str; execute stmt; drop prepare stmt; + + insert into t1 (x, y) values (1, 1), (2, 1), (3, 1), (4, 1), (5, 1); + + start transaction; + update t1 set y= y + 1 where x = 3; + update t1 set y= y + 1 where x = 2; + update t1 set y= y + 1 where x = 3; + update t1 set y= y + 1 where x > 3; + update t1 set y= y + 1 where x > 4; + commit; + + select x, y, sys_trx_end = 18446744073709551615 as current from t1 for system_time all; + + drop table t1; +end~~ + +create procedure test_04( + sys_type varchar(255), + engine varchar(255), + fields varchar(255)) +begin + set @str= concat(' + create table t1 ( + id int primary key auto_increment, + x int, + sys_trx_start ', sys_type, ' as row start invisible, + sys_trx_end ', sys_type, ' as row end invisible, + period for system_time (sys_trx_start, sys_trx_end)) + with system versioning + engine ', engine); + prepare stmt from @str; execute stmt; drop prepare stmt; + + set @t0= now(6); + insert into t1 (x) values (1); + set @t1= now(6); + update t1 set x= 2 where id = 1; + set @t2= now(6); + update t1 set x= 3 where id = 1; + + select x from t1 for system_time as of timestamp @t0; + select x from t1 for system_time as of timestamp @t1; + select x from t1 for system_time as of timestamp @t2; + select x from t1 for system_time as of timestamp now(6); + + drop table t1; +end~~ + +create procedure test_05( + sys_type varchar(255), + engine varchar(255), + fields varchar(255)) +begin + set @str= concat(' + create table t1( + x int unsigned, + sys_trx_end ', sys_type, ' as row end invisible, + sys_trx_start ', sys_type, ' as row start invisible, + y int unsigned, + period for system_time (sys_trx_start, sys_trx_end), + primary key(x, y)) + with system versioning + engine ', engine); + prepare stmt from @str; execute stmt; drop prepare stmt; + insert into t1(x, y) values + (1, 1000), + (3, 3000), + (4, 4000), + (5, 5000); + insert into t1(x, y) values(3, 3000) on duplicate key update y = y+1; + insert into t1(x, y) values(4, 4444) on duplicate key update y = y+1; + select x, y from t1 for system_time all; + select x, y from t1; + drop table t1; +end~~ + +create procedure test_06( + sys_type varchar(255), + engine varchar(255), + fields varchar(255)) +begin + set @str= concat('( + x int unsigned, + y int unsigned, + sys_trx_start ', sys_type, ' as row start invisible, + sys_trx_end ', sys_type, ' as row end invisible, + period for system_time (sys_trx_start, sys_trx_end)) + with system versioning + engine ', engine); + set @str2= concat('create table t1', @str); + prepare stmt from @str2; execute stmt; drop prepare stmt; + set @str2= concat('create table t2', @str); + prepare stmt from @str2; execute stmt; drop prepare stmt; + insert into t1(x, y) values + (1, 1000), + (2, 2000), + (3, 3000), + (4, 4000), + (5, 5000), + (6, 6000), + (7, 7000), + (8, 8000), + (9, 9000); + insert into t2(x, y) values + (1, 1010), + (2, 2010), + (3, 3010), + (4, 4010), + (5, 5010), + (6, 6010), + (7, 7010), + (8, 8010), + (9, 9010); + update t1, t2 set t1.y = t1.x + t1.y, t2.y = t2.x + t2.y where t1.x > 7 and t2.x < 7; + select x, y from t1 for system_time between timestamp '0-0-0 0:0:0' and timestamp '9999-1-1 0:0:0'; + select x, y from t1; + select x, y from t2 for system_time between timestamp '0-0-0 0:0:0' and timestamp '9999-1-1 0:0:0'; + select x, y from t2; + drop table t1; + drop table t2; +end~~ + +create procedure test_07( + sys_type varchar(255), + engine varchar(255), + fields varchar(255)) +begin + set @str= concat('( + id bigint primary key without system versioning, + name varchar(128), + salary bigint without system versioning, + sys_trx_start ', sys_type, ' as row start invisible, + sys_trx_end ', sys_type, ' as row end invisible, + period for system_time (sys_trx_start, sys_trx_end)) + with system versioning + engine ', engine); + + set @str2= concat('create table t1', @str); + prepare stmt from @str2; execute stmt; drop prepare stmt; + set @str2= concat('create table t2', @str); + prepare stmt from @str2; execute stmt; drop prepare stmt; + + insert into t1 values (1, "Jeremy", 3000); + insert into t2 values (1, "Jeremy", 4000); + + select sys_trx_start into @tmp1 from t1; + select sys_trx_start into @tmp2 from t2; + update t1, t2 set t1.name= "Jerry", t2.name= "Jerry" where t1.id = t2.id and t1.name = "Jeremy"; + select @tmp1 < sys_trx_start as A1, name from t1; + select @tmp2 < sys_trx_start as A2, name from t2; + + select sys_trx_start into @tmp1 from t1; + select sys_trx_start into @tmp2 from t2; + update t1, t2 set t1.salary= 2500, t2.salary= 2500 where t1.id = t2.id and t1.name = "Jerry"; + select @tmp1 = sys_trx_start as B1, salary from t1; + select @tmp2 = sys_trx_start as B2, salary from t2; + + drop table t1; + drop table t2; +end~~ +delimiter ;~~ + +call test_01('timestamp(6)', 'myisam', 'sys_trx_end'); +call test_01('timestamp(6)', 'innodb', 'vtq_commit_ts(sys_trx_end)'); +call test_01('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_trx_end)'); +call verify_vtq; + +call test_02('timestamp(6)', 'myisam', 'sys_trx_end'); +call test_02('timestamp(6)', 'innodb', 'vtq_commit_ts(sys_trx_end)'); +call test_02('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_trx_end)'); +call verify_vtq; + +--echo # Multiple UPDATE of same rows in single transaction create historical +--echo # rows only once (applicable to transaction-based only). +call test_03('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_trx_end)'); +call verify_vtq; + +call test_04('timestamp(6)', 'myisam', 'sys_trx_end'); +call test_04('timestamp(6)', 'innodb', 'vtq_commit_ts(sys_trx_end)'); +call test_04('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_trx_end)'); +call verify_vtq; + +call test_05('timestamp(6)', 'myisam', 'sys_trx_end'); +call test_05('timestamp(6)', 'innodb', 'vtq_commit_ts(sys_trx_end)'); +call test_05('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_trx_end)'); +call verify_vtq; + +call test_06('timestamp(6)', 'myisam', 'sys_trx_end'); +call test_06('timestamp(6)', 'innodb', 'vtq_commit_ts(sys_trx_end)'); +call test_06('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_trx_end)'); +call verify_vtq; + +--echo # Optimized fields +call test_07('timestamp(6)', 'myisam', 'sys_trx_end'); +call test_07('timestamp(6)', 'innodb', 'vtq_commit_ts(sys_trx_end)'); +call test_07('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_trx_end)'); +call verify_vtq; + +--echo ### Issue #365, bug 7 (duplicate of historical row) +create or replace table t1 (a int primary key, b int) +with system versioning engine myisam; +insert into t1 (a) values (1); +--replace_regex /'1-[- .\d:]+'/'1-YYYY-MM-DD hh:mm:ss.uuuuuu'/ +--error ER_DUP_ENTRY +replace t1 values (1,2),(1,3),(2,4); + +drop database test; +create database test; diff --git a/mysql-test/suite/versioning/t/view.test b/mysql-test/suite/versioning/t/view.test new file mode 100644 index 00000000000..56e322477e7 --- /dev/null +++ b/mysql-test/suite/versioning/t/view.test @@ -0,0 +1,102 @@ +--source suite/versioning/engines.inc +--source suite/versioning/common.inc + +create or replace table t1 (x int) with system versioning; +insert into t1 values (1); + +select now(6) into @t1; +update t1 set x= 2; + +select now(6) into @t2; +delete from t1; + +set @vt1= concat("create or replace view vt1 as select * from t1 for system_time as of timestamp '", @t1, "'"); +prepare stmt from @vt1; execute stmt; drop prepare stmt; + +set @vt2= concat("create or replace view vt2 as select *, row_end from t1 for system_time as of timestamp '", @t2, "'"); +prepare stmt from @vt2; execute stmt; drop prepare stmt; + +select * from t1; + +create or replace view vt1 as select * from t1; +--replace_result 18446744073709551615 MAX_RESULT "TIMESTAMP'2038-01-19 03:14:07.999999'" MAX_RESULT +show create view vt1; + +drop view vt1; +drop view vt2; + +create or replace view vt1 as select * from t1 for system_time all; +select * from vt1; +prepare stmt from 'select * from vt1'; execute stmt; drop prepare stmt; + +set @str= concat('create or replace view vt1 as +select * from t1 for system_time as of timestamp "', @t1, '"'); +prepare stmt from @str; execute stmt; drop prepare stmt; +select * from t1 for system_time as of timestamp @t1; +select * from vt1; + +insert into vt1 values (3); +select * from t1; +select * from vt1; + +create or replace table t1 (x int) with system versioning; +insert into t1 values (1), (2); +set @t1=now(6); +delete from t1 where x=2; +set @t2=now(6); +delete from t1 where x=1; +set @t3=now(6); + +set @tmp= concat("create or replace view vt1 as select * from t1 for system_time as of timestamp '", @t1, "'"); +prepare stmt from @tmp; execute stmt; drop prepare stmt; + +select * from vt1; + +--echo # VIEW with parameters [#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 +show create view vt1; + +--echo # VIEW over JOIN of versioned tables [#153] +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); +insert into t2 values (2); +create or replace view vt12 as select * from t1 cross join t2; +select * from vt12; +create or replace view vt12 as select * from t1 for system_time as of timestamp '0-0-0' cross join t2; +select * from vt12; + +--echo # VIEW improvements [#183] +create or replace table t3 (x int); +create or replace view vt1 as select * from t1, t2, t3; +--replace_result 18446744073709551615 MAX_RESULT "TIMESTAMP'2038-01-19 03:14:07.999999'" MAX_RESULT +show create view vt1; +create or replace view vt1 as select * from t3, t2, t1; +--replace_result 18446744073709551615 MAX_RESULT "TIMESTAMP'2038-01-19 03:14:07.999999'" MAX_RESULT +show create view vt1; +create or replace view vt1 as select a, t2.row_end as endo from t3, t1, t2; +--replace_result 18446744073709551615 MAX_RESULT "TIMESTAMP'2038-01-19 03:14:07.999999'" MAX_RESULT +show create view vt1; + +--echo # VIEW over UNION [#269] +create or replace view vt1 as select * from t1 union select * from t1; +select * from vt1; + +--echo # VIEW over UNION with non-versioned [#393] +create or replace table t2 (a int); +create or replace view vt1 as select * from t1 union select * from t2; +select * from vt1; + +--echo # MDEV-14689 crash on second PS execute +create or replace table t1 (a int); +create or replace view v1 as select * from t1; +create or replace table t2 (b int) with system versioning; +prepare stmt from 'select a from v1 inner join t2 group by a order by a'; +execute stmt; +execute stmt; + + +drop database test; +create database test; diff --git a/mysql-test/suite/versioning/t/vtmd.opt b/mysql-test/suite/versioning/t/vtmd.opt new file mode 100644 index 00000000000..3596fc4d3bd --- /dev/null +++ b/mysql-test/suite/versioning/t/vtmd.opt @@ -0,0 +1 @@ +--innodb --default-storage-engine=innodb diff --git a/mysql-test/suite/versioning/t/vtmd.test b/mysql-test/suite/versioning/t/vtmd.test new file mode 100644 index 00000000000..56bdb3d2546 --- /dev/null +++ b/mysql-test/suite/versioning/t/vtmd.test @@ -0,0 +1,204 @@ +-- source include/have_innodb.inc +delimiter ~~; +create or replace procedure drop_archives (in vtmd_name varchar(64)) +begin + declare archive_name varchar(64); + declare cur_done bool default false; + declare cur cursor for + select cur_tmp.archive_name from cur_tmp; + declare continue handler for not found set cur_done = true; + + set @tmp= concat(' + create or replace temporary table + cur_tmp as + select vtmd.archive_name from ', vtmd_name, ' + for system_time all as vtmd + where vtmd.archive_name is not null + group by vtmd.archive_name'); + prepare stmt from @tmp; execute stmt; drop prepare stmt; + + open cur; + fetch_loop: loop + fetch cur into archive_name; + if cur_done then + leave fetch_loop; + end if; + set @tmp= concat('drop table ', archive_name); + prepare stmt from @tmp; execute stmt; drop prepare stmt; + end loop; + + drop table cur_tmp; +end~~ +delimiter ;~~ + +delimiter ~~; +create or replace procedure check_vtmd (in vtmd_name varchar(64)) +begin + set @tmp= concat(' + create or replace temporary table + tmp_vtmd with system versioning as + select * from ', vtmd_name, ' + for system_time all as vtmd'); + prepare stmt from @tmp; execute stmt; drop prepare stmt; + + set @inf= 0xFFFFFFFFFFFFFFFF + 0; + set @start= null; + select start from tmp_vtmd for system_time all order by start limit 1 into @start; + select @start > 0 and @start < @inf; + select + start >= @start as A_start, + (@start:= end) and end = @inf as B_end, + name, + substr(archive_name, 1, instr(archive_name, '_')) as C_archive_name + from tmp_vtmd for system_time all; + + drop table tmp_vtmd; +end~~ +delimiter ;~~ + +delimiter ~~; +create or replace procedure show_tables() +begin + show tables; + select table_name, table_schema from information_schema.tables + where table_schema not in ('mysql', 'performance_schema', 'information_schema', 'mtr') + order by table_name; +end~~ +delimiter ;~~ + +# create +set versioning_alter_history= keep; +create table t0 (z int) with system versioning; +show tables; +set versioning_alter_history= survive; +create or replace table t0 (y int) with system versioning; +show tables; +show create table t0_vtmd; +call check_vtmd('t0_vtmd'); + +set versioning_alter_history= keep; +drop table t0; +set versioning_alter_history= survive; +--error ER_VERS_VTMD_ERROR +create table t0 (x int) with system versioning; + +drop table t0_vtmd; +create table t0 (y int) with system versioning; +create or replace table t0 (x int) with system versioning; + +# alter +insert into t0 values (1); +set @t0= now(6); +alter table t0 add column (y int); +select * from t0 for system_time as of @t0; +select * from t0; +call check_vtmd('t0_vtmd'); + +call drop_archives('t0_vtmd'); +drop table t0_vtmd; +alter table t0 drop column y; +call check_vtmd('t0_vtmd'); + +call drop_archives('t0_vtmd'); +set versioning_alter_history= keep; +drop tables t0, t0_vtmd; +set versioning_alter_history= survive; + +# rename +set versioning_alter_history= keep; +create or replace table x0 (x int) with system versioning; +set versioning_alter_history= survive; +rename table x0 to d0; +show tables; + +set versioning_alter_history= keep; +drop table d0; +set versioning_alter_history= survive; +create or replace table x0 (x int) with system versioning; +rename table x0 to d0; +show tables; +call check_vtmd('d0_vtmd'); + +set versioning_alter_history= keep; +drop table d0; +set versioning_alter_history= survive; +create or replace table x0 (x int) with system versioning; + +--error ER_VERS_VTMD_ERROR +rename table x0 to d0; +show tables; + +drop table x0_vtmd; +rename table x0 to d0; +show tables; + +rename table d0 to duck; +rename table duck to bay; +rename table bay to sheer; +rename table sheer to t0; +call check_vtmd('t0_vtmd'); + +alter table t0 add column (y int); +call check_vtmd('t0_vtmd'); + +# rename to different schema +alter table t0 add column (z int); +alter table t0 drop column y; +alter table t0 drop column z; + +create database db0; +rename table t0 to db0.t0; +show tables; +use db0; +show tables; +call test.check_vtmd('db0.t0_vtmd'); + +create database db1; +rename table t0 to db1.other_name; +show tables; +use db1; +show tables; +call test.check_vtmd('db1.other_name_vtmd'); + +# alter rename +alter table other_name rename to t1; +call test.check_vtmd('db1.t1_vtmd'); + +# alter rename and modify to different schema +alter table t1 rename to test.t2, add column (y int); +use test; +show tables; +call check_vtmd('t2_vtmd'); + +create or replace table t3 (x int) with system versioning; +alter table t3 change x x bigint; +alter table t3 change x x bigint after sys_trx_start; +call check_vtmd('t3_vtmd'); + +# hide archive tables +set versioning_hide= auto; +call show_tables(); + +set versioning_hide= implicit; +call show_tables(); + +set versioning_hide= full; +call show_tables(); + +set versioning_hide= never; +--replace_regex /\d{8}_\d{6}_\d{6}/TIMESTAMP_SUFFIX/ +call show_tables(); + +# wrong VTMD handling +set versioning_hide= auto; +create or replace table u0_vtmd (x int) with system versioning; +show tables; + +set versioning_alter_history= survive; +create or replace table t (x int) with system versioning; +select * from t for system_time all; + +drop database db0; +drop database db1; +drop database test; +create database test; diff --git a/mysql-test/suite/versioning/t/vtmd_show.opt b/mysql-test/suite/versioning/t/vtmd_show.opt new file mode 100644 index 00000000000..627becdbfb5 --- /dev/null +++ b/mysql-test/suite/versioning/t/vtmd_show.opt @@ -0,0 +1 @@ +--innodb diff --git a/mysql-test/suite/versioning/t/vtmd_show.test b/mysql-test/suite/versioning/t/vtmd_show.test new file mode 100644 index 00000000000..4397198c839 --- /dev/null +++ b/mysql-test/suite/versioning/t/vtmd_show.test @@ -0,0 +1,90 @@ +delimiter ~~; +create or replace procedure drop_archives (in vtmd_name varchar(64)) +begin + declare archive_name varchar(64); + declare cur_done bool default false; + declare cur cursor for + select cur_tmp.archive_name from cur_tmp; + declare continue handler for not found set cur_done = true; + + set @tmp= concat(' + create or replace temporary table + cur_tmp as + select vtmd.archive_name from ', vtmd_name, ' + for system_time all as vtmd + where vtmd.archive_name is not null + group by vtmd.archive_name'); + prepare stmt from @tmp; execute stmt; drop prepare stmt; + + open cur; + fetch_loop: loop + fetch cur into archive_name; + if cur_done then + leave fetch_loop; + end if; + set @tmp= concat('drop table ', archive_name); + prepare stmt from @tmp; execute stmt; drop prepare stmt; + end loop; + + drop table cur_tmp; +end~~ +delimiter ;~~ + +delimiter ~~; +create procedure test_01(in engine varchar(64)) +begin + set @tmp = concat('create table t (a int) with system versioning engine ', engine); + prepare stmt from @tmp; execute stmt; drop prepare stmt; + + set @tm1 = now(6); + alter table t add column b int; + + set @tm2 = now(6); + alter table t add column c int; + + show create table t for system_time as of timestamp @tm1; + show create table t for system_time as of timestamp @tm2; + show create table t for system_time as of now; + show create table t for system_time as of timestamp now(6); + show create table t; + + set @tm3 = now(6); + rename table t to tt; + show create table tt for system_time as of timestamp @tm3; + + set @tm4 = now(6); + alter table tt add column d int; + show create table tt for system_time as of timestamp @tm3; + show create table tt for system_time as of timestamp @tm4; + show create table tt; + + drop table tt; + call drop_archives('tt_vtmd'); + drop table tt_vtmd; +end~~ +delimiter ;~~ + +create table t (a int) with system versioning; +--error ER_VERS_VTMD_ERROR +show create table t for system_time as of now; + +set versioning_alter_history=survive; + +create or replace table t (a int) with system versioning; +--error ER_VERS_RANGE_PROHIBITED +show create table t for system_time between timestamp @tm1 and timestamp @tm1; +--error ER_VERS_RANGE_PROHIBITED +show create table t for system_time from timestamp @tm1 to timestamp @tm1; +--error ER_VERS_VTMD_ERROR +show create table t for system_time as of timestamp '01-01-1990'; +--error ER_VERS_VTMD_ERROR +show create table t for system_time as of timestamp '01-01-2020'; +drop table t; +call drop_archives('t_vtmd'); +drop table t_vtmd; + +call test_01('myisam'); +call test_01('innodb'); + +drop procedure test_01; +drop procedure drop_archives; diff --git a/mysql-test/suite/versioning/wait_system_clock.inc b/mysql-test/suite/versioning/wait_system_clock.inc new file mode 100644 index 00000000000..21bbe7aea21 --- /dev/null +++ b/mysql-test/suite/versioning/wait_system_clock.inc @@ -0,0 +1,10 @@ +# +# windows has a rather low-resolution system clock +# wait until the event from the past will actually be in the past +# +if (`select @@version_compile_os in ("win32","win64","windows")`) +{ + let $_past=`select max(row_start) from t1`; + --let $wait_condition=select TIMESTAMP'$_past' < sysdate(6) + --source include/wait_condition.inc +} |