diff options
Diffstat (limited to '')
36 files changed, 9616 insertions, 0 deletions
diff --git a/mysql-test/suite/versioning/t/alter.test b/mysql-test/suite/versioning/t/alter.test new file mode 100644 index 00000000..61653550 --- /dev/null +++ b/mysql-test/suite/versioning/t/alter.test @@ -0,0 +1,705 @@ +--source include/default_charset.inc +--source suite/versioning/common.inc + +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_NOT_ALLOWED +alter table t add primary key (a); +--error ER_VERS_ALTER_NOT_ALLOWED +alter table t add unique key (a); +--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; + +alter table t add system versioning; +--error ER_CANT_DROP_FIELD_OR_KEY +alter table t drop system versioning, drop column row_start; +alter table t drop system versioning; + +--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; + +--error ER_MISSING +alter table t drop system versioning; + +alter table t drop column trx_start, drop column trx_end; +select row_start from t; +alter table t drop system versioning; +show create table t; + +--error ER_VERS_NOT_VERSIONED +alter table t add column trx_start timestamp(6) as row start; + +alter table t add system versioning; +show create table t; + +--error ER_VERS_DUPLICATE_ROW_START_END +alter table t add column trx_start timestamp(6) as row start; +--error ER_VERS_DUPLICATE_ROW_START_END +alter table t modify a int as row start; + +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; +show create table t; + +--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; +--enable_prepare_warnings +select row_start from t where a=3 into @tm; +--disable_prepare_warnings +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 +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_trt; +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_trt; + +show create table t; +alter table t drop column trx_start, drop column trx_end; + +call verify_trt; +alter table t drop system versioning, algorithm=copy; +call verify_trt; + +alter table t add system versioning, algorithm=copy; +call verify_trt; + +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_trt; + +alter table t drop column b, algorithm=copy; +show create table t; +select * from t for system_time all; +call verify_trt; + +## FIXME: #414 IB: inplace for VERS_TIMESTAMP versioning +if (0) +{ +alter table t drop system versioning, algorithm=inplace; +call verify_trt; + +alter table t add system versioning, algorithm=inplace; +call verify_trt; +show create table t; + +update t set a= 1; +select * from t for system_time all; +call verify_trt; + +alter table t add column b int, algorithm=inplace; +show create table t; +select * from t; +call verify_trt; + +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_trt; + +# 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; +alter table t add c int, drop system versioning; +select * from t; + +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, b int primary key, c int unique) with system versioning; +insert t values (1,2,3),(1,3,4),(1,4,5); +alter table t drop system versioning; +show create table t; +select * from 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; +--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_trt; +} + +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_NOT_SUPPORTED +alter table t change column if exists b c bigint unsigned generated always as row start; +--error ER_VERS_NOT_SUPPORTED +alter table t change column if exists b c bigint unsigned generated always as row end; +--error ER_VERS_NOT_SUPPORTED +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, + 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) +) with system versioning; +show create table t; + +alter table t + drop column row_start, + drop column row_end, + drop period for system_time, + drop system versioning; +show create table t; + +--error ER_VERS_NOT_VERSIONED +alter table t drop period for system_time; + +create or replace table t ( + a int, + 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) +) with system versioning; +--error ER_MISSING +alter table t drop period for system_time; +--error ER_MISSING +alter table t drop column sys_trx_start, drop period for system_time; +--error ER_MISSING +alter table t drop column sys_trx_end, drop period for system_time; + +--error ER_VERS_ALREADY_VERSIONED +alter table t add period for system_time(sys_trx_start, sys_trx_end); + +--echo # +--echo # MDEV-14790 System versioning for system tables does not work as expected +--echo # +use mysql; +--error ER_VERS_DB_NOT_SUPPORTED +create or replace table t (x int) with system versioning; +--error ER_VERS_DB_NOT_SUPPORTED +alter table db add system versioning; +use test; + +--echo # MDEV-15956 Strange ER_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN upon ALTER on versioning column +create or replace table t1 (i int, j int as (i), s timestamp(6) as row start, e timestamp(6) as row end, period for system_time(s,e)) with system versioning; +--error ER_VERS_DUPLICATE_ROW_START_END +alter table t1 modify s timestamp(6) as row start; + +--echo # ignore CHECK for historical rows +create or replace table t (a int) with system versioning; +insert into t values (0), (1); +delete from t where a = 0; +--error ER_CONSTRAINT_FAILED +alter table t add check (a > 1); +alter table t add check (a > 0); +--error ER_CONSTRAINT_FAILED +insert into t values (0); +insert into t values (2); +drop table t; + +--echo # +--echo # MDEV-18869 Assertion `!((field)->vcol_info && (field)->stored_in_db())' failed in innodb_col_no upon altering table with system versioning +--echo # +set system_versioning_alter_history= keep; +create or replace table t1 (a int, b int generated always as (0) stored) engine=innodb with system versioning; +insert into t1 (a) values (1); +--enable_info +alter table t1 modify a int without system versioning, algorithm=copy; +alter table t1 modify a int with system versioning, algorithm=copy; +alter table t1 modify a int without system versioning; +alter table t1 modify a int with system versioning; +--disable_info +show create table t1; +select * from t1; +--enable_info +--error ER_PARSE_ERROR +alter table t1 modify b int generated always as (0) stored without system versioning; +--error ER_PARSE_ERROR +alter table t1 modify b int generated always as (0) stored with system versioning; +alter table t1 modify b int without system versioning; +--disable_info +show create table t1; +select * from t1; + +create or replace table t1 (a int, b int generated always as (0) virtual) engine=innodb with system versioning; +insert into t1 (a) values (1); +--enable_info +alter table t1 modify a int without system versioning, algorithm=copy; +alter table t1 modify a int with system versioning, algorithm=copy; +alter table t1 modify a int without system versioning; +alter table t1 modify a int with system versioning; +select * from t1; +--disable_info + +--echo # +--echo # MDEV-19304 Segfault in ALTER TABLE after UPDATE for SIMULTANEOUS_ASSIGNMENT +--echo # +create or replace table t1 (a int, s timestamp(6) as row start, e timestamp(6) as row end, period for system_time(s,e)) engine=myisam with system versioning; +insert into t1 values (null, null, null); +insert into t1 values (null, null, null); +set sql_mode= 'simultaneous_assignment'; +update t1 set e= 1; +alter table t1 force; +set sql_mode= default; + +--echo # +--echo # MDEV-18862 Unfortunate error message upon attempt to drop system versioning +--echo # +set system_versioning_alter_history= keep; +create or replace table t1 (x int) with system versioning; +--error ER_CANT_DROP_FIELD_OR_KEY +alter table t1 drop column `row_start`, drop column `row_end`, drop period for system_time, drop system versioning; +--error ER_CANT_DROP_FIELD_OR_KEY +alter table t1 drop period for system_time; +--error ER_CANT_DROP_FIELD_OR_KEY +alter table t1 drop column `row_start`, drop column `row_end`, drop system versioning; +--error ER_CANT_DROP_FIELD_OR_KEY +alter table t1 drop column `row_end`; + +--echo # +--echo # MDEV-19127 Assertion `row_start_field' failed in vers_prepare_keys upon ALTER TABLE +--echo # +set system_versioning_alter_history=keep; +create or replace table t1 (f1 int) with system versioning; +alter table t1 add f2 int with system versioning, drop system versioning; +create or replace table t1 (f1 int) with system versioning; +--error ER_VERS_NOT_VERSIONED +alter table t1 drop system versioning, add f2 int with system versioning; + +drop table t1; +--source suite/versioning/common_finish.inc +--echo # MDEV-16490 It's possible to make a system versioned table without any versioning field + +set @@system_versioning_alter_history=keep; +create or replace table t (a int) with system versioning engine=innodb; +--error ER_VERS_TABLE_MUST_HAVE_COLUMNS +alter table t change column a a int without system versioning; + +alter table t + change column a a int without system versioning, + add column b int with system versioning; +show create table t; + +alter table t + change column a new_a int, + drop system versioning; +show create table t; + +alter table t add system versioning; +alter table t change column new_a a int without system versioning; +show create table t; + +--error ER_VERS_TABLE_MUST_HAVE_COLUMNS +alter table t + add column c int, + change column c c int without system versioning, + change column b b int without system versioning; + +alter table t + add column c int without system versioning, + change column c c int, + change column b b int without system versioning; + +drop table t; + +--echo # +--echo # MDEV-21688 Assertion or ER_WARN_DATA_OUT_OF_RANGE upon ALTER on previously versioned table +--echo # +create or replace table t1 (a int) with system versioning; +insert into t1 values (128); +delete from t1; +set statement system_versioning_alter_history=keep for +alter table t1 drop system versioning, modify column a tinyint; + +# cleanup +drop table t1; + +--echo # +--echo # MDEV-24690 Dropping primary key column from versioned table always fails with 1072 +--echo # +create table t1 (a int, b int primary key) with system versioning; +alter table t1 drop column b; + +create or replace table t1 ( + a int, b int primary key, + row_start timestamp(6) as row start, + row_end timestamp(6) as row end, + period for system_time(row_start, row_end) +) with system versioning; +show create table t1; +--error ER_KEY_COLUMN_DOES_NOT_EXIST +alter table t1 drop column b; + +create or replace table t1 ( +a int, b int primary key, + 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; +show create table t1; +--error ER_KEY_COLUMN_DOES_NOT_EXIST +alter table t1 drop column b; + +# cleanup +drop table t1; + +--echo # +--echo # MDEV-25172 Wrong error message for ADD COLUMN .. AS ROW START +--echo # +create or replace table t1 (x int); +--error ER_VERS_NOT_VERSIONED +alter table t1 add column y timestamp(6) as row start; +# cleanup +drop table t1; + + +--echo # +--echo # MDEV-25327 Unexpected ER_DUP_ENTRY upon dropping PK column from system-versioned table +--echo # +create table t1 (pk int, a int, primary key (pk), key (a)) +with system versioning; +insert into t1 values (1, 1), (2, 2); +delete from t1; +set system_versioning_alter_history= keep; +alter table t1 drop pk; +# cleanup +drop table t1; + +create table t1 (pk int, a int, primary key (pk), key (a)) +with system versioning; +insert into t1 values (1, 2), (2, 8), (3, 4), (4, 4), (5, 0); +delete from t1; +set system_versioning_alter_history= keep; +alter ignore table t1 drop pk; +# cleanup +drop table t1; + + +--echo # +--echo # MDEV-22660 SIGSEGV on adding system versioning and modifying system column +--echo # +create or replace table t1 (a int); +--error ER_VERS_PERIOD_COLUMNS +alter table t1 + add row_start timestamp(6) as row start, + add row_end timestamp(6) as row end, + add period for system_time(row_start, row_end), + with system versioning, + modify row_end varchar(8); +--error ER_VERS_PERIOD_COLUMNS +alter table t1 + add row_start timestamp(6) as row start, + add row_end timestamp(6) as row end, + add period for system_time(row_start, row_end), + with system versioning, + modify row_start varchar(8); +# cleanup +drop table t1; + + +--echo # +--echo # MDEV-21941 RENAME doesn't work for system time or period fields +--echo # +create or replace table t1 (a int) with system versioning; +--error ER_BAD_FIELD_ERROR +alter table t1 rename column row_start to x; + +create or replace table t1 ( + 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 t1 rename column row_start to x; +alter table t1 rename column row_end to y; + +show create table t1; +# cleanup +drop table t1; + +--echo # End of 10.5 tests diff --git a/mysql-test/suite/versioning/t/autoinc.test b/mysql-test/suite/versioning/t/autoinc.test new file mode 100644 index 00000000..7c87c173 --- /dev/null +++ b/mysql-test/suite/versioning/t/autoinc.test @@ -0,0 +1,63 @@ +-- source suite/versioning/engines.inc +-- source suite/versioning/common.inc + +--replace_result $sys_datatype_expl SYS_DATATYPE +eval create table t1( + id int unsigned auto_increment primary key, + x int unsigned, + y int unsigned, + 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; + +eval create table t2( + id int unsigned auto_increment primary key, + x int unsigned, + y int unsigned); + +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; + +--echo # +--echo # MDEV-22562 Assertion `next_insert_id == 0' upon UPDATE on system-versioned table +--echo # +create table t1 (pk integer auto_increment primary key) engine=myisam with system versioning; +insert delayed into t1 (pk) values (1); +lock tables t1 write; +update t1 set pk= 0; +update t1 set pk= 0; +unlock tables; + +# cleanup +drop table t1; + +-- source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/t/binlog.test b/mysql-test/suite/versioning/t/binlog.test new file mode 100644 index 00000000..8b6de96d --- /dev/null +++ b/mysql-test/suite/versioning/t/binlog.test @@ -0,0 +1,18 @@ +--source include/have_log_bin.inc + +--echo # +--echo # MDEV-29741 SHOW BINLOG EVENTS shows garbage with system_versioning_insert_history=on +--echo # MDEV-29732 mysqlbinlog produces syntactically incorrect output with system_versioning_insert_history +--echo # +reset master; +set timestamp=1000000000; +create table t (a int) with system versioning; +set system_versioning_insert_history= on; +insert into t (a) values (1); +set system_versioning_insert_history= off; +drop table t; +source include/show_binlog_events.inc; +flush binary logs; +--let $datadir=`select @@datadir` +--exec $MYSQL_BINLOG -s $datadir/master-bin.000001 +set timestamp=default; 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 00000000..96461f5c --- /dev/null +++ b/mysql-test/suite/versioning/t/commit_id.test @@ -0,0 +1,98 @@ +-- 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; + + +# TRT_TRX_ID, TRT_COMMIT_ID, TRT_TRX_SEES # + +insert into t1 values (); + +--real_sleep 0.01 +set @ts0= now(6); +insert into t1 values (); + +--enable_prepare_warnings + +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 + trt_trx_id(@ts0) < @tx0 as A, + trt_trx_id(@ts0, true) = @tx0 as B, + trt_trx_id(@ts1) = @tx0 as C, + trt_trx_id(@ts1, true) = @tx1 as D, + trt_trx_id(@ts2) = @tx1 as E, + trt_trx_id(@ts2, true) = @tx2 as F, + trt_trx_id(@ts3) = @tx2 as G, + trt_trx_id(@ts3, true) is null as H; + +select + trt_commit_id(@ts0) < @tx0 as A, + trt_commit_id(@ts0, true) = trt_commit_id(null, @tx0) as B, + trt_commit_id(@ts1) = trt_commit_id(null, @tx0) as C, + trt_commit_id(@ts1, true) = trt_commit_id(null, @tx1) as D, + trt_commit_id(@ts2) = trt_commit_id(null, @tx1) as E, + trt_commit_id(@ts2, true) = trt_commit_id(null, @tx2) as F, + trt_commit_id(@ts3) = trt_commit_id(null, @tx2) as G, + trt_commit_id(@ts3, true) is null as H; + +select + trt_trx_sees(@tx1, @tx0) as A, + not trt_trx_sees(@tx0, @tx1) as B, + trt_trx_sees_eq(@tx1, @tx1) as C, + not trt_trx_sees(@tx1, @tx1) as D, + trt_trx_sees(@tx2, 0) as E, + trt_trx_sees(-1, @tx2) as F; + +select trt_trx_sees(0, @tx2); + +# TRT_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; + +--disable_prepare_warnings + +drop table t1; +call verify_trt; + +-- 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 00000000..46ed8fad --- /dev/null +++ b/mysql-test/suite/versioning/t/create.test @@ -0,0 +1,498 @@ +--source suite/versioning/engines.inc +--source suite/versioning/common.inc + +--enable_prepare_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,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 +show create table t1; + +--replace_result $default_engine DEFAULT_ENGINE +--error ER_VERS_PERIOD_COLUMNS +eval create or replace table t1 ( + x3 int unsigned, + Sys_start timestamp(6) as row start invisible, + Sys_end timestamp(6) as row end invisible, + period for system_time (x, Sys_end) +) with system versioning; + +--replace_result $default_engine DEFAULT_ENGINE +--error ER_VERS_PERIOD_COLUMNS +eval create or replace table t1 ( + x4 int unsigned, + Sys_start timestamp(6) as row start invisible, + Sys_end2 timestamp(6) as row end invisible, + period for system_time (Sys_start, Sys_end) +) with system versioning; + +--replace_result $default_engine DEFAULT_ENGINE +--error ER_VERS_PERIOD_COLUMNS +eval create or replace table t1 ( + x5 int unsigned, + Sys_start timestamp(6) as row start invisible, + Sys_end timestamp(6) 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 +--error ER_MISSING +eval create or replace table t1 ( + x7 int unsigned, + Sys_start timestamp(6) as row start invisible, + Sys_end timestamp(6) as row end invisible, + period for system_time (Sys_start, Sys_end) +); + +--replace_result $default_engine DEFAULT_ENGINE +--error ER_VERS_PERIOD_COLUMNS +eval create or replace table t1 ( + x8 int unsigned, + Sys_start timestamp(6) as row start invisible, + Sys_end timestamp(6) as row end invisible, + period for system_time (sys_insert, sys_remove) +) with system versioning; + +--replace_result $default_engine DEFAULT_ENGINE +--error ER_MISSING +eval create or replace table t1 ( + x9 int unsigned, + Sys_start timestamp(6) as row start invisible, + Sys_end timestamp(6) as row end invisible, + period for system_time (Sys_start, Sys_end) +); + +--replace_result $default_engine DEFAULT_ENGINE +--error ER_MISSING +eval create or replace table t1 ( + x10 int unsigned, + Sys_start timestamp(6) as row start invisible, + Sys_end timestamp(6) 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 +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 +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 +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 +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 +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 +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 +show create table tt1; + +--echo # CREATE TABLE ... SELECT +create or replace table t1 (x23 int) with system versioning; +--replace_result $default_engine DEFAULT_ENGINE +eval create or replace table t0( + y int, + st timestamp(6) as row start, + en timestamp(6) 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 +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 +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 +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 +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 +eval create or replace table t3 ( + st timestamp(6) as row start invisible, + en timestamp(6) as row end invisible, + period for system_time (st, en) +) with system versioning as select * from t0; +--replace_result $default_engine DEFAULT_ENGINE +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 +show create table t3; +select * from t3; +--error ER_DUP_FIELDNAME +create or replace table t3 with system versioning select x23, row_start from t1; +--error ER_DUP_FIELDNAME +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 +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 +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 +show create table t2; + +create or replace table t2 with system versioning +as select x25, row_start rs, row_end re from t1; +--replace_result $default_engine DEFAULT_ENGINE +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; +create or replace table t2 with system versioning engine myisam +as select * from t1; +show create table t2; + +--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 rs, t1.row_end re from t2 inner join t1 on t2.id=t1.id; +--replace_result $default_engine DEFAULT_ENGINE +show create table t3; + +--echo ## Errors + +--error ER_VERS_NOT_SUPPORTED +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 +eval create or replace table t2 ( + y int, + st timestamp(6) as row start invisible, + en timestamp(6) 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 +show create table t3; + +--replace_result $default_engine DEFAULT_ENGINE +eval create or replace table t3 ( + y int, + st timestamp(6) as row start invisible, + en timestamp(6) 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 +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. + +--echo # MDEV-15413 Unexpected errors upon CREATE TABLE .. WITH SYSTEM VERSIONING AS SELECT ... +create or replace table t1 with system versioning as select 1 as i; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +create or replace table t1 (i int) with system versioning as select 1 as i; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +--error ER_VERS_FIELD_WRONG_TYPE +create or replace table t1 ( + a int, + row_start bigint as row start, + row_end bigint as row end, + period for system_time (row_start, row_end) +) engine=innodb with system versioning; + +--error ER_VERS_FIELD_WRONG_TYPE +create or replace table t1 ( + a int, + row_start bigint as row start, + row_end bigint as row end, + period for system_time (row_start, row_end) +) engine=myisam with system versioning; + +--error ER_VERS_FIELD_WRONG_TYPE +create table t ( + a int, + row_start datetime(6) generated always as row start, + row_end datetime(6) generated always as row end, + period for system_time(row_start, row_end) +) with system versioning; + +--source suite/versioning/common_finish.inc +--echo # MDEV-16490 It's possible to make a system versioned table without any versioning field +create or replace table t1 (x int without system versioning) +with system versioning +select 1 as y; +--error ER_VERS_TABLE_MUST_HAVE_COLUMNS +create or replace table t1 (x int without system versioning) +with system versioning +select 1 as x; + +drop tables t0, t1, t2, t3; + +--echo # +--echo # MDEV-23968 CREATE TEMPORARY TABLE .. LIKE (system versioned table) returns error if unique index is defined in the table +--echo # +--error ER_KEY_COLUMN_DOES_NOT_EXIST +create table t1 (id int primary key, index(row_start)) with system versioning; +--error ER_KEY_COLUMN_DOES_NOT_EXIST +create table t1 (id int primary key, index(row_end)) with system versioning; +--error ER_KEY_COLUMN_DOES_NOT_EXIST +create table t1 (id int, primary key(id, row_end, row_end)) with system versioning; +create table t1 (id int primary key) with system versioning; +create temporary table t2 like t1; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +--replace_result $default_engine DEFAULT_ENGINE +show create table t2; +drop temporary table t2; +create or replace table t1 ( + a int, + row_start timestamp(6) as row start, + row_end timestamp(6) as row end, + period for system_time (row_start, row_end), + index(row_start), + index(row_end), + primary key(row_end, a, row_start), + index(row_end, row_start, a)) with system versioning; +create temporary table t2 like t1; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +--replace_result $default_engine DEFAULT_ENGINE +show create table t2; +drop temporary table t2; +drop table t1; +--disable_prepare_warnings + +--echo # +--echo # MDEV-16857 system-invisible row_end is displayed in SHOW INDEX +--echo # +create or replace table t1 (id int primary key, x int) with system versioning; +select table_schema, table_name, non_unique, index_schema, index_name, seq_in_index, column_name +from information_schema.statistics where table_name = 't1'; +--replace_column 6 # 7 # 8 # 9 # 10 # 11 # +show index from t1; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +drop table t1; + +--echo # +--echo # MDEV-26928 Column-inclusive WITH SYSTEM VERSIONING doesn't work with explicit system fields +--echo # +create or replace table t1 (x int, y int with system versioning); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +create or replace table t1 ( + x int, y int with system versioning, + row_start timestamp(6) as row start, + row_end timestamp(6) as row end, + period for system_time(row_start, row_end)); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +drop table t1; + +--echo # +--echo # MDEV-27452 TIMESTAMP(0) system field is allowed for certain creation of system-versioned table +--echo # +--error ER_VERS_FIELD_WRONG_TYPE +create or replace table t ( + a int, + s timestamp as row start, + e timestamp as row end, + period for system_time (s, e)) +with system versioning; + +--error ER_VERS_FIELD_WRONG_TYPE +create or replace table t ( + a int with system versioning, + s timestamp as row start, + e timestamp as row end, + period for system_time (s, e)); + +create or replace table t ( + a int with system versioning, + b int with system versioning, + s timestamp(6) as row start, + e timestamp(6) as row end, + period for system_time (s, e)); +insert into t () values (),(); + +# cleanup +drop table t; diff --git a/mysql-test/suite/versioning/t/cte.test b/mysql-test/suite/versioning/t/cte.test new file mode 100644 index 00000000..025e1b23 --- /dev/null +++ b/mysql-test/suite/versioning/t/cte.test @@ -0,0 +1,237 @@ +if (`SELECT $PS_PROTOCOL != 0`) +{ + --skip Test temporarily disabled for ps-protocol +} +--source include/have_innodb.inc +--source include/default_optimizer_switch.inc + +SET @saved_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = OFF; + +set time_zone="+00:00"; +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 row_start into @ts_1 from emp where name="jane"; + +update emp set mgr=30 where name ="john"; + +explain extended +with ancestors as ( + select e.emp_id, e.name, e.mgr, e.salary from emp as e where name = 'bill' + union + select e.emp_id, e.name, e.mgr, e.salary from emp as e +) select * from ancestors for system_time as of @ts_1; + +select row_start into @ts_2 from emp where name="john"; + +let $q= +/* 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; + +eval explain extended $q; +eval $q; + +let $q=with recursive +ancestors +as +( + select e.emp_id, e.name, e.mgr, e.salary + from emp as e + where name = 'bill' + union + select e.emp_id, e.name, e.mgr, e.salary + from emp as e, + ancestors as a + where e.mgr = a.emp_id +) +select * from ancestors for system_time as of timestamp @ts_1; + +eval explain extended $q; +eval $q; + +let $q=with recursive +ancestors +as +( + select e.emp_id, e.name, e.mgr, e.salary + from emp as e + where name = 'bill' + union + select e.emp_id, e.name, e.mgr, e.salary + from emp as e, + ancestors as a + where e.mgr = a.emp_id +) +select name from emp where emp_id in (select emp_id from ancestors for system_time as of timestamp @ts_1); + +eval explain extended $q; +eval $q; + +with recursive +ancestors +as +( + select e.emp_id, e.name, e.mgr, e.salary + from emp as e + where name = 'bill' + union + select e.emp_id, e.name, e.mgr, e.salary + from emp as e, + ancestors as a + where e.mgr = a.emp_id +) +select * from ancestors for system_time as of @ts_2, + ancestors for system_time as of @ts_2 a2; + +--error ER_CONFLICTING_FOR_SYSTEM_TIME +with recursive +ancestors +as +( + select e.emp_id, e.name, e.mgr, e.salary + from emp as e + where name = 'bill' + union + select e.emp_id, e.name, e.mgr, e.salary + from emp as e, + ancestors as a + where e.mgr = a.emp_id +) +select * from ancestors for system_time as of @ts_2, + ancestors for system_time as of now() a2; + +--error ER_CONFLICTING_FOR_SYSTEM_TIME +with recursive +ancestors +as +( + select e.emp_id, e.name, e.mgr, e.salary + from emp as e + where name = 'bill' + union + select e.emp_id, e.name, e.mgr, e.salary + from emp as e, + ancestors as a + where e.mgr = a.emp_id +) +select * from ancestors, + ancestors for system_time as of @ts_2 a2; + +--error ER_CONFLICTING_FOR_SYSTEM_TIME +with recursive +ancestors +as +( + select e.emp_id, e.name, e.mgr, e.salary + from emp as e + where name = 'bill' + union + select e.emp_id, e.name, e.mgr, e.salary + from emp as e, + ancestors as a + where e.mgr = a.emp_id +) +select * from ancestors for system_time as of @ts_2, + ancestors a2; + +--error ER_CONFLICTING_FOR_SYSTEM_TIME +with recursive +ancestors +as +( + select e.emp_id, e.name, e.mgr, e.salary + from emp as e + where name = 'bill' + union + select e.emp_id, e.name, e.mgr, e.salary + from emp as e, + ancestors as a + where e.mgr = a.emp_id +) +select * from ancestors for system_time as of @ts_2 + where emp_id in (select * from ancestors); + +--echo # SYSTEM_TIME to internal recursive instance is prohibited +--error ER_VERS_NOT_VERSIONED +with recursive cte as +( + select * from emp + union all + select * from cte for system_time as of @ts_1 +) +select * from cte; + +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; + +SET GLOBAL innodb_stats_persistent = @saved_stats_persistent; diff --git a/mysql-test/suite/versioning/t/data.test b/mysql-test/suite/versioning/t/data.test new file mode 100644 index 00000000..fb996258 --- /dev/null +++ b/mysql-test/suite/versioning/t/data.test @@ -0,0 +1,169 @@ +--source include/not_embedded.inc +--source suite/versioning/common.inc + +--echo # +--echo # MDEV-16355 Add option for mysqldump to read data as of specific timestamp from system-versioned tables +--echo # +create or replace table t1 (x int) with system versioning; +set timestamp=unix_timestamp('1990-01-01 00:00'); +insert t1 (x) values (1),(2),(3); +set timestamp=unix_timestamp('1990-08-03 00:00'); +delete from t1 where x=1; +set timestamp=unix_timestamp('1991-01-02 00:00'); +delete from t1 where x=2; +set timestamp=default; + +--echo #MYSQL_DUMP --compact test +--exec $MYSQL_DUMP --compact test +--echo #MYSQL_DUMP --compact --as-of="1990-01-02 00:00" test +--exec $MYSQL_DUMP --compact --as-of="1990-01-02 00:00" test +--echo #MYSQL_DUMP --compact --as-of="1990-08-02 00:00" --databases test +--exec $MYSQL_DUMP --compact --as-of="1990-08-02 00:00" --databases test +--echo #MYSQL_DUMP --compact --as-of="1990-08-04 00:00" test t1 +--exec $MYSQL_DUMP --compact --as-of="1990-08-04 00:00" test t1 +## Forged query protection +--echo #MYSQL_DUMP --compact --as-of="1990-08-04 00:00' where 'abc" test 2>&1 +--replace_result mariadb-dump.exe mariadb-dump +--error 1 +--exec $MYSQL_DUMP --compact --as-of="1990-08-04 00:00' where 'abc" test 2>&1 + +drop tables t1; + +--echo # +--echo # MDEV-16029 mysqldump: dump and restore historical data +--echo # +create or replace table t1 (x int) with system versioning; +set timestamp=unix_timestamp('2010-10-10 10:10:10.101010'); +insert into t1 values (1), (2); +set timestamp=unix_timestamp('2011-11-11 11:11:11.111111'); +delete from t1 where x = 1; +set timestamp=default; +select row_start, row_end into @s1, @e1 from t1 for system_time all where x = 1; +select row_start, row_end into @s2, @e2 from t1 for system_time all where x = 2; + +create or replace table t2 ( + x 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; + +eval +create or replace function check_fields(x int, row_start timestamp(6), row_end timestamp(6)) + returns char(50) deterministic + return if (x = 1, + if (row_start = @s1 and row_end = @e1, '[CORRECT]', '[WRONG]'), + if (x = 2 and row_start = @s2 and row_end = @e2, '[CORRECT]', '[WRONG]')); + +set @@system_versioning_insert_history= 1; +insert into t2 (x, row_start, row_end) select x, row_start, row_end from t1 for system_time all; +set @@system_versioning_insert_history= 0; +--echo # t2 has the same data as t1 +select x, check_fields(x, row_start, row_end) from t2 for system_time all order by x; + +--let TMP= $MYSQLTEST_VARDIR/tmp + +--exec $MYSQL_DUMP --dump-history --databases test > $TMP/dump_history.sql +--exec $MYSQL_DUMP --databases test > $TMP/dump_no_history.sql +--exec $MYSQL_DUMP --dump-history --no-create-info --skip-comments --databases test > $TMP/dump_only_data.sql +--exec $MYSQL_DUMP --dump-history --compact test 2>&1 > $TMP/dump_history_compact.sql +--cat_file $TMP/dump_history_compact.sql +--replace_result mariadb-dump.exe mariadb-dump +--error 1 +--exec $MYSQL_DUMP --dump-history --as-of="1990-01-02 00:00" test 2>&1 +--replace_result mariadb-dump.exe mariadb-dump +--error 1 +--exec $MYSQL_DUMP --dump-history --replace test 2>&1 +--replace_result mariadb-dump.exe mariadb-dump +--error 1 +--exec $MYSQL_DUMP --dump-history --xml test 2>&1 + +--exec $MYSQL_DUMP --dump-history --tab=$TMP test + +--echo # SQL dump with/without history +--echo ## With history +drop tables t1, t2; +--exec $MYSQL test < $TMP/dump_history.sql +select x, check_fields(x, row_start, row_end) from t1 for system_time all order by x; +select x, check_fields(x, row_start, row_end) from t2 for system_time all order by x; +--echo ## Without history +drop tables t1, t2; +--exec $MYSQL test < $TMP/dump_no_history.sql +select x, check_row_ts(row_start, row_end) from t1 for system_time all order by x; +select x, check_row_ts(row_start, row_end) from t2 for system_time all order by x; + +--echo ## History and --no-create-info --skip-comments +create or replace table t1 (x int) with system versioning; +delete from t2; delete history from t2; +--exec $MYSQL test < $TMP/dump_only_data.sql +select x, check_fields(x, row_start, row_end) from t1 for system_time all order by x; +select x, check_fields(x, row_start, row_end) from t2 for system_time all order by x; + +--echo ## compact +--exec $MYSQL test < $TMP/dump_history.sql +select x, check_fields(x, row_start, row_end) from t1 for system_time all order by x; +select x, check_fields(x, row_start, row_end) from t2 for system_time all order by x; + +create or replace table t1 (x int) with system versioning; + +# TODO: MDEV-16766 mysqldump: dump history in XML +if (0) +{ +--echo # XML with history +drop table t1; +create or replace table t1 (x int) with system versioning; +delete from t2; +delete history from t2; +set @@system_versioning_insert_history= 1; +--replace_result $TMP TMP +eval load xml infile '$TMP/dump_history.xml' into table t1; +--exec cp $TMP/dump_history.xml /tmp +set @@system_versioning_insert_history= 0; +--echo ## History is now loaded as current data (TODO) +select *, check_row_ts(row_start, row_end) from t1 for system_time all; +# TODO: check mysqlimport +# --exec $MYSQL_IMPORT test $TMP/dump_history.xml +} + +--echo # --tab with history +drop tables t1, t2; +--exec $MYSQL test < $TMP/t1.sql +--exec $MYSQL test < $TMP/t2.sql +show create table t1; +show create table t2; +set @@system_versioning_insert_history= 1; +--replace_result $TMP tmp +eval load data infile '$TMP/t1.txt' into table t1 (x, row_start, row_end); +--replace_result $TMP tmp +eval load data infile '$TMP/t2.txt' into table t2 (x, row_start, row_end); +set @@system_versioning_insert_history= 0; +select *, check_row_ts(row_start, row_end) from t1 for system_time all; +select *, check_row_ts(row_start, row_end) from t2 for system_time all; + +# Cleanup +--remove_files_wildcard $TMP *.sql +--remove_files_wildcard $TMP *.txt +--remove_files_wildcard $TMP *.xml +drop tables t1, t2; +drop function check_fields; + +--echo # +--echo # MDEV-29730 mysqldump --dump-history creates broken dump if there are precision-versioned tables +--echo # +create table t1 (x int, + rs BIGINT unsigned as row start, re BiGiNt unsigned as row end, + period for system_time (rs,re)) with system versioning engine=innodb; +insert t1 (x) values (1); +insert t1 (x) values (2); +delete from t1 where x=1; + +--replace_result mariadb-dump.exe mariadb-dump +--error 6 +--exec $MYSQL_DUMP --dump-history test 2>&1 >/dev/null +--replace_regex /2,\d+,/2,XXX,/ /mariadb-dump\.exe/mariadb-dump/ +--error 6 +--exec $MYSQL_DUMP --force --dump-history --compact test 2>&1 + +drop table t1; + +--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 00000000..94917f01 --- /dev/null +++ b/mysql-test/suite/versioning/t/debug.test @@ -0,0 +1,108 @@ +--source include/have_debug.inc +--source include/have_partition.inc + +--let $datadir=`select @@datadir` + +create table t1 (a int); +show create table t1; + +--error ER_VERS_NOT_SUPPORTED +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; +drop table t1, t2, t3, t4; +set debug_dbug= @old_dbug; +set global debug_dbug= @old_dbug; + +--echo # +--echo # MDEV-19525 remove ER_VERS_FIELD_WRONG_TYPE from init_from_binary_frm_image() +--echo # +create table t1 (x int) with system versioning; +set debug_dbug='+d,error_vers_wrong_type'; +--replace_result $datadir ./ +--error ER_NOT_FORM_FILE +show create table t1; +--replace_result $datadir ./ +show warnings; +drop table t1; +set debug_dbug= @old_dbug; + + +--echo # +--echo # MDEV-17554 Auto-create new partition for system versioned tables +--echo # with history partitioned by INTERVAL/LIMIT +--echo # +call mtr.add_suppression("need more HISTORY partitions"); +create or replace table t1 (x int) with system versioning +partition by system_time limit 1 auto partitions 2; +insert into t1 values (1); +update t1 set x= x + 1; + +--connect con2, localhost, root +--connect con1, localhost, root + +--disable_warnings +--echo # Both threads create partition simultaneously +--connection con1 +set debug_sync= 'add_history_partition signal s1 wait_for s2'; +send update t1 set x= x + 10; +--connection con2 +set debug_sync= 'now wait_for s1'; +flush tables t1; +set debug_sync= 'add_history_partition signal s2'; +update t1 set x= x + 20; +--connection con1 +reap; +--connection default +# 1 or 2 history rows may be created depending on which UPDATE finishes first (MDEV-28459) +# select partition_name, table_rows from information_schema.partitions +# where table_name = 't1'; + +# Fill empty partition for next UPDATE to trigger auto-create +update t1 set x= x + 2; + +--echo # Second thread skips to reopen 3 times until first thread creates partition +--connection con1 +set debug_sync= 'add_history_partition SIGNAL s1 WAIT_FOR s2'; +send update t1 set x= x + 30; +--connection con2 +set debug_sync= 'now WAIT_FOR s1'; +set debug_sync= 'reopen_history_partition SIGNAL s2 EXECUTE 3'; +update t1 set x= x + 40; +--connection con1 +reap; +--connection default +# Same here (MDEV-28459) +# select partition_name, table_rows from information_schema.partitions +# where table_name = 't1'; +--enable_warnings + +--disconnect con1 +--disconnect con2 +set @@timestamp= default; + +drop tables t1; +set debug_sync= 'reset'; diff --git a/mysql-test/suite/versioning/t/delete.test b/mysql-test/suite/versioning/t/delete.test new file mode 100644 index 00000000..9debdcfe --- /dev/null +++ b/mysql-test/suite/versioning/t/delete.test @@ -0,0 +1,122 @@ +source suite/versioning/engines.inc; +source suite/versioning/common.inc; + +--echo # Basic + delete from view +replace_result $sys_datatype_expl SYS_DATATYPE; +eval create or replace table t1( + XNo int unsigned, + 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; + +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); +replace_result $sys_datatype_max MAXVAL; +eval select XNo, sys_end < $sys_datatype_max from t1 for system_time all; +delete from t1 where XNo = 0; +delete from t1 where XNo = 1; +delete from t1 where XNo > 5; +create view vt1 as select XNo from t1; +select XNo as XNo_vt1 from vt1; +delete from vt1 where XNo = 3; +select XNo as XNo_vt1 from vt1; +drop view vt1; +drop table t1; + +--echo # Check sys_start, sys_end +replace_result $sys_datatype_expl SYS_DATATYPE; +eval create or replace table t1( + x 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)) + with system versioning; + +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 all; +drop table t1; + +--echo # Multi-delete +replace_result $sys_datatype_expl SYS_DATATYPE; +eval create or replace table t1( + x int, + y 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)) + with system versioning; +create or replace table t2 like t1; +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 all; +select x as t2_x_all from t2 for system_time all; +drop table t1; +drop table t2; + +--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 table t1; + +--echo # +--echo # MDEV-18929 2nd execution of SP does not detect ER_VERS_NOT_VERSIONED +--echo # +create or replace table t1 (a int) with system versioning; +replace into t1 values (1), (2); +create or replace trigger tr before delete on t1 for each row delete from xx; +create or replace procedure pr() delete from t1; +--error ER_NO_SUCH_TABLE +call pr; +--error ER_NO_SUCH_TABLE +call pr; +drop procedure pr; +drop trigger tr; +drop table t1; + +--echo # +--echo # MDEV-21138 Assertion `col->ord_part' or `f.col->ord_part' failed in row_build_index_entry_low +--echo # +--echo # Check DELETE and multi-DELETE with foreign key +replace_result $sys_datatype_expl SYS_TYPE; +eval create table t1 ( + f1 int, f2 text, f3 int, fulltext (f2), key(f1), key(f3), + foreign key r (f3) references t1 (f1) on delete set null, + row_start $sys_datatype_expl as row start invisible, + row_end $sys_datatype_expl as row end invisible, + period for system_time (row_start, row_end)) +with system versioning engine innodb; +insert into t1 values (1, repeat('a', 8193), 1), (1, repeat('b', 8193), 1); +insert into t1 select 2, f2, 2 from t1; +select f1, f3, check_row(row_start, row_end) from t1; +delete from t1 where f1 = 1; +select f1, f3, check_row(row_start, row_end) from t1 for system_time all order by f1, row_end; +create table t2 (f1 int); +insert into t2 values (2); +--echo # Multi-delelte +delete t1, t2 from t1 join t2 where t1.f1 = t2.f1; +select f1, f3, check_row(row_start, row_end) from t1 for system_time all order by f1, row_end; +--echo # Cleanup +drop tables t1, t2; + +--source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/t/delete_history.test b/mysql-test/suite/versioning/t/delete_history.test new file mode 100644 index 00000000..f82fe9bd --- /dev/null +++ b/mysql-test/suite/versioning/t/delete_history.test @@ -0,0 +1,246 @@ +--source suite/versioning/common.inc +--source include/have_partition.inc +--source suite/versioning/engines.inc + +call mtr.add_suppression("need more HISTORY partitions"); + +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. +--replace_result $sys_datatype_expl SYS_TYPE +eval create or replace table t ( + a int, + row_start $sys_datatype_expl as row start invisible, + row_end $sys_datatype_expl as row end invisible, + period for system_time (row_start, row_end)) +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; + +--replace_result $sys_datatype_expl SYS_TYPE +eval create or replace table t ( + a int, + row_start $sys_datatype_expl as row start invisible, + row_end $sys_datatype_expl as row end invisible, + period for system_time (row_start, row_end)) +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 # Truncate partitioned +create or replace table t (a int) with system versioning +partition by system_time limit 1 partitions 3; +insert into t values (1); +update t set a= 2; +update t set a= 3; +--echo # You see warning above ^ +delete history from t; +select * from t for system_time all; + +--echo # VIEW +--replace_result $sys_datatype_expl SYS_TYPE +eval create or replace table t ( + i int, + row_start $sys_datatype_expl as row start invisible, + row_end $sys_datatype_expl as row end invisible, + period for system_time (row_start, row_end)) +with system versioning; +delete history from t; +create or replace view v as select * from t; +--error ER_IT_IS_A_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_IT_IS_A_VIEW +delete history from v; +--error ER_VERS_NOT_VERSIONED +prepare stmt from 'delete history from t'; + +drop table t; +drop view v; + +# +# MDEV-15402 Assertion `table' failed in mysql_delete on attempt to delete history from view +# +create or replace table t (i int); +create or replace view v as select * from t; +--error ER_IT_IS_A_VIEW +drop table v; +lock table v write; +--error ER_IT_IS_A_VIEW +delete history from v before system_time now(6); +unlock tables; +drop view v; +drop table t; + +# +# MDEV-16783 Assertion `!conds' failed in mysql_delete upon 2nd execution of SP with DELETE HISTORY +# +create table t1 (i int) with system versioning; +create procedure pr() delete history from t1 before system_time now(); +call pr; +call pr; +drop procedure pr; +drop table t1; + +--echo # MDEV-15966 Behavior for TRUNCATE versioned table is not documented and not covered by tests +create or replace table t1 (id int); +create or replace table t2 (id int) with system versioning; + +-- echo # force cleaning table shares +flush tables t1, t2; + +truncate table t1; +--error ER_VERS_NOT_SUPPORTED +truncate table t2; + +-- echo # fetch table shares +describe t1; +describe t2; + +truncate table t1; +--error ER_VERS_NOT_SUPPORTED +truncate table t2; + +--echo # enter locked tables mode +lock tables t1 WRITE, t2 WRITE; + +truncate t1; +--error ER_VERS_NOT_SUPPORTED +truncate t2; + +unlock tables; +drop table t2; + +--echo # +--echo # MDEV-19814 Assertion `update->n_fields < ulint(table->n_cols + table->n_v_cols)' on DELETE HISTORY +--echo # +--replace_result $sys_datatype_expl SYS_TYPE +eval create or replace table t1 ( + f varchar(1), + row_start $sys_datatype_expl as row start, + row_end $sys_datatype_expl as row end, + period for system_time (row_start, row_end)) +with system versioning; +insert into t1 (f) values ('a'), ('b'), ('c'), ('d'), ('e'), ('f'), ('g'), ('h'); +delete from t1; +delete history from t1; +drop table t1; + +--echo # +--echo # MDEV-20186 Wrong result or Assertion on INSERT after DELETE HISTORY +--echo # +create or replace table t1 (a int check (a > 0)) with system versioning; +delete history from t1; +insert into t1 values (1); +select * from t1; +drop table t1; + +--echo # +--echo # MDEV-25468 DELETE HISTORY may delete current data on system-versioned table +--echo # +create or replace table t1 (x int) with system versioning; +insert into t1 values (1); +delete history from t1 before system_time '2039-01-01 23:00'; +select * from t1; +explain extended delete history from t1 before system_time '2039-01-01 23:00'; +create or replace procedure p() delete history from t1 before system_time '2039-01-01 23:00'; +call p; +select * from t1; +call p; +select * from t1; +drop procedure p; +prepare stmt from "delete history from t1 before system_time '2039-01-01 23:00'"; +execute stmt; +select * from t1; +execute stmt; +select * from t1; +drop prepare stmt; +drop table t1; + +--echo # +--echo # MDEV-25004 Missing row in FTS_DOC_ID_INDEX during DELETE HISTORY +--echo # +create table t1 (a integer, c0 varchar(255), fulltext key (c0)) +with system versioning engine innodb; +set system_versioning_alter_history= keep; +alter table t1 drop system versioning; +alter table t1 add system versioning; +insert into t1 values (1, 'politician'); +update t1 set c0= 'criminal'; +--source suite/innodb/include/wait_all_purged.inc +delete history from t1; +drop table t1; + +create table t1 (id int primary key, ftx varchar(255)) +with system versioning engine innodb; +insert into t1 values (1, 'c'); +delete from t1; +alter table t1 add fulltext key(ftx); +drop table t1; + +--echo # +--echo # MDEV-28201 Server crashes upon SHOW ANALYZE/EXPLAIN FORMAT=JSON +--echo # +CREATE TABLE t1 (a INT) WITH SYSTEM VERSIONING; +CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1; +SET optimizer_trace= 'enabled=on'; +--error ER_NON_UPDATABLE_TABLE +DELETE HISTORY FROM v1 BEFORE SYSTEM_TIME '2021-01-01'; +--error ER_NON_UPDATABLE_TABLE +DELETE HISTORY FROM v1; +DROP VIEW v1; +DROP TABLE t1; + +--echo # End of 10.4 tests + +--echo # +--echo # MDEV-17554 Auto-create new partition for system versioned tables with history partitioned by INTERVAL/LIMIT +--echo # +--echo # Don't auto-create new partition on DELETE HISTORY: +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create or replace table t (a int) with system versioning +partition by system_time interval 1 hour auto; +set timestamp= unix_timestamp('2000-01-01 10:00:00'); +delete history from t; +set timestamp= default; +--replace_result $default_engine DEFAULT_ENGINE +show create table t; +drop table t; + +--echo # End of 10.9 tests + +--source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/t/derived.test b/mysql-test/suite/versioning/t/derived.test new file mode 100644 index 00000000..9d96856f --- /dev/null +++ b/mysql-test/suite/versioning/t/derived.test @@ -0,0 +1,238 @@ +--source include/default_optimizer_switch.inc + +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/foreign.combinations b/mysql-test/suite/versioning/t/foreign.combinations new file mode 100644 index 00000000..1a0812cf --- /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 00000000..5f228747 --- /dev/null +++ b/mysql-test/suite/versioning/t/foreign.test @@ -0,0 +1,629 @@ +--source suite/versioning/key_type.inc +--source suite/versioning/common.inc + +--echo ################# +--echo # Test RESTRICT # +--echo ################# + +--replace_result "$KEY_TYPE" KEY_TYPE +eval create table parent( + id int, + $KEY_TYPE (id) +) 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 all; + +drop table child; +drop table parent; + +--echo ############################################## +--echo # Test when clustered index is a foreign key # +--echo ############################################## + +--replace_result "$KEY_TYPE" KEY_TYPE +eval create table parent( + id int(10) unsigned, + $KEY_TYPE (id) +) 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 ################ + +--replace_result "$KEY_TYPE" KEY_TYPE +eval create table parent( + id int, + $KEY_TYPE (id) +) 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); + +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 "$KEY_TYPE" KEY_TYPE +eval create or replace table parent ( + id int, + $KEY_TYPE(id), + 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; + +--replace_result "$KEY_TYPE" KEY_TYPE +eval create or replace table parent ( + id int, + $KEY_TYPE(id) +) +engine innodb; + +--replace_result $sys_datatype_expl SYS_DATATYPE +eval create or replace table child ( + id int primary key, + parent_id int not null, + row_start $sys_datatype_expl as row start invisible, + row_end $sys_datatype_expl as row end invisible, + period for system_time(row_start, row_end), + 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); +delete from parent; +select * from child; +select *, check_row(row_start, row_end) from child for system_time all; + +drop table child; +drop table parent; + +--echo ################# +--echo # Test SET NULL # +--echo ################# + +--replace_result "$KEY_TYPE" KEY_TYPE +eval create table parent( + id int, + $KEY_TYPE (id) +) engine innodb; + +--replace_result $sys_datatype_expl SYS_DATATYPE +eval create or replace 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); + +delete from parent where id = 1; +select * from child; +select *, current_row(sys_end) as current_row from child for system_time all order by sys_end; +delete from child; + +insert into parent values(1); +insert into child values(1); +update parent set id= id + 1; +select * from child; +select *, current_row(sys_end) as current_row from child for system_time all order by sys_end; + +drop table child; +drop table parent; + +--echo ########################### +--echo # Parent table is foreign # +--echo ########################### + +--replace_result $sys_datatype_expl SYS_DATATYPE "$KEY_TYPE" KEY_TYPE +eval create or replace table parent( + id int, + $KEY_TYPE (id), + 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 "$KEY_TYPE" KEY_TYPE +eval create or replace table a ( + cola int(10), + $KEY_TYPE (cola), + 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; + +--echo ############################################### +--echo # CASCADE UPDATE foreign not system versioned # +--echo ############################################### +create or replace table parent ( + id smallint unsigned not null auto_increment, + value int unsigned not null, + primary key (id, value) +) engine = innodb; + +--replace_result $sys_datatype_expl SYS_DATATYPE +eval create or replace table child ( + id mediumint unsigned not null auto_increment primary key, + parent_id smallint unsigned not null, + parent_value int unsigned not null, + 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), + constraint `fk_child_parent` + foreign key (parent_id, parent_value) references parent (id, value) + on delete cascade + on update cascade +) engine = innodb with system versioning; + +create or replace table subchild ( + id int not null auto_increment primary key, + parent_id smallint unsigned not null, + parent_value int unsigned not null, + constraint `fk_subchild_child_parent` + foreign key (parent_id, parent_value) references child (parent_id, parent_value) + on delete cascade + on update cascade +) engine=innodb; + +insert into parent (value) values (23); +--enable_prepare_warnings +select id, value from parent into @id, @value; +--disable_prepare_warnings +insert into child values (default, @id, @value); +insert into subchild values (default, @id, @value); + +select parent_id from subchild; +update parent set id = 11, value = value + 1; +select parent_id from subchild; +select * from child; + +delete from parent; +select count(*) from child; +select * from child for system_time all; +select count(*) from subchild; + +drop table subchild, child, parent; + +--echo # +--echo # MDEV-18057 Assertion `(node->state == 5) || (node->state == 6)' failed in row_upd_sec_step upon DELETE after UPDATE failed due to FK violation +--echo # +create or replace table t1 (f1 int, key(f1)) engine=innodb; +create or replace table t2 (f2 int, foreign key (f2) references t1 (f1)) engine=innodb with system versioning; + +set foreign_key_checks= off; +insert ignore into t2 values (1); + +set foreign_key_checks= on; +--error ER_NO_REFERENCED_ROW_2 +update t2 set f2= 2; +delete from t2; + +drop table t2, t1; + +--echo # +--echo # MDEV-18879 Corrupted record inserted by FOREIGN KEY operation +--echo # +SET timestamp = 1; +SET time_zone='+02:00'; +SELECT now(); +CREATE TABLE t1 ( + pk INT UNSIGNED PRIMARY KEY, + f1 varchar(255) CHARACTER SET ucs2, + f2 longtext CHARACTER SET ucs2, + f3 varchar(255), + f4 char(255), + f5 longtext CHARACTER SET ucs2, + f6 INT UNSIGNED, + f7 INT UNSIGNED, + f8 INT UNSIGNED, + f9 INT UNSIGNED, + f10 INT UNSIGNED, + f11 INT UNSIGNED, + f12 varchar(255) CHARACTER SET ucs2, + f13 char(255) CHARACTER SET ucs2, + f14 char(255) CHARACTER SET ucs2, + f15 varchar(255), + f16 longtext, + f17 char(255) +) ENGINE=InnoDB WITH SYSTEM VERSIONING; + +INSERT INTO t1 VALUES +(1, 'a', 'e', 'f', 'a', 'generate', 1, 2, 3, 4, 5, 6, 'main', 'against', 'b', 'u', 'explode', 'tomorrow'), +(2, REPEAT('a',127), 'f', 'k', 'game', 'g', 2, 3, 4, 5, 6, 7, REPEAT('o',222), 'oven', 'flower', REPEAT('r',120), 'l', 'g'), +(3, 'weekly', 'x', 'v', 'r', 'c', 3, 4, 5, 6, 7, 8, 'validity', 'y', 'h', 'oxygen', 'venture', 'uncertainty'), +(4, 'r', 't', REPEAT('b',153), 'modern', 'h', 4, 5, 6, 7, 8, 9, REPEAT('g',128), 'a', 'w', 'f', 'b', 'b'), +(5, 'h', 'y', REPEAT('v',107), 'knife', 'profession', 5, 6, 7, 8, 9, 0, 'infection', 'u', 'likelihood', REPEAT('n',149), 'folk', 'd'), +(6, 'g', 'violent', REPEAT('o',28), 'capital', 'p', 6, 7, 8, 9, 0, 1, 'w', 'patron', 'd', 'y', 'originally', 'k'), +(7, 'k', 'uncomfortable', REPEAT('v',248), 'y', 'link', 7, 8, 9, 0, 1, 2, REPEAT('j',204), 'j', 'statute', 'emphasis', 'u', 'water'), +(8, 'preparation', 'water', 'suck', 'silver', 'a', 8, 9, 0, 1, 2, 3, 'h', 'q', 'o', 't', 'k', 'y'), +(9, 'y', 'f', 'e', 'a', 'dawn', 9, 0, 1, 2, 3, 4, 'peak', 'parking', 'b', 't', 'timber', 'c'), +(10, REPEAT('h',78), 'apologize', 'direct', 'u', 'frankly', 0, 1, 2, 3, 4, 5, 'h', 'exhibit', 'f', 'd', 'effective', 'c'), +(11, 'i', 'h', 'a', 'y', 'u', 1, 2, 3, 4, 5, 6, 'l', 'b', 'm', 'respond', 'ideological', 'credibility'); + +CREATE TABLE t2 ( + pk int primary key, + f char(255) CHARACTER SET ucs2, + key(f) +) ENGINE=InnoDB; + +INSERT INTO t2 VALUES (1,'against'),(2,'q'); + +SET SQL_MODE= ''; +SET timestamp = 2; +--disable_ps2_protocol +SELECT * INTO OUTFILE 't1.data' FROM t1; +--enable_ps2_protocol +SET timestamp = 3; +UPDATE t1 SET f13 = 'q'; +SET timestamp = 4; +LOAD DATA INFILE 't1.data' REPLACE INTO TABLE t1; +--disable_ps2_protocol +SELECT * INTO OUTFILE 't1.data.2' FROM t1; +--enable_ps2_protocol +SET timestamp = 5; +LOAD DATA INFILE 't1.data.2' REPLACE INTO TABLE t1; +--disable_ps2_protocol +SELECT * INTO OUTFILE 't2.data' FROM t2; +--enable_ps2_protocol +SET timestamp = 6; +LOAD DATA INFILE 't2.data' REPLACE INTO TABLE t2; +SET FOREIGN_KEY_CHECKS = OFF; +ALTER TABLE t1 ADD FOREIGN KEY (f13) REFERENCES t2 (f) ON DELETE SET NULL; +SET timestamp = 7; +LOAD DATA INFILE 't1.data' REPLACE INTO TABLE t1; +SET FOREIGN_KEY_CHECKS = ON; + +SET SESSION SQL_MODE= 'NO_BACKSLASH_ESCAPES'; +SET timestamp = 8; +LOAD DATA INFILE 't1.data' REPLACE INTO TABLE t1; +SET timestamp = 9; +REPLACE INTO t2 SELECT * FROM t2; + +# Cleanup +DROP TABLE t1, t2; +set timestamp= default; +set time_zone='+00:00'; +--let $datadir= `select @@datadir` +--remove_file $datadir/test/t1.data +--remove_file $datadir/test/t1.data.2 +--remove_file $datadir/test/t2.data + +--echo # +--echo # MDEV-16210 FK constraints on versioned tables use historical rows, which may cause constraint violation +--echo # +create or replace table t1 (a int, key(a)) engine innodb with system versioning; +create or replace table t2 (b int, foreign key (b) references t1(a)) engine innodb; +insert into t1 values (1),(2); +insert into t2 values (1); +--echo # DELETE from referenced table is not allowed +--error ER_ROW_IS_REFERENCED_2 +delete from t1 where a = 1; +drop tables t2, t1; + +--echo # +--echo # MDEV-20812 Unexpected ER_ROW_IS_REFERENCED_2 or server crash in row_ins_foreign_report_err upon DELETE from versioned table with FK +--echo # +create or replace table t1 (x int primary key) engine innodb; +create or replace table t2 (x int, foreign key (x) references t1(x)) engine innodb with system versioning; +set foreign_key_checks= off; +insert into t2 values (1), (1); +set foreign_key_checks= on; +--echo # DELETE from foreign table is allowed +delete from t2; +drop tables t2, t1; + +create or replace table t1 (a int, key(a)) engine innodb; +insert into t1 values (1); +create or replace table t2 (b int, foreign key (b) references t1(a)) engine innodb with system versioning; +insert into t2 values (1), (1); +--echo # DELETE from foreign table is allowed +delete from t2; +drop tables t2, t1; + +--echo # +--echo # MDEV-23644 Assertion on evaluating foreign referential action for self-reference in system versioned table +--echo # +create table t1 (pk int primary key, f1 int,f2 int, f3 text, + key(f1), fulltext(f3), key(f3(10)), + foreign key (f2) references t1 (f1) on delete set null +) engine=innodb with system versioning; + +insert into t1 values (1, 8, 8, 'SHORT'), (2, 8, 8, repeat('LONG', 8071)); + +delete from t1; +select pk, f1, f2, left(f3, 4), check_row_ts(row_start, row_end) from t1 for system_time all order by pk; + +# cleanup +drop table t1; + +--echo # Shorter case for clustered index (MDEV-25004) +create table t1 ( + y int primary key, r int, f int, key (r), + foreign key (f) references t1 (r) on delete set null) +with system versioning engine innodb; + +insert into t1 values (1, 6, 6), (2, 6, 6); +delete from t1; +select *, check_row_ts(row_start, row_end) from t1 for system_time all; +drop tables t1; + +--echo # Secondary unique index +create table t1 ( + y int unique null, r int, f int, key (r), + foreign key (f) references t1 (r) on delete set null) +with system versioning engine innodb; + +insert into t1 values (1, 6, 6), (2, 6, 6); +delete from t1; +select *, check_row_ts(row_start, row_end) from t1 for system_time all; +drop tables t1; + +--echo # Non-unique index cannot be fixed because it does not trigger duplicate error +create table t1 ( + y int, r int, f int, key (y), key (r), + foreign key (f) references t1 (r) on delete set null) +with system versioning engine innodb; + +insert into t1 values (1, 6, 6), (2, 6, 6); +delete from t1; +select *, check_row_ts(row_start, row_end) from t1 for system_time all; +drop tables t1; + +--echo # +--echo # MDEV-21555 Assertion secondary index is out of sync on delete from versioned table +--echo # +create table t1 (a int, b int as (a + 1) virtual, key(a)) engine=innodb with system versioning; + +set foreign_key_checks= off; +insert into t1 (a) values (1), (2); +alter table t1 add foreign key (b) references t1 (a), algorithm=copy; +update t1 set a= null where a = 1; +delete from t1 where a is null; +set foreign_key_checks= on; + +delete history from t1; +delete from t1; + +# cleanup +drop table t1; + +--echo # +--echo # MDEV-30378 Versioned REPLACE succeeds with ON DELETE RESTRICT +--echo # constraint +--echo # +create table t0 (pk integer primary key) with system versioning engine=innodb; +create table t1 (pk integer primary key, + foreign key(pk) references t0(pk) + on delete restrict on update cascade) engine=innodb; +create table t2 (pk integer); + +insert into t0 (pk) values (1); +insert into t1 (pk) values (1); +insert into t2 (pk) values (1); + +--error ER_ROW_IS_REFERENCED_2 +delete from t0; + +--error ER_ROW_IS_REFERENCED_2 +replace t0 values (1); + +--disable_ps2_protocol +select * into outfile 'load_t0' from t0 ; +--enable_ps2_protocol +--error ER_ROW_IS_REFERENCED_2 +load data infile 'load_t0' replace into table t0; + +--error ER_ROW_IS_REFERENCED_2 +delete t0, t2 from t0 join t2; + +select pk from t0; + +--echo # Cleanup +drop table t1, t0, t2; +--let $datadir= `select @@datadir` +--remove_file $datadir/test/load_t0 + + +--echo # create_select for a temporary table didn't set up pos_in_locked_tables. +create table t (a int unique) engine=innodb + replace select 1 as a, 2 as b union select 1 as a, 3 as c; +select * from t; +drop table t; + +create temporary table t (a int unique) engine=innodb + replace select 1 as a, 2 as b union select 1 as a, 3 as c; +select * from t; +drop table t; + +--echo # +--echo # MDEV-20729 Fix REFERENCES constraint in column definition +--echo # +create table t1(id int); +--echo # system fields can't be foreign keys: +--replace_result $sys_datatype_expl SYS_DATATYPE +--error ER_PARSE_ERROR,ER_PARSE_ERROR +eval create or replace table t2( + x int, + sys_start $sys_datatype_expl as row start references t1(id), + sys_end $sys_datatype_expl as row end, + period for system_time(sys_start, sys_end) +) engine innodb with system versioning; +--replace_result $sys_datatype_expl SYS_DATATYPE +--error ER_PARSE_ERROR,ER_PARSE_ERROR +eval create or replace table t2( + x int, + sys_start $sys_datatype_expl as row start, + sys_end $sys_datatype_expl as row end references t1(id), + period for system_time(sys_start, sys_end) +) engine innodb with system versioning; +--replace_result $sys_datatype_expl SYS_DATATYPE +--error ER_CANT_CREATE_TABLE +eval create or replace table t2( + x int, + sys_start $sys_datatype_expl as row start, + sys_end $sys_datatype_expl as row end, + period for system_time(sys_start, sys_end), + foreign key (sys_start) references t1(id) +) engine innodb with system versioning; +--replace_result $sys_datatype_expl SYS_DATATYPE +--error ER_CANT_CREATE_TABLE +eval create or replace table t2( + x int, + sys_start $sys_datatype_expl as row start, + sys_end $sys_datatype_expl as row end, + period for system_time(sys_start, sys_end), + foreign key (sys_end) references t1(id) +) engine innodb with system versioning; +drop table t1; + +--echo # End of 10.5 tests + +--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 00000000..f4c54eb6 --- /dev/null +++ b/mysql-test/suite/versioning/t/insert.test @@ -0,0 +1,269 @@ +source suite/versioning/engines.inc; +source suite/versioning/common.inc; + +replace_result $sys_datatype_expl SYS_DATATYPE; +eval create or replace table t1( + x int unsigned, + y int unsigned, + 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; + +insert into t1(x, y) values(3, 4); +insert into t1(x, y) values(2, 3); +insert into t1 values(40, 33); +replace_result $sys_datatype_max MAXVAL; +eval select x, y, sys_end < $sys_datatype_max from t1; + +replace_result $sys_datatype_expl SYS_DATATYPE; +eval create or replace table t1( + id int unsigned auto_increment primary key, + x int unsigned, + y int unsigned, + 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; + +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); +replace_result $sys_datatype_max MAXVAL; +eval select id, x, y, sys_end < $sys_datatype_max from t1; + +replace_result $sys_datatype_expl SYS_DATATYPE; +eval create or replace table t1( + x int unsigned, + y int unsigned, + 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; +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); +replace_result $sys_datatype_max MAXVAL; +eval select x, y, sys_end < $sys_datatype_max from t1; +select x, y from vt1_1; +drop view vt1_1; + +replace_result $sys_datatype_expl SYS_DATATYPE; +eval create or replace table t1( id bigint primary key, a int, b int) with system versioning; +insert into t1 values(1, 1, 1); +--enable_prepare_warnings +select row_start, row_end from t1 into @sys_start, @sys_end; +--disable_prepare_warnings +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; + +replace_result $sys_datatype_expl SYS_DATATYPE; +eval create or replace table t1( + x int unsigned, + y int unsigned, + 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; +create or replace table t2 like t1; +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 all; +select x, y from t1; +select x, y from t2; +drop table t1; +drop table t2; + +--echo # +--echo # MDEV-16546 System versioning setting to allow history modification +--echo # +set @@session.time_zone='+00:00'; +let $MAX_TIMESTAMP= TIMESTAMP'2038-01-19 03:14:07.999999'; + +create table t1(x int primary key) with system versioning; +create table t2(y int primary key, + 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; +create table t3(z int primary key, + row_start timestamp(6) as row start, + row_end timestamp(6) as row end, + period for system_time (row_start, row_end)) +with system versioning; +--error ER_BAD_FIELD_ERROR +insert into t1(x, row_start, row_end) values (2, '1980-01-01 00:00:00', '1980-01-01 00:00:01'); +--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN +insert into t2(y, row_start, row_end) values (2, '1980-01-01 00:00:00', '1980-01-01 00:00:01'); +set @@system_versioning_insert_history= 1; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +insert into t1(x, row_start, row_end) values (3, '1980-01-01 00:00:00', '1980-01-01 00:00:01'); +insert into t2(y, row_start, row_end) values (4, '1980-01-01 00:00:00', '1980-01-01 00:00:01'); +insert into t3 values (5, '1980-01-01 00:00:00', '1980-01-01 00:00:01'); +--error ER_WRONG_VALUE +insert into t3 values (5, '1980-01-02 00:00:00', '1980-01-01 00:00:01'); + +select x, row_start, row_end from t1 for system_time all; +select y, row_start, row_end from t2 for system_time all; +select z, row_start, row_end from t3 for system_time all; + +insert into t1(x) values (1); +insert into t2(y) values (1); + +update t1 set x= x + 1; +--error ER_BAD_FIELD_ERROR +update t1 set row_start= '1971-01-01 00:00:00'; +--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN +update t2 set row_start= '1971-01-01 00:00:00'; +--error ER_BAD_FIELD_ERROR +insert t1 (x) values (2) on duplicate key update x= 3, row_end= '1970-01-01 00:00:00'; +--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN +insert t2 (y) values (1) on duplicate key update y= 3, row_end= '1970-01-01 00:00:00'; +--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN +insert t2 (y,row_end) values (1, '1970-01-01 00:00:00') on duplicate key update y= 3; +# this should work, row_start/row_end must be mentioned explicitly: +insert into t1 values (4); +insert into t1 set x= 5, row_start= '1980-01-01 00:00:00', row_end= '1980-01-01 00:00:01'; +--error ER_WRONG_VALUE +insert into t1(x, row_start, row_end) values (6, '1980-01-01 00:00:01', '1980-01-01 00:00:00'); +--error ER_WRONG_VALUE +insert into t1(x, row_start, row_end) values (7, '1980-01-01 00:00:11', '1980-01-01 00:00:11'); +insert into t1(x, row_start) values (8, '1980-01-01 00:00:22'); +--replace_regex /'202\d-\d\d-\d\d .*'/'now'/ +--error ER_WRONG_VALUE +insert into t1(x, row_end) values (9, '1980-01-01 00:00:33'); +eval insert into t1(x, row_end) values (10, $MAX_TIMESTAMP); +select x, check_row_ts(row_start, row_end) from t1 for system_time all order by x; +eval select x, row_start, row_end from t1 for system_time all +where x > 1 and row_end < $MAX_TIMESTAMP order by x, row_start, row_end; +--echo # Direct insert is not possible for TRX_ID versioning +create or replace table t2(y int primary key, + row_start bigint unsigned as row start, + row_end bigint unsigned as row end, + period for system_time (row_start, row_end)) +with system versioning engine innodb; +--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN +insert into t2(y, row_start, row_end) values (0, 1, 2); +set @@system_versioning_insert_history= 0; + +--echo ## INSERT..SELECT +create or replace table t2 like t1; +set @@system_versioning_insert_history= 1; +insert into t2 (x, row_start, row_end) select x, row_start, row_end from t1 for system_time all; +select x, check_row_ts(row_start, row_end) from t2 for system_time all order by x; +eval select x, row_start, row_end from t2 for system_time all +where x > 1 and row_end < $MAX_TIMESTAMP order by x, row_start, row_end; +set @@system_versioning_insert_history= 0; + +--echo # REPLACE / REPLACE .. SELECT +create or replace table t2(a int primary key, + 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_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN +replace into t2 (a, row_start, row_end) values (1, '1980-01-01 00:00:00', '1980-01-01 00:00:01'); +--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN +replace into t2 (a, row_start, row_end) select x, row_start, row_end from t1; +create or replace table t2 (a int primary key) with system versioning; +--error ER_BAD_FIELD_ERROR +replace into t2 (a, row_start, row_end) values (1, '1980-01-01 00:00:00', '1980-01-01 00:00:01'); +--error ER_BAD_FIELD_ERROR +replace into t2 (a, row_start, row_end) select x, row_start, row_end from t1; +set @@system_versioning_insert_history= 1; +--echo # REPLACE ignores system_versioning_insert_history +--error ER_BAD_FIELD_ERROR +replace into t2 (a, row_end) values (0, '1980-01-01 00:00:00'); +--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN +replace into t3 (z, row_start) values (0, '1980-01-01 00:00:00'); +--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN +replace into t3 values (0, '1980-01-01 00:00:00', '1981-01-01 00:00:00'); + +--echo # LOAD DATA +--let DATAFILE= $MYSQLTEST_VARDIR/tmp/test_versioning_t3.data +--replace_result $DATAFILE DATAFILE +--disable_ps2_protocol +eval select x, row_start, row_end into outfile '$DATAFILE' from t1 for system_time all; +--enable_ps2_protocol +create or replace table t2 like t1; +--replace_result $default_engine DEFAULT_ENGINE +show create table t2; +set @@system_versioning_insert_history= 1; +--replace_result $default_engine DEFAULT_ENGINE +show create table t2; +--replace_result $DATAFILE DATAFILE +eval load data infile '$DATAFILE' into table t2 (x, row_start, row_end); +select x, check_row_ts(row_start, row_end) from t2 for system_time all order by x; +select row_start = '1980-01-01 00:00:00', row_end = '1980-01-01 00:00:01' from t2 for system_time all where x = 3; +--remove_file $DATAFILE + +--echo # Honor secure_timestamp option +--let $restart_parameters= --secure-timestamp=YES +--source include/restart_mysqld.inc +set @@system_versioning_insert_history= 1; +--error ER_OPTION_PREVENTS_STATEMENT +insert into t3(z, row_start, row_end) values (8, '1980-01-01 00:00:00', '1980-01-01 00:00:01'); +--error ER_OPTION_PREVENTS_STATEMENT +insert into t3 values (8, '1980-01-01 00:00:00', '1980-01-01 00:00:01'); +--let $restart_parameters= --secure-timestamp=REPLICATION +--source include/restart_mysqld.inc +create user nobody; +grant all privileges on test.* to nobody; +change_user nobody; +set @@system_versioning_insert_history= 1; +--error ER_SPECIFIC_ACCESS_DENIED_ERROR +insert into test.t3(z, row_start, row_end) values (9, '1980-01-01 00:00:00', '1980-01-01 00:00:01'); +--error ER_SPECIFIC_ACCESS_DENIED_ERROR +insert into test.t3 values (9, '1980-01-01 00:00:00', '1980-01-01 00:00:01'); +change_user root; +--let $restart_parameters= --secure-timestamp=SUPER +--source include/restart_mysqld.inc +set @@system_versioning_insert_history= 1; +insert into test.t3(z, row_start, row_end) values (10, '1980-01-01 00:00:00', '1980-01-01 00:00:01'); +change_user nobody; +set @@system_versioning_insert_history= 1; +--error ER_SPECIFIC_ACCESS_DENIED_ERROR +insert into test.t3(z, row_start, row_end) values (7, '1980-01-01 00:00:00', '1980-01-01 00:00:01'); +--error ER_SPECIFIC_ACCESS_DENIED_ERROR +insert into test.t3 values (7, '1980-01-01 00:00:00', '1980-01-01 00:00:01'); +change_user root; +use test; +--let $restart_parameters= --secure-timestamp=NO +--source include/restart_mysqld.inc + +drop tables t1, t2, t3; + +--echo # +--echo # MDEV-29813 REPLACE/IGNORE does not work with historical records in InnoDB +--echo # +set sql_mode='STRICT_ALL_TABLES'; + +create or replace table t1 (a int) with system versioning; +set system_versioning_insert_history= on; +insert into t1 (a,row_start,row_end) values (1,'2022-01-01','2023-01-01'),(1,'2022-01-01','2023-01-01'); +--disable_ps2_protocol +select a,row_start,row_end into outfile 'mdev29813.txt' from t1 for system_time all; +--enable_ps2_protocol + +create or replace table t1 (a int primary key) with system versioning; +load data infile 'mdev29813.txt' ignore into table t1 (a,row_start,row_end); +select a,row_start,row_end from t1 for system_time all; + +create or replace table t1 (a int primary key) with system versioning; +insert ignore into t1 (a,row_start,row_end) values (1,'2022-01-01','2023-01-01'),(1,'2022-01-01','2023-01-01'); +select a,row_start,row_end from t1 for system_time all; + +--let $datadir= `select @@datadir` +--remove_file $datadir/test/mdev29813.txt +drop table t1; +set sql_mode=default; + +-- source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/t/insert2.test b/mysql-test/suite/versioning/t/insert2.test new file mode 100644 index 00000000..1e7d2166 --- /dev/null +++ b/mysql-test/suite/versioning/t/insert2.test @@ -0,0 +1,86 @@ +--source include/have_innodb.inc + +# TRT test + +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; + +start transaction; +insert into t2(x) values(1); +savepoint a; +insert into t1(x) values(1); +rollback to a; +commit; + +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, + 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; +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, e>TIMESTAMP'2038-01-01 00:00:00' AS current_row from t1; + +drop table t1; +drop table t2; + +--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; + +# +# MDEV-14794 Limitations which the row end as a part of PK imposes due to CURRENT_TIMESTAMP behavior and otherwise +# +create table t1 (pk int primary key, i int) with system versioning; +replace into t1 values (1,10),(1,100),(1,1000); +select pk,i,row_end > '2038-01-01' from t1 for system_time all; +drop table t1; diff --git a/mysql-test/suite/versioning/t/load_data.test b/mysql-test/suite/versioning/t/load_data.test new file mode 100644 index 00000000..4b77d9f8 --- /dev/null +++ b/mysql-test/suite/versioning/t/load_data.test @@ -0,0 +1,18 @@ +# +# MDEV-15330 Server crash or assertion `table->insert_values' failure in write_record upon LOAD DATA +# +--let $datadir= `select @@datadir` +CREATE TABLE t1 (a INT, b INT, c INT, vc INT AS (c), UNIQUE(a), UNIQUE(b)) WITH SYSTEM VERSIONING; +INSERT IGNORE INTO t1 (a,b,c) VALUES (1,2,3); + +--enable_prepare_warnings +--disable_ps2_protocol +SELECT a, b, c FROM t1 INTO OUTFILE '15330.data'; +--disable_prepare_warnings +--enable_ps2_protocol +LOAD DATA INFILE '15330.data' IGNORE INTO TABLE t1 (a,b,c); +LOAD DATA INFILE '15330.data' REPLACE INTO TABLE t1 (a,b,c); + +# Cleanup +DROP TABLE t1; +--remove_file $datadir/test/15330.data diff --git a/mysql-test/suite/versioning/t/misc.test b/mysql-test/suite/versioning/t/misc.test new file mode 100644 index 00000000..fa5012b6 --- /dev/null +++ b/mysql-test/suite/versioning/t/misc.test @@ -0,0 +1,51 @@ +# +# simple tests that don't need to be run in multiple various combinations +# +set time_zone='+00:00'; + +--echo # +--echo # MDEV-29750 triggers can modify history +--echo # +set sql_mode='', timestamp=unix_timestamp('2010-10-10 10:10:10'); +create table t (a int, b int as (a+1), s timestamp(6) as row start, e timestamp(6) as row end, period for system_time(s,e)) with system versioning; +insert into t values (1,1, '2022-01-01','2023-01-01'),(2,2, '2022-02-02','2023-02-02'); +create trigger tr before insert on t for each row set new.b=1, new.s = '2022-03-03', new.e = '2023-03-03'; +insert into t (a) values (3),(4); +select * from t for system_time all; +drop table t; +set sql_mode=default, timestamp=default; + +--echo # +--echo # End of 10.3 tests +--echo # +# +# simple tests that don't need to be run in multiple various combinations +# +set time_zone='+00:00'; + +--echo # +--echo # MDEV-29721 Inconsistency upon inserting history with visible system versioning columns +--echo # +create table t1 (a int, s timestamp(6) as row start, e timestamp(6) as row end, period for system_time(s,e)) with system versioning; +set system_versioning_insert_history=on; +set timestamp=unix_timestamp('2010-10-10 10:10:10'); +insert t1 (a,s,e) values (1,'2020-01-01',default), (2,'2020-02-02',ignore),(3,default,'2020-03-03'), (4,ignore,'2020-04-04'); +set timestamp=unix_timestamp('2010-11-11 11:11:11'); +insert t1 values (5,'2020-01-01',default), (6,'2020-02-02',ignore),(7,default,'2020-03-03'), (8,ignore,'2020-04-04'); +set timestamp=default; +select * from t1 for system_time all; +drop table t1; + +--echo # +--echo # MDEV-29830 Assertion `table->versioned()' in THD::vers_insert_history_fast +--echo # +create table t1 (a int) with system versioning; +insert into t1 values (1),(2); +create table t2 (a timestamp); +insert into t2 (a) values (now()),(now()); +select * from t2 where a in (select row_start from t1); +drop table t1, t2; + +--echo # +--echo # End of 10.11 tests +--echo # diff --git a/mysql-test/suite/versioning/t/not_embedded.test b/mysql-test/suite/versioning/t/not_embedded.test new file mode 100644 index 00000000..38f42a44 --- /dev/null +++ b/mysql-test/suite/versioning/t/not_embedded.test @@ -0,0 +1,107 @@ +--source include/not_embedded.inc +--source include/have_innodb.inc +--source include/have_partition.inc + +--echo # +--echo # SYSTEM_VERSIONING_ASOF sysvar +--echo # +create table t (a int) with system versioning; +set @before= UNIX_TIMESTAMP(now(6)); +insert into t values (1); +set @after= UNIX_TIMESTAMP(now(6)); +update t set a= 2; + +set global system_versioning_asof= FROM_UNIXTIME(@after); +set system_versioning_asof= FROM_UNIXTIME(@after); +select * from t as nonempty; + +--connect (subcon,127.0.0.1,root,,,$SERVER_MYPORT_1) +--connection subcon +select * from t as nonempty; +--disconnect subcon +--connection default + +set global system_versioning_asof= FROM_UNIXTIME(@before); +select * from t as nonempty; + +--connect (subcon,127.0.0.1,root,,,$SERVER_MYPORT_1) +--connection subcon +select * from t as empty; +--disconnect subcon +--connection default + +drop table t; + +set global system_versioning_asof= DEFAULT; +set system_versioning_asof= DEFAULT; + +--echo # +--echo # DELETE HISTORY and privileges +--echo # + +# 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,,"*NO-ONE*"); +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; +--disconnect user1 +--disconnect root +--connection default + +--echo # +--echo # MDEV-25559 Auto-create: infinite loop after interrupted lock wait +--echo # + +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create table t (pk int primary key, a int) engine innodb with system versioning +partition by system_time interval 1 hour auto; +insert into t values (1, 0); +begin; +update t set a= a + 1; +--connect (con1,localhost,root,,) +set max_statement_time= 1; +set timestamp= unix_timestamp('2000-01-01 01:00:00'); +send update t set a= a + 2; +--connection default +set timestamp= unix_timestamp('2000-01-01 01:00:00'); +send update t set a= a + 3; +--connection con1 +--error ER_STATEMENT_TIMEOUT +reap; +--disconnect con1 +--connection default +reap; +commit; +drop table t; +set timestamp= default; diff --git a/mysql-test/suite/versioning/t/online.test b/mysql-test/suite/versioning/t/online.test new file mode 100644 index 00000000..5932c346 --- /dev/null +++ b/mysql-test/suite/versioning/t/online.test @@ -0,0 +1,198 @@ +--source suite/versioning/innodb.inc +--source suite/versioning/common.inc +--source include/maybe_debug.inc + +set system_versioning_alter_history=keep; + +create or replace table t (a int); +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +alter table t add system versioning, lock=none; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +alter table t add system versioning, algorithm=inplace; +alter table t add system versioning, lock=shared; + +alter table t add column b int, change column a a int without system versioning, lock=none; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +alter table t drop system versioning, lock=none; +alter table t drop system versioning, algorithm=inplace; + +--replace_result $sys_datatype_expl SYS_DATATYPE +eval create or replace table t ( + a int, b int, + row_start $sys_datatype_expl as row start invisible, + row_end $sys_datatype_expl as row end invisible, + period for system_time (row_start, row_end) +) with system versioning; +insert into t values (1, 0); +insert into t values (2, 0); +delete from t where a = 2; +alter table t drop column b, lock=none; +alter table t add index idx(a), lock=none; + +select a, check_row(row_start, row_end) from t for system_time all order by a; + +--echo # MDEV-17038 ALTER TABLE CHANGE COLUMN c1 c1 bigint NOT NULL - +--echo # generates error if table uses SYSTEM VERSIONING [tempesta-tech/mariadb#540] +create or replace table t1 (a int, key(a)) with system versioning; +create or replace table t2 like t; +alter table t2 add foreign key(a) references t1(a); +alter table t2 modify column a int not null, lock=none; + +drop table t2; +drop table t1; + +--echo # MDEV-16330 Allow instant change of WITH SYSTEM VERSIONING column attribute +--replace_result $sys_datatype_expl SYS_DATATYPE +eval create or replace table t1 ( + a int, + b int, + row_start $sys_datatype_expl as row start invisible, + row_end $sys_datatype_expl as row end invisible, + period for system_time(row_start, row_end) +) with system versioning; + +--replace_result $sys_datatype_expl SYS_DATATYPE +eval create or replace table t2 ( + a int without system versioning, + b int, + row_start $sys_datatype_expl as row start invisible, + row_end $sys_datatype_expl as row end invisible, + period for system_time(row_start, row_end) +) with system versioning; + +insert into t1 values (1,1); +insert into t2 values (1,1); + +set @@system_versioning_alter_history=keep; + +--enable_info +--echo # without rebuild +alter table t1 + change a a int without system versioning, + algorithm=instant; + +--error ER_ALTER_OPERATION_NOT_SUPPORTED +alter table t2 + change a a int with system versioning, + add primary key pk (a), + algorithm=instant; + +--echo # with rebuild +alter table t2 + change a a int with system versioning, + add primary key pk (a); +--disable_info + +--source include/restart_mysqld.inc + +update t1 set a=2; +select count(*) from t1 for system_time all; + +update t2 set a=2; +select count(*) from t2 for system_time all; + +drop table t1, t2; + +--echo # rollback ALTER TABLE: nothing should change +--replace_result $sys_datatype_expl SYS_DATATYPE +eval create or replace table t ( + a int, + b int, + row_start $sys_datatype_expl as row start invisible, + row_end $sys_datatype_expl as row end invisible, + period for system_time(row_start, row_end) +) with system versioning; + +insert into t values (1, 1); + +select c.prtype from information_schema.innodb_sys_columns as c + join information_schema.innodb_sys_tables as t on c.table_id=t.table_id + where t.name='test/t' and c.name='b'; + +set @@system_versioning_alter_history=keep; + +if ($have_debug) { +--disable_query_log +--disable_result_log +set debug_dbug='+d,ib_commit_inplace_fail_1'; +--error ER_INTERNAL_ERROR +alter table t + change b b int without system versioning; +set debug_dbug= default; +--enable_query_log +--enable_result_log +} + +select c.prtype from information_schema.innodb_sys_columns as c + join information_schema.innodb_sys_tables as t on c.table_id=t.table_id + where t.name='test/t' and c.name='b'; + +--replace_result $sys_datatype_expl SYS_DATATYPE +show create table t; + +select count(*) from t for system_time all; +update t set b=11; +select count(*) from t for system_time all; +drop table t; + +--echo # Start of 10.4 tests + +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; +alter table t drop column b, algorithm=instant; +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; + +--echo # +--echo # MDEV-17697 Broken versioning info after instant drop column +--echo # +set @@system_versioning_alter_history= keep; +create or replace table t1 (a int, b int) with system versioning; +insert into t1 values (1, 1); +alter table t1 drop column b, algorithm=instant; +alter table t1 drop system versioning; + +create or replace table t1 (a int, b int) with system versioning; +insert into t1 values (1, 1); + +if ($have_debug) { +--disable_query_log +--disable_result_log +set debug_dbug='+d,ib_commit_inplace_fail_1'; +--error ER_INTERNAL_ERROR +alter table t1 drop column b, algorithm=instant; +set debug_dbug= default; +--enable_query_log +--enable_result_log +} +alter table t1 drop system versioning; + +--echo # +--echo # MDEV-18173 Assertion `o->ind == vers_end' or `o->ind == vers_start' failed in dict_table_t::instant_column +--echo # +set @@system_versioning_alter_history= keep; +create or replace table t1 (pk integer primary key, a int, b int, v int as (a)) +with system versioning; + +alter table t1 force; +alter table t1 drop column b; + +--echo # +--echo # MDEV-18122 Assertion `table->versioned() == m_prebuilt->table->versioned()' failed in ha_innobase::open +--echo # +create or replace table t1 ( + x int, + v int as (x) virtual, + y int +) with system versioning; +alter table t1 drop system versioning; + +drop tables t, t1; + +--source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/t/optimized.test b/mysql-test/suite/versioning/t/optimized.test new file mode 100644 index 00000000..054c1d32 --- /dev/null +++ b/mysql-test/suite/versioning/t/optimized.test @@ -0,0 +1,40 @@ +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; + +# +# MDEV-15062 Information Schema COLUMNS Table does not show system versioning information +# +create or replace table t (x int with system versioning, y int); +select column_name, extra from information_schema.columns where table_name='t'; +show create table t; + +drop table t; diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test new file mode 100644 index 00000000..3699ac28 --- /dev/null +++ b/mysql-test/suite/versioning/t/partition.test @@ -0,0 +1,2677 @@ +-- source include/have_partition.inc +-- source suite/versioning/common.inc +-- source suite/versioning/engines.inc +-- source include/have_sequence.inc + +set @save_persistent=@@global.innodb_stats_persistent; +set global innodb_stats_persistent= 0; + +call mtr.add_suppression("need more HISTORY partitions"); + +--enable_prepare_warnings + +set system_versioning_alter_history=keep; +--let $datadir= `select @@datadir` +--echo # Check conventional partitioning on temporal tables + +--replace_result $sys_datatype_expl SYS_DATATYPE +eval create or replace table t1 ( + x int, + row_start $sys_datatype_expl as row start invisible, + row_end $sys_datatype_expl as row end invisible, + period for system_time(row_start, row_end)) +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 $sys_datatype_expl SYS_DATATYPE $default_engine DEFAULT_ENGINE +eval create or replace table t1 ( + i int, + row_start $sys_datatype_expl as row start invisible, + row_end $sys_datatype_expl as row end invisible, + period for system_time(row_start, row_end)) +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_NOT_VERSIONED +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_NOT_VERSIONED +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); + +--error ER_PARTITION_WRONG_TYPE +create or replace table t1 (a int) +partition by range (a) ( + partition p0 history, + partition p1 current); + +--error ER_PARTITION_WRONG_TYPE +create or replace table t1 (b int) +partition by range (a) ( + partition p0 current, + partition p1 history); + + +--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 +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 # rename works +create or replace table t1 (x int) with system versioning +partition by system_time; +alter table t1 reorganize partition p0 into +(partition custom_name history); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +--echo # merge and split doesn't (MDEV-19938) +create or replace table t1 (x int) with system versioning +partition by system_time limit 10 partitions 3; +--error ER_REORG_HASH_ONLY_ON_SAME_NO +alter table t1 reorganize partition p0, p1 into (partition p00 history); +--error ER_REORG_HASH_ONLY_ON_SAME_NO +alter table t1 reorganize partition p1 into (partition p1 history, partition p2 history); + + +--echo # Bug tempesta-tech/mariadb#260: incorrect IB partitioning warning +create or replace table t1 (x int) +with system versioning +partition by system_time limit 1; +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; + +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; + +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 # +--echo # Rotation by LIMIT +--echo # +--error ER_PART_WRONG_VALUE +create or replace table t1 (x int) +with system versioning +partition by system_time limit 0 partitions 3; + +create or replace table t1 (x int) +with system versioning +partition by system_time limit 2 partitions 3; + +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +--error ER_PARTITION_DOES_NOT_EXIST +alter table t1 drop partition non_existent; + +insert into t1 values (1), (2), (3), (4), (5), (6); +select * from t1 partition (pn); +delete from t1 where x < 4; +delete from t1; +--echo # You see warning above ^ +select * from t1 partition (p0); +select * from t1 partition (p1); + +insert into t1 values (7), (8); +--echo ### warn about full partition +delete from t1; +--echo # You see warning above ^ +select * from t1 partition (p1) order by x; + +--echo # +--echo # Rotation by INTERVAL +--echo # +--error ER_PART_WRONG_VALUE +create or replace table t1 (x int) +with system versioning +partition by system_time interval 0 second partitions 3; + +--error ER_PARSE_ERROR +create table t1 (i int) with system versioning +partition by system_time interval 6 day limit 98; + +--error ER_DATA_OUT_OF_RANGE +create or replace table t1 (pk int) with system versioning +partition by system_time interval 10 year partitions 3; + +--echo # INTERVAL and ALTER TABLE +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 hour; + +set @ts=(select partition_description from information_schema.partitions + where table_schema='test' and table_name='t1' and partition_name='p0'); + +alter table t1 add column b int; +select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1'; +alter table t1 add partition (partition p1 history, partition p2 history); +select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1'; +alter table t1 drop partition p0; +select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1'; +--error ER_VERS_DROP_PARTITION_INTERVAL +alter table t1 drop partition p2; +select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1'; + +# +# partition rotation (moved from partition_rotation.test) +# +set timestamp=unix_timestamp('2001-02-03 10:20:30'); +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 day + subpartition by key (i) subpartitions 2 + (partition p1 history, partition pn current); +set timestamp=unix_timestamp('2001-02-03 10:20:40'); +insert t1 values (1); delete from t1; +set timestamp=unix_timestamp('2001-02-04 10:20:50'); +insert t1 values (2); delete from t1; + +select subpartition_name, partition_description, table_rows from information_schema.partitions where table_schema='test' and table_name='t1'; +select * from t1 partition (p1); + +set timestamp=unix_timestamp('2001-02-04 10:20:55'); +alter table t1 add partition (partition p0 history, partition p2 history); +set timestamp=unix_timestamp('2001-02-04 10:30:00'); +insert t1 values (4),(5); +set timestamp=unix_timestamp('2001-02-04 10:30:10'); +update t1 set i=6 where i=5; + +select subpartition_name, partition_description, table_rows from information_schema.partitions where table_schema='test' and table_name='t1'; +select * from t1 partition (p1); +select * from t1 partition (p0); +select * from t1 partition (p2); + +alter table t1 rebuild partition p0, p1, p2; +select * from t1 partition (p1); +select * from t1 partition (p0); +select * from t1 partition (p2); + +--echo ## pruning check +set @ts=(select partition_description from information_schema.partitions + where table_schema='test' and table_name='t1' and partition_name='p0' limit 1); +--sorted_result +select * from t1; +--replace_column 10 # +explain partitions select * from t1; +--replace_column 10 # +explain partitions select * from t1 for system_time as of '2001-02-04 10:20:30'; +set @ts=(select row_end from t1 for system_time all where i=1); +select * from t1 for system_time all where row_end = @ts; +--replace_column 5 # 10 # 11 # +explain partitions select * from t1 for system_time all where row_end = @ts; + +--echo # +--echo # MDEV-16023 Unfortunate error message WARN_VERS_PART_FULL +--echo # + +set timestamp= unix_timestamp('2020-07-29 10:30:10'); +create or replace table t1 (a int) with system versioning + partition by system_time interval 1 second ( + partition p0 history, + partition p1 history, + partition pc current + ); + +set timestamp= unix_timestamp('2020-07-29 10:30:14'); +insert into t1 values (1),(2),(3); +show warnings; + +--echo # Cleanup +set timestamp= default; + +--echo ## INTERVAL ... STARTS +--error ER_PART_WRONG_VALUE +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 day starts 'a'; + +--error ER_PART_WRONG_VALUE +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 day starts '00:00:00'; + +--error ER_PART_WRONG_VALUE +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 day starts '2000-00-01 00:00:00'; + +--error ER_PART_WRONG_VALUE +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 day starts 946684800; + +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 day starts '2000-01-01 00:00:00'; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +--echo # Test STARTS warning +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 day; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 day starts '2000-01-01 00:00:01'; + +--echo # Test default STARTS rounding +set timestamp= unix_timestamp('1999-12-15 13:33:33'); +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 second; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 minute; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 hour; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 day; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 month; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 year; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +--echo # seconds equivalent of 1 day does not round: +create or replace table t1 (i int) with system versioning +partition by system_time interval 86400 second; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +--echo # STARTS value is in local time_zone: +set time_zone="+03:00"; +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 day starts '2000-01-01 00:00:00'; + +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create or replace table t2 (i int) with system versioning +partition by system_time interval 1 day; + +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +--replace_result $default_engine DEFAULT_ENGINE +show create table t2; +set time_zone="+00:00"; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +--replace_result $default_engine DEFAULT_ENGINE +show create table t2; + +--echo # Test rotation +set timestamp= unix_timestamp('2001-01-01 00:00:00'); +--echo # it's ok to add partitions for past: +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 day starts '2000-01-01 00:00:00' +partitions 3; + +insert into t1 values (0); +set timestamp= unix_timestamp('2001-01-01 00:00:01'); +update t1 set i= i + 1; +set timestamp= unix_timestamp('2001-01-01 00:00:02'); +update t1 set i= i + 1; + +select *, row_end from t1 partition (p0); +select *, row_end from t1 partition (p1); + +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +--echo # now we "overflow" first partition a bit: +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 day starts '2000-01-03 00:00:00' +partitions 3; + +insert into t1 values (0); +set timestamp= unix_timestamp('2000-01-01 00:00:01'); +update t1 set i= i + 1; +set timestamp= unix_timestamp('2000-01-02 00:00:01'); +update t1 set i= i + 1; +set timestamp= unix_timestamp('2000-01-03 00:00:01'); +update t1 set i= i + 1; +set timestamp= unix_timestamp('2000-01-04 00:00:01'); +update t1 set i= i + 1; + +select *, row_end from t1 partition (p0); +select *, row_end from t1 partition (p1); + +--echo # and this is how it usually goes: +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 day +partitions 3; + +insert into t1 values (0); +set timestamp= unix_timestamp('2000-01-01 00:00:01'); +update t1 set i= i + 1; +set timestamp= unix_timestamp('2000-01-02 00:00:01'); +update t1 set i= i + 1; +set timestamp= unix_timestamp('2000-01-03 00:00:01'); +update t1 set i= i + 1; +set timestamp= unix_timestamp('2000-01-04 00:00:01'); +update t1 set i= i + 1; + +alter table t1 add partition (partition p2 history, partition p3 history); +select *, row_end from t1 partition (p0); +select *, row_end from t1 partition (p1); +select *, row_end from t1 partition (p2); +select *, row_end from t1 partition (p3); + +drop tables t1, t2; + +--echo ## Subpartitions +create or replace table t1 (x int) +with system versioning +partition by system_time limit 2 partitions 3 +subpartition by key (x) +subpartitions 2; + +insert into t1 (x) values (1), (2), (3), (4), (5); +select * from t1 partition (pnsp0); +select * from t1 partition (pnsp1); + +delete from t1 where x < 3; +delete from t1; +--echo # You see warning above ^ +delete from t1; +--echo # You see warning above ^ (no matter if nothing was deleted) +select * from t1 partition (p0sp0); +select * from t1 partition (p0sp1); +select * from t1 partition (p1sp0); +select * from t1 partition (p1sp1); + +--echo # check implicit sys fields for implicit engine of partitioned table +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); +select * from t1 partition (p0); + +--echo # check for partition engine +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); +select * from t1 partition (part1); + +--echo # +--echo # TRX_ID versioning (moved from partition_innodb.test) +--echo # +--echo # MDEV-15951 system versioning by trx id doesn't work with partitioning +--echo # currently trx_id does not support partitioning by system_time +--error ER_VERS_FIELD_WRONG_TYPE +create or replace table t1( + i int, + row_start bigint unsigned generated always as row start, + row_end bigint unsigned generated always as row end, + period for system_time(row_start, row_end) +) engine=InnoDB with system versioning partition by system_time ( + partition p0 history, + partition pn current +); + +create or replace table t1( + i int, + row_start bigint unsigned generated always as row start, + row_end bigint unsigned generated always as row end, + period for system_time(row_start, row_end) +) engine=InnoDB with system versioning; + +--error ER_VERS_FIELD_WRONG_TYPE +alter table t1 partition by system_time ( + partition p0 history, + partition pn current +); + +drop table t1; + +--error ER_VERS_TRX_PART_HISTORIC_ROW_NOT_SUPPORTED +create or replace table t ( + a int primary key, + row_start bigint unsigned as row start invisible, + row_end bigint unsigned as row end invisible, + period for system_time(row_start, row_end) +) engine=innodb with system versioning +partition by key() ( + partition p1, + partition p2 +); + +--error ER_VERS_TRX_PART_HISTORIC_ROW_NOT_SUPPORTED +create or replace table t ( + a int primary key, + row_start bigint unsigned as row start invisible, + row_end bigint unsigned as row end invisible, + period for system_time(row_start, row_end) +) engine=innodb with system versioning +partition by key(a, row_start) ( + partition p1, + partition p2 +); + +--error ER_VERS_TRX_PART_HISTORIC_ROW_NOT_SUPPORTED +create or replace table t ( + a int primary key, + row_start bigint unsigned as row start invisible, + row_end bigint unsigned as row end invisible, + period for system_time(row_start, row_end) +) engine=innodb with system versioning +partition by hash(a + row_end * 2) ( + partition p1, + partition p2 +); + +--error ER_VERS_TRX_PART_HISTORIC_ROW_NOT_SUPPORTED +create or replace table t ( + a int primary key, + row_start bigint unsigned as row start invisible, + row_end bigint unsigned as row end invisible, + period for system_time(row_start, row_end) +) engine=innodb with system versioning +partition by range columns (a, row_start) ( + partition p1 values less than (100, 100) +); + +--echo # +--echo # Assertion in ALTER on warning from partitioning LIMIT [#446] +--echo # +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 # +--echo # MDEV-14649 Assertion `t->mysql_col_len == 8' failed in row_insert_for_mysql +--echo # +create or replace table t1 (i int) engine=innodb partition by key(i); +alter table t1 add system versioning; +insert into t1 values(); + +--echo # +--echo # MDEV-14722 Assertion in ha_commit_trans for sub-statement +--echo # +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 day; +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 # +--echo # MDEV-14740 Locking assertion for system_time partitioning +--echo # +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 week; +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 # +--echo # MDEV-14747 ALTER PARTITION BY SYSTEM_TIME after LOCK TABLES +--echo # +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 # +--echo # MDEV-14748 Assertion in ha_myisammrg::attach_children() +--echo # +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 # +--echo # MDEV-14821 Assertion failure +--echo # +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; +--echo # You see warning above ^ +delete from t1 where x = 2; +--echo # You see warning above ^ + +--echo # +--echo # MDEV-14923 Assertion upon INSERT into locked versioned partitioned table +--echo # +create or replace table t1 (x int) with system versioning +partition by system_time; +lock table t1 write; +--error ER_SAME_NAME_PARTITION +alter table t1 add partition (partition p0 history); +insert into t1 values (1); +unlock tables; + +--echo # +--echo # MDEV-15103 Assertion in ha_partition::part_records() for updating VIEW +--echo # +create or replace table t1 (pk int primary key, f int) with system versioning +partition by system_time limit 100; +insert into t1 values (1,10), (2,20); +create or replace view v1 as select * from t1; +update v1 set f= 30; + +--echo # +--echo # MDEV-15168 Unexpected ER_VERS_ENGINE_UNSUPPORTED upon dropping versioning on a partitioned table +--echo # +create or replace table t (a int) with system versioning +partition by system_time; +--error ER_DROP_VERSIONING_SYSTEM_TIME_PARTITION +alter table t drop system versioning; + +--echo # +--echo # MDEV-15191 Assertion `bit < (map)->n_bits' failed in bitmap_is_set upon INSERT +--echo # +create or replace table t1 (i int) with system versioning; +insert into t1 values (1), (2); +update t1 set i= 3; +alter table t1 partition by system_time interval 1 month (partition p1 history, partition pn current); +lock table t1 write; +alter table t1 add partition (partition p2 history); +insert into t1 values (4); +unlock tables; + +--echo # +--echo # MDEV-15036 Assertion `!is_set() || (m_status == DA_OK_BULK && is_bulk_op())' in Diagnostics_area::set_ok_status or unexpected ER_RANGE_NOT_INCREASING_ERROR +--echo # +create or replace table t1 (a int) with system versioning +partition by system_time limit 2 partitions 4; +insert into t1 values (1),(2),(3); +update t1 set a = 4; +delete from t1; +delete from t1 where a is not null; + +--echo # +--echo # MDEV-14823 Wrong error message upon selecting from a system_time partition +--echo # +create or replace table t1 (i int) with system versioning partition by system_time limit 10; +--error ER_VERS_QUERY_IN_PARTITION +select * from t1 partition (p0) for system_time all; +--echo # MDEV-18929 2nd execution of SP does not detect ER_VERS_NOT_VERSIONED +create or replace procedure sp() +select * from t1 partition (p0) for system_time all; +--error ER_VERS_QUERY_IN_PARTITION +call sp; +--error ER_VERS_QUERY_IN_PARTITION +call sp; +drop procedure sp; + +--echo # +--echo # MDEV-15380 Index for versioned table gets corrupt after partitioning and DELETE +--echo # +create or replace table t1 (pk int primary key) + engine=myisam + with system versioning + partition by key() partitions 3; +set timestamp=1523466002.799571; +insert into t1 values (11),(12); +set timestamp=1523466004.169435; +delete from t1 where pk in (11, 12); +--echo Same test but for Aria storage engine +create or replace table t1 (pk int primary key) + engine=aria + with system versioning + partition by key() partitions 3; +set timestamp=1523466002.799571; +insert into t1 values (11),(12); +set timestamp=1523466004.169435; +delete from t1 where pk in (11, 12); + +--echo # +--echo # MDEV-18136 Server crashes in Item_func_dyncol_create::prepare_arguments +--echo # +create or replace table t1 (pk int) with system versioning +partition by system_time interval 7 second; +alter table t1 +partition by system_time interval column_get(column_create(7,7), 7 as int) second ( + partition ver_p1 history, + partition ver_pn current); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +set timestamp= default; + +--echo # +--echo # MDEV-18794 Assertion `!m_innodb' failed in ha_partition::cmp_ref upon SELECT from partitioned table +--echo # +create or replace table t1 (pk int auto_increment, i int, c char(1), primary key (pk), key(i)) +engine=innodb with system versioning partition by key() partitions 2; +insert into t1 (i, c) values (1, 'a'), (2, 'b'), (null, 'c'), (null, 'b'); +alter table t1 drop system versioning; +replace into t1 select * from t1; +select * from t1 where i > 0 or pk = 1000 limit 1; +drop table t1; + +--echo # +--echo # MDEV-19175 Server crashes in ha_partition::vers_can_native upon INSERT DELAYED into versioned partitioned table +--echo # +create or replace table t1 (f int) with system versioning partition by hash(f); +# delayed works differently in embedded server +--error 0,ER_DELAYED_NOT_SUPPORTED +insert delayed into t1 values (1); + +--echo # +--echo # MDEV-20068 History partition rotation is not done under LOCK TABLES +--echo # +create or replace table t1 (x int) with system versioning partition by system_time limit 1 +(partition p1 history, partition pn current); +lock tables t1 write; +insert into t1 values (0), (1), (2), (3); +delete from t1 where x < 3; +--echo # You see warning above ^ +delete from t1; +--echo # You see warning above ^ +unlock tables; + +--echo # +--echo # MDEV-20336 Assertion bitmap_is_set(read_partitions) upon SELECT FOR UPDATE from versioned table +--echo # +create or replace table t1 (pk int primary key) with system versioning partition by system_time limit 100 (partition p1 history, partition pn current); +execute immediate 'select * from t1 for update'; + +--echo # +--echo # MDEV-19903 Setup default partitions for system versioning +--echo # +create or replace table t1 (x int) with system versioning partition by system_time; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +--echo # 2 partitions are created: p0 and pn +select PARTITION_NAME, PARTITION_METHOD, PARTITION_DESCRIPTION from information_schema.partitions where table_name = 't1' order by PARTITION_NAME; + +create or replace table t1 (x int) with system versioning partition by system_time limit 10 partitions 4; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +--echo # 4 partitions are created: p0, p1, p2 and pn +select PARTITION_NAME, PARTITION_METHOD, PARTITION_DESCRIPTION from information_schema.partitions where table_name = 't1' order by PARTITION_NAME; + +--echo # Test cleanup +drop view v1; +drop tables t, t1, t2, t3, t4; + +--echo # +--echo # MDEV-18957 UPDATE with LIMIT clause is wrong for versioned partitioned tables +--echo # +create or replace table t1 ( + x int, + a varchar(255) +) with system versioning partition by system_time (partition p1 history, partition pn current); + +insert into t1 (x) values (1), (2), (3), (4); +update t1 set a= 'foo' limit 3; +update t1 set a= 'bar' limit 4; +select * from t1; +drop table t1; + +--echo # +--echo # MDEV-21011 Table corruption reported for versioned partitioned table after DELETE: "Found a misplaced row" +--echo # +create table t1 (a int) with system versioning +partition by system_time limit 3 +(partition p1 history, partition p2 history, partition pn current); +insert into t1 values (1),(2),(3),(4); +delete from t1; +delete from t1; +check table t1; + +# cleanup +drop table t1; + +--echo # +--echo # MDEV-21233 Assertion `m_extra_cache' failed in ha_partition::late_extra_cache +--echo # +create table t1 (id int, a varchar(8)) with system versioning partition by key (id) partitions 2; +insert into t1 values (1,'foo'),(2,'bar'); + +create table t2 (b int); +insert into t2 values (1),(2); + +update t1, t2 set a = 1; + +# cleanup +drop table t1, t2; + +--echo # +--echo # MDEV-20515 multi-update tries to position updated table by null reference +--echo # +create or replace table t1 (a int); +insert into t1 values (0), (1); + +create or replace table t2 (b int) with system versioning +partition by system_time +(partition p1 history, partition pn current); + +insert into t2 values (0), (2); +update t1 left join t2 on a > b set b= 2 order by b; + +# cleanup +drop table t1, t2; + +--echo # +--echo # MDEV-17091 Assertion `old_part_id == m_last_part' failed in +--echo # ha_partition::update_row or `part_id == m_last_part' in +--echo # ha_partition::delete_row upon UPDATE/DELETE after dropping versioning +--echo # +create or replace table t1 (pk int primary key, f int) engine=innodb + with system versioning + partition by key() partitions 2; +insert into t1 values (1,10),(2,20); +--echo # expected to hit same partition +select * from t1 partition (p0); +alter table t1 drop system versioning; + +--echo # 1 and 2 are expected to be in different partitions +select * from t1 partition(p0); +select * from t1 partition(p1); + +update t1 set f=pk; +delete from t1; +drop table t1; + +--echo # +--echo # MDEV-22413 Server hangs upon UPDATE/DELETE on a view reading from versioned partitioned table +--echo # +create or replace table t1 (f char(6)) engine innodb with system versioning; + +insert into t1 values (null); +update t1 set f= 'foo'; +update t1 set f= 'bar'; +--echo # You see warning above ^ + +create or replace view v1 as select * from t1 for system_time all; +--error ER_TABLE_NOT_LOCKED_FOR_WRITE +update v1 set f = ''; + +create or replace table t1 (f char(6)) engine innodb with system versioning +partition by system_time limit 1 +(partition p1 history, partition p2 history, partition pn current); + +insert into t1 values (null); +update t1 set f= 'foo'; +update t1 set f= 'bar'; + +create or replace view v1 as select * from t1 for system_time all; +--error ER_TABLE_NOT_LOCKED_FOR_WRITE +update v1 set f= ''; +--error ER_TABLE_NOT_LOCKED_FOR_WRITE +delete from v1; + +# cleanup +drop view v1; +drop table t1; + +--echo # +--echo # MDEV-22112 Assertion `tab_part_info->part_type == RANGE_PARTITION || tab_part_info->part_type == LIST_PARTITION' failed in prep_alter_part_table +--echo # + +create table t1 (a int) with system versioning partition by system_time; +drop table t1; + +create table t1 (a int) with system versioning partition by system_time +(partition p1 history, partition pn current); +--error ER_PARTITION_WRONG_TYPE +alter table t1 add partition (partition p2); + +--echo # MDEV-17891 Assertion failures in select_insert::abort_result_set and +--echo # mysql_load upon attempt to replace into a full table + +--let $max_heap_table_size_orig= `select @@max_heap_table_size;` +set @@max_heap_table_size= 1024*1024; +create or replace table t1 ( + pk integer auto_increment, + primary key (pk), + f varchar(45000) +) with system versioning engine=memory + partition by system_time interval 1 year (partition p1 history, + partition pn current); + +--echo # fill the table until full +insert into t1 () values (),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(); +--error ER_RECORD_FILE_FULL +insert into t1 (f) select f from t1; +--echo # leave space for exactly one record in current partition +delete from t1 where pk = 1; +--echo # copy all data into history partition +replace into t1 select * from t1; +--error ER_RECORD_FILE_FULL +replace into t1 select * from t1; + +create or replace table t1 ( + pk integer auto_increment, + primary key (pk), + f varchar(45000) +) with system versioning engine=memory + partition by system_time interval 1 year (partition p1 history, + partition pn current); + +insert into t1 () values (),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(); + +--disable_ps2_protocol +select * into outfile 'MDEV-17891.data' from t1; +--enable_ps2_protocol +load data infile 'MDEV-17891.data' replace into table t1; +--error ER_RECORD_FILE_FULL +load data infile 'MDEV-17891.data' replace into table t1; +--error ER_RECORD_FILE_FULL +load data infile 'MDEV-17891.data' replace into table t1; + +# Cleanup +--remove_file $datadir/test/MDEV-17891.data +eval set @@max_heap_table_size= $max_heap_table_size_orig; +drop table t1; + +--echo # +--echo # MDEV-22178 Assertion `info->alias.str' failed in partition_info::check_partition_info instead of ER_VERS_WRONG_PARTS +--echo # +create or replace table t1 (a int) with system versioning; +--error ER_VERS_WRONG_PARTS +alter table t1 partition by system_time (partition pn current); +# Cleanup +drop table t1; + +--echo # +--echo # MDEV-22247 History partition overflow leads to wrong SELECT result +--echo # +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create or replace table t1 (x int) with system versioning +partition by system_time interval 1 hour +(partition p0 history, partition p1 history, partition pn current); + +insert into t1 values (0); +update t1 set x= x + 1; + +set timestamp= unix_timestamp('2000-01-01 02:00:01'); +update t1 set x= x + 1; + +select *, row_start, row_end from t1 for system_time as of '2000-01-01 02:00:00'; +--replace_column 10 # +explain partitions select * from t1 for system_time as of '2000-01-01 02:00:00'; +--replace_column 5 # 10 # 11 # +explain partitions select * from t1; +drop table t1; + +--echo # +--echo # MDEV-27244 Table corruption upon adding serial data type +--echo # +create table t1 (f int, key(f)) with system versioning +partition by system_time limit 10 (partition p0 history, partition pn current); +alter table t1 add x serial; +alter table t1 add partition (partition p1 history); +alter table t1 add partition (partition p2 history); +drop table t1; + +--echo # +--echo # MDEV-27217 DELETE partition selection doesn't work for history partitions +--echo # +create table t1 (f char) with system versioning +partition by system_time limit 10 ( + partition p0 history, + partition p1 history, + partition p2 history, + partition pn current); + +--error ER_VERS_NOT_ALLOWED +delete from t1 partition (p1); +--error ER_VERS_NOT_ALLOWED +delete from t1 partition (p0, pn); +--error ER_VERS_NOT_ALLOWED +delete from t1 partition (p0, p1); +--error ER_VERS_NOT_ALLOWED +delete from t1 partition (p0, p1, pn); +drop table t1; + +set timestamp=unix_timestamp('2000-01-01 00:00:00'); +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 day ( + partition p0 history, + partition p1 history, + partition pn current); +set timestamp=unix_timestamp('2000-01-02 00:00:00'); +insert t1 values (1); +--error ER_VERS_NOT_ALLOWED +delete from t1 partition (p0, pn); +--error ER_VERS_NOT_ALLOWED +delete from t1 partition (p0, p1, pn); +lock tables t1 write; +--error ER_VERS_NOT_ALLOWED +delete from t1 partition (p0, pn); +delete from t1; +unlock tables; +drop table t1; +set timestamp= default; + +--echo # +--echo # MDEV-25546 LIMIT partitioning does not respect ROLLBACK +--echo # +create or replace table t1 (pk int primary key) +with system versioning engine innodb +partition by system_time limit 100 ( + partition p0 history, + partition p1 history, + partition pn current); +insert into t1 select seq from seq_1_to_90; + +start transaction; +# Puts 80 rows into p0 +replace into t1 select seq from seq_1_to_80; +# Puts another 70 rows into p0 +replace into t1 select seq from seq_1_to_70; +# Puts 60 rows into p1 +replace into t1 select seq from seq_1_to_60; + +select partition_name, table_rows +from information_schema.partitions +where table_name = 't1'; +rollback; + +select partition_name, table_rows +from information_schema.partitions +where table_name = 't1'; + +# Should put 10 rows into the empty partition p0 +replace into t1 select seq from seq_1_to_10; +select partition_name, table_rows +from information_schema.partitions +where table_name = 't1'; + # Cleanup +drop table t1; + +--echo # +--echo # MDEV-28271 Assertion on TRUNCATE PARTITION for PARTITION BY SYSTEM_TIME +--echo # +create table t1 (x int) with system versioning +partition by system_time limit 1 ( + partition p0 history, + partition p1 history, + partition p2 history, # p2 just disables warning about p1 partition full + partition pn current); + +insert into t1 values (0); +update t1 set x= x + 1; +update t1 set x= x + 1; + +select * from t1 partition (p0); +select * from t1 partition (p1); +select * from t1 partition (pn); + +delete from t1; +delete history from t1; +select * from t1 partition (p0); +select * from t1 partition (p1); +select * from t1 partition (pn); + +insert into t1 values (0); +update t1 set x= x + 1; +update t1 set x= x + 1; + +--echo # TRUNCATE PARTITION ALL does the same +alter table t1 truncate partition all; +select * from t1 partition (p0); +select * from t1 partition (p1); +select * from t1 partition (pn); + +insert into t1 values (0); +update t1 set x= x + 1; +update t1 set x= x + 1; + +--echo # TRUNCATE PARTITION deletes data from HISTORY partition +alter table t1 truncate partition p1; +select * from t1 partition (p0); +select * from t1 partition (p1); +select * from t1 partition (pn); + +--echo # or from CURRENT partition +alter table t1 truncate partition pn; +select * from t1 partition (p0); +select * from t1 partition (p1); +select * from t1 partition (pn); + +drop table t1; + +--echo # +--echo # MDEV-20077 Warning on full history partition is delayed until next DML statement +--echo # +--echo # DELETE +create table t1 (x int) with system versioning +partition by system_time limit 100 ( + partition p0 history, + partition p1 history, + partition pn current); + +insert into t1 select seq from seq_0_to_200; + +--echo # p0 is filled with 100 records (no warnings): +delete from t1 where x <= 99; +--echo # p1 is filled with 1 + 100 records (warning is printed): +delete from t1 where x <= 100; +delete from t1; +--echo # You see warning above ^ + +select count(*) from t1 partition (p0); +select count(*) from t1 partition (p1); +drop table t1; + +--echo # DELETE under LOCK TABLES +create table t1 (x int) with system versioning +partition by system_time limit 100 ( + partition p0 history, + partition p1 history, + partition pn current); + +insert into t1 select seq from seq_0_to_200; + +lock tables t1 write; +--echo # (LOCK TABLES) p0 is filled with 100 records (no warnings): +delete from t1 where x <= 99; +--echo # (LOCK TABLES) p1 is filled with 1 + 100 records (warning is printed): +delete from t1 where x <= 100; +delete from t1; +--echo # You see warning above ^ +unlock tables; + +select count(*) from t1 partition (p0); +select count(*) from t1 partition (p1); +drop table t1; + +--echo # DELETE multitable +create table t1 (x int) with system versioning +partition by system_time limit 100 ( + partition p0 history, + partition p1 history, + partition pn current); + +create table t2 (y int); + +insert into t1 select seq from seq_0_to_200; +insert into t2 select seq from seq_0_to_3; +delete t1, t2 from t1 join t2 where x < 50 and y = 0; +delete t1, t2 from t1 join t2 where x < 100 and y = 1; +delete t1, t2 from t1 join t2 where x < 150 and y = 2; +delete t1, t2 from t1 join t2; +--echo # You see warning above ^ + +select count(*) from t1 partition (p0); +select count(*) from t1 partition (p1); +drop table t1; + +--echo # UDPATE +create table t1 (x int) with system versioning +partition by system_time limit 100 ( + partition p0 history, + partition p1 history, + partition pn current); + +insert into t1 select seq from seq_0_to_49; + +update t1 set x= x + 1; +update t1 set x= x + 1; +update t1 set x= x + 1; +update t1 set x= x + 1; +--echo # You see warning above ^ + +select count(*) from t1 partition (p0); +select count(*) from t1 partition (p1); +drop tables t1, t2; + +--echo # UPDATE multitable +create table t1 (x int) with system versioning +partition by system_time limit 100 ( + partition p0 history, + partition p1 history, + partition pn current); + +create table t2 (y int); + +insert into t1 select seq from seq_0_to_49; +insert into t2 values (5); + +update t1, t2 set x= x + 1; +update t1, t2 set x= x + 1; +update t1, t2 set x= x + 1; +update t1, t2 set x= x + 1; +--echo # You see warning above ^ + +select count(*) from t1 partition (p0); +select count(*) from t1 partition (p1); +drop tables t1, t2; + +--echo # INSERT .. ON DUPLICATE KEY UPDATE (ODKU) +create table t1 (x int primary key) with system versioning +partition by system_time limit 100 ( + partition p0 history, + partition p1 history, + partition pn current); + +insert into t1 select seq from seq_0_to_100; + +delete from t1 where x <= 99; +insert into t1 values (100) on duplicate key update x= 400; + +select count(*) from t1 partition (p0); +select count(*) from t1 partition (p1); +drop table t1; + +--echo # INSERT .. SELECT .. ON DUPLICATE KEY UPDATE (ODKU) +create table t1 (x int primary key) with system versioning +partition by system_time limit 100 ( + partition p0 history, + partition p1 history, + partition pn current); + +create table t2 (y int); +insert into t2 values (100); +insert into t1 select seq from seq_0_to_100; + +delete from t1 where x <= 99; +insert into t1 select * from t2 on duplicate key update x= 500; + +select count(*) from t1 partition (p0); +select count(*) from t1 partition (p1); +drop tables t1, t2; + +--echo # REPLACE +create table t1 (x int primary key) with system versioning +partition by system_time limit 100 ( + partition p0 history, + partition p1 history, + partition pn current); + +insert into t1 select seq from seq_0_to_100; + +delete from t1 where x < 99; +replace t1 values (100); +replace t1 values (100); + +select count(*) from t1 partition (p0); +select count(*) from t1 partition (p1); +drop table t1; + +--echo # LOAD DATA .. REPLACE +create table t1 (x int primary key) with system versioning +partition by system_time limit 100 ( + partition p0 history, + partition p1 history, + partition pn current); + +insert into t1 select seq from seq_0_to_49; +--disable_ps2_protocol +select x into outfile 'MDEV-20077.data' from t1; +--enable_ps2_protocol + +load data infile 'MDEV-20077.data' replace into table t1 (x); +load data infile 'MDEV-20077.data' replace into table t1 (x); +load data infile 'MDEV-20077.data' replace into table t1 (x); +load data infile 'MDEV-20077.data' replace into table t1 (x); +--echo # You see warning above ^ + +select count(*) from t1 partition (p0); +select count(*) from t1 partition (p1); +drop table t1; +--remove_file $datadir/test/MDEV-20077.data + +--echo # REPLACE .. SELECT +create table t1 (x int primary key) with system versioning +partition by system_time limit 100 ( + partition p0 history, + partition p1 history, + partition pn current); + +insert into t1 select seq from seq_0_to_49; +replace t1 select * from t1; +replace t1 select * from t1; +replace t1 select * from t1; +replace t1 select * from t1; +--echo # You see warning above ^ + +select count(*) from t1 partition (p0); +select count(*) from t1 partition (p1); +drop table t1; + +--echo # +--echo # MDEV-28552 Assertion `inited==RND' failed in handler::ha_rnd_end +--echo # +create table tcount (c int unsigned); +insert into tcount values (0); + +create table t (f int) with system versioning +partition by system_time limit 1000 +(partition p1 history, partition pn current); +insert into t values (1),(2); +create trigger tr before insert on t for each row update tcount set c = c + 1; + +insert into t select * from t; + +# cleanup +drop table tcount, t; + +--echo # +--echo # MDEV-19569 Assertion `table_list->table' failed in find_field_in_table_ref and Assertion `table_ref->table || table_ref->view' in Field_iterator_table_ref::set_field_iterator +--echo # +set timestamp=unix_timestamp('2000-01-01 00:00:00'); +create table t1 (i int); +create table t2 (i int); + +--error ER_SUBQUERIES_NOT_SUPPORTED +alter table t1 partition by system_time + interval (select i from t2) day (partition p1 history, partition pn current); + +drop table t1; + +--error ER_SUBQUERIES_NOT_SUPPORTED +create table t1 (id int) with system versioning + partition by system_time + interval (select i from t2) day (partition p1 history, partition pn current); + +--error ER_PART_WRONG_VALUE +create table t1 (id int) with system versioning + partition by system_time + interval "hello" day (partition p1 history, partition pn current); + +create table t1 (id int) with system versioning + partition by system_time + interval 3.893 day (partition p1 history, partition pn current); + +drop table t1, t2; + +create table t1 (id int) with system versioning + partition by system_time interval "3-11" year_month (partition p1 history, partition pn current); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +drop table t1; + +create table t1 (id int) with system versioning + partition by system_time interval "3 11" day_hour (partition p1 history, partition pn current); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +drop table t1; + +create table t1 (id int) with system versioning + partition by system_time interval "3 11:12" day_minute (partition p1 history, partition pn current); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +drop table t1; + +create table t1 (id int) with system versioning + partition by system_time interval "3 11:12:13" day_second (partition p1 history, partition pn current); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +drop table t1; + +create table t1 (id int) with system versioning + partition by system_time interval "11:12" hour_minute (partition p1 history, partition pn current); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +drop table t1; + +create table t1 (id int) with system versioning + partition by system_time interval "11:12:13" hour_second (partition p1 history, partition pn current); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +drop table t1; + +create table t1 (id int) with system versioning + partition by system_time interval "12:13" minute_second (partition p1 history, partition pn current); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +drop table t1; + +--error ER_PART_WRONG_VALUE +create table t1 (id int) with system versioning + partition by system_time interval "12:13.123" minute_microsecond (partition p1 history, partition pn current); + +--echo # +--echo # End of 10.3 tests +--echo # + +--echo # +--echo # MDEV-22283 Server crashes in key_copy or unexpected error 156: The table already existed in the storage engine +--echo # +create table t1 (a int primary key) engine=aria page_checksum=0 +with system versioning +partition by system_time (partition p1 history, partition pn current); + +alter table t1 add partition (partition p2 history); +show table status; +drop table t1; + +create table t1 (b int) engine=aria row_format=dynamic with system versioning +partition by system_time (partition p1 history, partition pn current); +insert into t1 values (1); +replace into t1 values (1); + +# cleanup +drop table t1; + +--echo # +--echo # MDEV-18794 Assertion `!m_innodb' failed in ha_partition::cmp_ref upon SELECT from partitioned table +--echo # +create or replace table t1 (pk int auto_increment, i int, c char(1), primary key (pk), key(i)) +engine=innodb with system versioning partition by key() partitions 2; +insert into t1 (i, c) values (1, 'a'), (2, 'b'), (null, 'c'), (null, 'b'); +alter table t1 drop system versioning; +replace into t1 select * from t1; +select * from t1 where i > 0 or pk = 1000 limit 1; +drop table t1; + +--echo # +--echo # End of 10.4 tests +--echo # + +--echo # +--echo # MDEV-22153 ALTER add default history partitions makes table inaccessible +--echo # +create or replace table t1 (x int) with system versioning partition by system_time; +alter table t1 add partition partitions 1; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +alter table t1 add partition partitions 2; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +alter table t1 add partition partitions 3; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +drop tables t1; + +--echo # +--echo # MDEV-22207 Drop default history partitions renders table inaccessible +--echo # +create or replace table t1 (i int) with system versioning +partition by system_time limit 1 partitions 5; + +alter table t1 drop partition p0, p2; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +alter table t1 add partition partitions 1; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +drop tables t1; + +--echo # +--echo # MDEV-22155 ALTER add default history partitions name clash on non-default partitions +--echo # +set timestamp= default; +create or replace table t1 (x int) with system versioning +partition by system_time limit 1 +(partition p2 history, partition p8 history, partition pn current); +alter table t1 add partition partitions 1; +alter table t1 add partition partitions 2; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +alter table t1 add partition partitions 8; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +drop tables t1; + +--echo # +--echo # MDEV-27328 Change of SYSTEM_TIME partitioning options is not possible without data copy +--echo # +create or replace table t1 (f int) with system versioning +partition by hash(f); +alter table t1 partition by system_time; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +create or replace table t1 (f int) with system versioning +partition by system_time; +alter table t1 partition by hash(f); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +create or replace table t1 (x int) with system versioning; +alter table t1 partition by system_time; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +create or replace table t1 (x int) with system versioning +partition by system_time limit 100 partitions 4; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +alter table t1 add partition partitions 2; +alter table t1 partition by system_time; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +alter table t1 partition by system_time limit 33; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +insert t1 values (0); +set timestamp= unix_timestamp('2000-01-01 00:10:00'); +update t1 set x= x + 1; +set timestamp= unix_timestamp('2000-01-01 01:00:00'); +update t1 set x= x + 1; +set timestamp= unix_timestamp('2000-01-01 01:30:00'); +update t1 set x= x + 1; +set timestamp= unix_timestamp('2000-01-01 02:00:00'); +update t1 set x= x + 1; + +# When we switch to INTERVAL we must reorganize partitions. +# Otherwise pruning won't work correctly. +alter table t1 partition by system_time interval 1 hour +starts '2000-01-01 00:00:00'; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +select * from t1 partition (p0); +select * from t1 partition (p1); +select * from t1 partition (p2); +select * from t1 partition (pn); +set timestamp= default; + +# When we switch to LIMIT we probably don't want to reorganize old partitions. +# Note: reorganize for LIMIT is broken, it pushes all history into first partition. +# TODO: MDEV-27337 +alter table t1 partition by system_time limit 1; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +update t1 set x= x + 1; +update t1 set x= x + 1; +--echo # You see warning above ^ +select * from t1 partition (p0); +select * from t1 partition (p1); +select * from t1 partition (p2); +select * from t1 partition (p3); +select * from t1 partition (p4); +select * from t1 partition (pn); + +drop table t1; + +--echo # End of 10.6 tests + +--echo # +--echo # MDEV-22166 MIGRATE PARTITION: move out partition into a table +--echo # +create or replace table t1 (x int) +with system versioning +partition by range(x) ( + partition p1 values less than (10), + partition p2 values less than (20), + partition p3 values less than (30), + partition p4 values less than (40), + partition p5 values less than (50), + partition pn values less than maxvalue); + +insert into t1 values (2), (12), (22), (32), (42), (52); +update t1 set x= x + 1; + +alter table t1 convert partition p2 to table tp2; +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table tp2; +select * from tp2; +select * from tp2 for system_time all order by x; + +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table t1; +select * from t1 order by x; +select * from t1 for system_time all order by x; + +--echo # SP +create or replace procedure sp() +alter table t1 convert partition p3 to table tp3; +call sp; +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table tp3; +select * from tp3; +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table t1; +select * from t1 order by x; +drop table tp3; +--error ER_PARTITION_DOES_NOT_EXIST +call sp; +--error ER_PARTITION_DOES_NOT_EXIST +call sp; +drop procedure sp; + +--echo # LOCK TABLES, PS, SP +create or replace procedure sp() +alter table t1 convert partition p4 to table tp4; +lock tables t1 write; +prepare stmt from 'call sp'; +execute stmt; + +# TODO: don't unlock here (see above TODO) +unlock tables; +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table tp4; +select * from tp4; +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table t1; +select * from t1 order by x; +drop table tp4; +lock tables t1 write; +--error ER_PARTITION_DOES_NOT_EXIST +execute stmt; +--error ER_PARTITION_DOES_NOT_EXIST +call sp; +drop prepare stmt; +unlock tables; +drop procedure sp; +unlock tables; + +drop tables t1, tp2; + +--echo # System-versioned tables (SYSTEM_TIME LIMIT) + +create or replace table t1 ( + x 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 +partition by system_time limit 1 partitions 4; + +insert into t1 values (2), (12), (22); +update t1 set x= x + 1 where x = 2; +update t1 set x= x + 1 where x = 12; +update t1 set x= x + 1 where x = 22; + +select * from t1 partition (p1); +--error ER_VERS_WRONG_PARTS +alter table t1 convert partition pn to table tp1; +alter table t1 convert partition p1 to table tp1; + +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table tp1; +select * from tp1; +select * from tp1 for system_time all; + +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table t1; +select * from t1 order by x; +select * from t1 for system_time all order by x; + +drop tables t1, tp1; + +--echo # System-versioned tables (SYSTEM_TIME INTERVAL) + +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create or replace table t1 ( + x 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 +partition by system_time interval 1 hour partitions 4; + +insert into t1 values (2), (12), (22); +set timestamp= unix_timestamp('2000-01-01 00:00:01'); +update t1 set x= x + 1 where x = 2; +set timestamp= unix_timestamp('2000-01-01 01:00:00'); +update t1 set x= x + 1 where x = 12; +set timestamp= unix_timestamp('2000-01-01 02:00:00'); +update t1 set x= x + 1 where x = 22; + +select * from t1 partition (p0); +select * from t1 partition (p1); +select * from t1 partition (p2); +--error ER_VERS_DROP_PARTITION_INTERVAL +alter table t1 convert partition p1 to table tp1; +alter table t1 convert partition p0 to table tp0; +alter table t1 convert partition p1 to table tp1; +--error ER_VERS_WRONG_PARTS +alter table t1 convert partition p2 to table tp2; + +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table tp0; +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table tp1; +select * from tp0; +select * from tp1; +select * from tp0 for system_time all; +select * from tp1 for system_time all; + +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table t1; +select * from t1; +select * from t1 for system_time all order by x; + +drop tables t1, tp0, tp1; + +--echo # System-versioned tables (implicit) + +create or replace table t1(x int) with system versioning +partition by system_time limit 1 partitions 3; + +alter table t1 convert partition p1 to table tp1; +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table tp1; +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table t1; + +drop tables t1, tp1; + +if (!$MTR_COMBINATION_HEAP) +{ +--echo # Complex table +create or replace table t1 ( + x int primary key auto_increment, + t timestamp(6) default '2001-11-11 11:11:11', + b blob(4096) compressed null, + c varchar(1033) character set utf8 not null, + u int, + unique key (x, u), + m enum('a', 'b', 'c') not null default 'a' comment 'absolute', + i1 tinyint, i2 smallint, i3 bigint, + index three(i1, i2, i3), + v1 timestamp(6) generated always as (t + interval 1 day), + v2 timestamp(6) generated always as (t + interval 1 month) stored, + s timestamp(6) as row start, + e timestamp(6) as row end, + period for system_time (s, e), + ps date, pe date, + period for app_time (ps, pe), + constraint check_constr check (u > -1)) +with system versioning default charset=ucs2 +partition by range(x) ( + partition p0 values less than (10), + partition p1 values less than (20), + partition pn values less than maxvalue); + +alter table t1 convert partition p1 to table tp1; + +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table tp1; +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table t1; + +drop tables t1, tp1; +} + +--echo # +--echo # MDEV-29841 Partition by system_time can be converted into table but not back +--echo # +create or replace table t (a int) with system versioning +partition by system_time limit 10 partitions 3; +alter table t convert partition p0 to table tp; +--error ER_ONLY_ON_RANGE_LIST_PARTITION +alter table t convert table tp to partition p0; +drop tables t, tp; + +--echo # +--echo # End of 10.7 tests +--echo # + +--echo # +--echo # MDEV-17554 Auto-create new partition for system versioned tables +--echo # with history partitioned by INTERVAL/LIMIT +--echo # +create or replace table t1 (x int) with system versioning +partition by system_time limit 1 auto; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +--echo # Turn off AUTO +alter table t1 partition by system_time limit 1; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +--echo # Get AUTO back +alter table t1 partition by system_time limit 1 auto; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +insert into t1 values (1); + +create or replace table t2 (y int); +insert into t2 values (2); + +insert into t1 select * from t2; +insert into t2 select * from t1; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +--echo # Too many partitions error +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create or replace table t1 (x int) with system versioning +partition by system_time interval 1 hour auto; +set timestamp= unix_timestamp('2001-01-01 00:01:00'); +--error ER_VERS_HIST_PART_FAILED +update t1 set x= x + 1; +show warnings; + +--echo # Auto-create failed error +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create or replace table t1 (x int) with system versioning engine innodb +partition by system_time interval 1 hour auto; + +insert into t1 values (1); + +call mtr.add_suppression("rror number .*(File exists|file operation)"); +call mtr.add_suppression("InnoDB: Cannot create file"); + +--let $datadir= `select @@datadir` +--let $dummy= $datadir/test/t1#P#p1.ibd +--write_file $dummy +EOF + +set timestamp= unix_timestamp('2000-01-01 01:00:00'); +--error ER_GET_ERRNO +update t1 set x= x + 2; +show warnings; +--remove_file $dummy + +--echo # Partition overflow error and manual fix +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create or replace table t1 (x int) with system versioning +partition by system_time interval 1 hour; + +insert into t1 values (440); +set timestamp= unix_timestamp('2000-01-01 00:10:00'); +update t1 set x= x + 1; + +--echo # Check how pruning boundaries work +--replace_column 5 # 10 # 11 # +explain partitions select * from t1 for system_time as of '2000-01-01 00:59:58'; +--replace_column 5 # 10 # 11 # +explain partitions select * from t1 for system_time as of '2000-01-01 00:59:59'; +--replace_column 5 # 10 # 11 # +explain partitions select * from t1 for system_time as of '2000-01-01 01:00:00'; +select * from t1 for system_time as of '2000-01-01 00:09:59'; + +set timestamp= unix_timestamp('2000-01-01 02:00:00'); +update t1 set x= x + 1; + +select * from t1 for system_time as of '2000-01-01 01:00:00'; +select * from t1 partition (p0) order by x; + +--echo # Here is how manual fix works: just add new partitions there +alter table t1 add partition partitions 3; +select * from t1 for system_time as of '2000-01-01 01:00:00'; +select * from t1 partition (p0) order by x; + +--echo # Check pruning after ALTER +--replace_column 5 # 10 # 11 # +explain partitions select * from t1 for system_time as of '2000-01-01 00:59:58'; +--replace_column 5 # 10 # 11 # +explain partitions select * from t1 for system_time as of '2000-01-01 00:59:59'; +--replace_column 5 # 10 # 11 # +explain partitions select * from t1 for system_time as of '2000-01-01 01:00:00'; + +drop table t1; + +--enable_info +create or replace table t1 (x int) with system versioning +partition by system_time interval 3600 second +starts '2000-01-01 00:00:00' auto partitions 3; + +insert into t1 values (1); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +set timestamp= unix_timestamp('2000-01-01 02:00:00'); +update t1 set x= x + 1; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +set timestamp= unix_timestamp('2000-01-01 03:00:00'); +update t1 set x= x + 2; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create or replace table t1 (x int) with system versioning +partition by system_time interval 1 hour auto ( + partition p1 history, + partition p3 history, + partition pn current); + +insert into t1 values (1); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +set timestamp= unix_timestamp('2000-01-01 02:00:00'); +update t1 set x= x + 3; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +set timestamp= unix_timestamp('2000-01-01 03:00:00'); +update t1 set x= x + 4; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +set timestamp= unix_timestamp('2000-01-01 04:00:00'); +lock tables t1 write; +update t1 set x= x + 5; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +unlock tables; +set timestamp= default; + +--echo # Couple of more LOCK TABLES cases +create or replace table t1 (x int) with system versioning +partition by system_time limit 1 auto; +lock tables t1 write; +insert into t1 values (1); +update t1 set x= x + 1; +update t1 set x= x + 2; +update t1 set x= x + 3; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +unlock tables; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +--echo # Overflow prevention under LOCK TABLES +create or replace table t1 (x int) +with system versioning partition by system_time +limit 10 auto; + +insert into t1 values (1), (2), (3), (4), (5), (6), (7), (8), (9); +update t1 set x= x + 10; + +lock tables t1 write; +update t1 set x= 1 where x = 11; +update t1 set x= 2 where x = 12; +update t1 set x= 3 where x = 13; +unlock tables; + +select count(x) from t1 partition (p0); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +drop tables t1; + +--echo # Test VIEW, LOCK TABLES +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create or replace table t1 (x int) with system versioning +partition by system_time interval 1 hour auto; +create or replace view v1 as select * from t1; + +insert into t1 values (1); +set timestamp= unix_timestamp('2000-01-01 01:00:00'); +update v1 set x= x + 2; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +set timestamp= unix_timestamp('2000-01-01 02:00:00'); +lock tables v1 write; +update v1 set x= x + 3; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +unlock tables; + +drop view v1; +drop tables t1; + +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create or replace table t1 (x int) with system versioning +partition by system_time interval 1 hour auto partitions 3; + +create or replace table t2 (y int) with system versioning +partition by system_time interval 1 hour auto; + +insert into t1 values (1); +insert into t2 values (2); + +set timestamp= unix_timestamp('2000-01-01 01:00:00'); +update t1, t2 set x= x + 1, y= y + 1; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +--replace_result $default_engine DEFAULT_ENGINE +show create table t2; + +set timestamp= unix_timestamp('2000-01-01 02:00:00'); +update t1, t2 set x= x + 1, y= y + 1; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +--replace_result $default_engine DEFAULT_ENGINE +show create table t2; + +set timestamp= unix_timestamp('2000-01-01 03:00:00'); +update t1, t2 set t1.x= 0 where t1.x< t2.y; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +# Multiupdate_prelocking_strategy::handle_end() is processed after table open. +# For PS it is possible to skip unneeded auto-creation because the above happens at +# prepare stage and auto-creation is done at execute stage. +--replace_result $default_engine DEFAULT_ENGINE 'PARTITIONS 4' 'PARTITIONS ok' 'PARTITIONS 5' 'PARTITIONS ok' +show create table t2; + +drop tables t1, t2; + +--echo # PS, SP, LOCK TABLES +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create or replace table t1 (x int) with system versioning +partition by system_time interval 1 hour auto; + +insert into t1 values (1); + +set timestamp= unix_timestamp('2000-01-01 01:00:00'); +execute immediate 'update t1 set x= x + 5'; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +prepare s from 'update t1 set x= x + 6'; +set timestamp= unix_timestamp('2000-01-01 02:00:00'); +execute s; execute s; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +set timestamp= unix_timestamp('2000-01-01 03:00:00'); +lock tables t1 write; +execute s; execute s; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +unlock tables; +drop prepare s; + +create procedure sp() update t1 set x= x + 7; +set timestamp= unix_timestamp('2000-01-01 04:00:00'); +call sp; call sp; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +set timestamp= unix_timestamp('2000-01-01 05:00:00'); +lock tables t1 write; +call sp; call sp; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +unlock tables; +drop procedure sp; + +set timestamp= unix_timestamp('2001-01-01 00:00:00'); +create or replace table t1 (i int) with system versioning +partition by system_time interval 1 day starts '2001-01-01 00:00:00'; +insert into t1 values (0); +set timestamp= unix_timestamp('2001-01-01 00:00:01'); +prepare s from 'update t1 set i= i + 1'; +execute s; +set timestamp= unix_timestamp('2001-01-02 00:00:01'); +execute s; +drop prepare s; + +# Because of blobs: +if (!$MTR_COMBINATION_HEAP) +{ +--echo # Complex table +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create or replace table t1 ( + x int primary key auto_increment, + t timestamp(6) default '2001-11-11 11:11:11', + b blob(4096) compressed null, + c varchar(1033) character set utf8 not null, + u int unique, + m enum('a', 'b', 'c') not null default 'a' comment 'absolute', + i1 tinyint, i2 smallint, i3 bigint, + index three(i1, i2, i3), + v1 timestamp(6) generated always as (t + interval 1 day), + v2 timestamp(6) generated always as (t + interval 1 month) stored, + s timestamp(6) as row start, + e timestamp(6) as row end, + period for system_time (s, e), + ps date, pe date, + period for app_time (ps, pe), + constraint check_constr check (u > -1)) +with system versioning default charset=ucs2 +partition by system_time interval 1 hour auto ( + partition p2 history, + partition pn current); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +insert into t1 (x, c, u, i1, i2, i3, ps, pe) +values (1, 'cc', 0, 1, 2, 3, '1999-01-01', '2000-01-01'); +set timestamp= unix_timestamp('2000-01-01 01:00:00'); +update t1 set x= x + 8; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +set timestamp= unix_timestamp('2000-01-01 02:00:00'); +update t1 set x= x - 8; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +} +--disable_info + +--echo # INSERT .. ON DUPLICATE KEY UPDATE (ODKU) +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create or replace table t1 (x int primary key) with system versioning +partition by system_time interval 1 hour auto; +insert into t1 values (1); +set timestamp= unix_timestamp('2000-01-01 01:00:00'); +insert into t1 values (1) on duplicate key update x= x + 1; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +--echo # LOAD DATA .. REPLACE +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create or replace table t1 (x int primary key) with system versioning +partition by system_time interval 1 hour auto; + +insert t1 values (1), (2), (3); +--disable_ps2_protocol +select x into outfile 'MDEV-17554.data' from t1; +--enable_ps2_protocol + +set timestamp= unix_timestamp('2000-01-01 01:00:00'); +load data infile 'MDEV-17554.data' replace into table t1 (x); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +--remove_file $datadir/test/MDEV-17554.data + +--echo # Concurrent DML +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create or replace table t1 (x int) with system versioning +partition by system_time interval 1 hour auto partitions 3; + +insert into t1 values (1); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +--connect con8, localhost, root +--connect con7, localhost, root +--connect con6, localhost, root +--connect con5, localhost, root +--connect con4, localhost, root +--connect con3, localhost, root +--connect con2, localhost, root +--connect con1, localhost, root +set timestamp= unix_timestamp('2000-01-01 02:00:00'); +send update t1 set x= x + 10; +--connection con2 +set timestamp= unix_timestamp('2000-01-01 02:00:00'); +send update t1 set x= x + 20; +--connection con3 +set timestamp= unix_timestamp('2000-01-01 02:00:00'); +send update t1 set x= x + 30; +--connection con4 +set timestamp= unix_timestamp('2000-01-01 02:00:00'); +send update t1 set x= x + 40; +--connection con5 +set timestamp= unix_timestamp('2000-01-01 02:00:00'); +send update t1 set x= x + 50; +--connection con6 +set timestamp= unix_timestamp('2000-01-01 02:00:00'); +send update t1 set x= x + 60; +--connection con7 +set timestamp= unix_timestamp('2000-01-01 02:00:00'); +send update t1 set x= x + 70; +--connection con8 +set timestamp= unix_timestamp('2000-01-01 02:00:00'); +update t1 set x= x + 80; +--connection con1 +reap; +--disconnect con1 +--connection con2 +reap; +--disconnect con2 +--connection con3 +reap; +--disconnect con3 +--connection con4 +reap; +--disconnect con4 +--connection con5 +reap; +--disconnect con5 +--connection con6 +reap; +--disconnect con6 +--connection con7 +reap; +--disconnect con7 +--disconnect con8 +--connection default +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +drop tables t1; +set timestamp= default; + +--echo # Concurrent DML (LIMIT) +create or replace table t1 (x int) with system versioning engine heap +partition by system_time limit 1 auto partitions 3; + +insert into t1 values (1); + +--let $max_loop= 3 +# For more intensity use +# --let $max_loop= 30 +--echo update t1 set x= x + N; # (running multithreaded for $max_loop times) +--disable_query_log +--disable_result_log +--connect con9, localhost, root +--connect con10, localhost, root +--connect con11, localhost, root +--connect con12, localhost, root +--connect con13, localhost, root +--connect con14, localhost, root +--connect con15, localhost, root +--connect con16, localhost, root +--connect con17, localhost, root +--connect con18, localhost, root +--connect con19, localhost, root +--connect con20, localhost, root +--connect con8, localhost, root +--connect con7, localhost, root +--connect con6, localhost, root +--connect con5, localhost, root +--connect con4, localhost, root +--connect con3, localhost, root +--connect con2, localhost, root +--connect con1, localhost, root +--let $i= 0 +while ($i < $max_loop) +{ + --connection con1 + send update t1 set x= x + 100; + --connection con2 + send update t1 set x= x + 200; + --connection con3 + send update t1 set x= x + 300; + --connection con4 + send update t1 set x= x + 400; + --connection con5 + send update t1 set x= x + 500; + --connection con6 + send update t1 set x= x + 600; + --connection con7 + send update t1 set x= x + 700; + --connection con8 + send update t1 set x= x + 800; + --connection con9 + send update t1 set x= x + 900; + --connection con10 + send update t1 set x= x + 1000; + --connection con11 + send update t1 set x= x + 1100; + --connection con12 + send update t1 set x= x + 1200; + --connection con13 + send update t1 set x= x + 1300; + --connection con14 + send update t1 set x= x + 1400; + --connection con15 + send update t1 set x= x + 1500; + --connection con16 + send update t1 set x= x + 1600; + --connection con17 + send update t1 set x= x + 1700; + --connection con18 + send update t1 set x= x + 1800; + --connection con19 + send update t1 set x= x + 1900; + --connection con20 + send update t1 set x= x + 2000; + --connection con1 + reap; + --connection con2 + reap; + --connection con3 + reap; + --connection con4 + reap; + --connection con5 + reap; + --connection con6 + reap; + --connection con7 + reap; + --connection con8 + reap; + --connection con9 + reap; + --connection con10 + reap; + --connection con11 + reap; + --connection con12 + reap; + --connection con13 + reap; + --connection con14 + reap; + --connection con15 + reap; + --connection con16 + reap; + --connection con17 + reap; + --connection con18 + reap; + --connection con19 + reap; + --connection con20 + reap; + --inc $i +} + +--disconnect con1 +--disconnect con2 +--disconnect con3 +--disconnect con4 +--disconnect con5 +--disconnect con6 +--disconnect con7 +--disconnect con8 +--disconnect con9 +--disconnect con10 +--disconnect con11 +--disconnect con12 +--disconnect con13 +--disconnect con14 +--disconnect con15 +--disconnect con16 +--disconnect con17 +--disconnect con18 +--disconnect con19 +--disconnect con20 + +--connection default +# Result is undeterministic under LIMIT concurrency (MDEV-28459) +# show create table t1; + +--enable_query_log +--enable_result_log + +drop tables t1; + +--echo # Transaction +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create or replace table t1 (x int) with system versioning engine innodb +partition by system_time interval 1 hour auto; + +insert into t1 values (1); +set timestamp= unix_timestamp('2000-01-01 01:00:00'); +start transaction; +update t1 set x= 0; +--connect con1, localhost, root +select * from t1; +show create table t1; +--connection default +commit; +show create table t1; + +set timestamp= unix_timestamp('2000-01-01 02:00:00'); +start transaction; +update t1 set x= 1; +--connection con1 +select * from t1; +--connection default +rollback; +show create table t1; +--disconnect con1 +--connection default +drop table t1; + +--echo # +--echo # MDEV-25479 Auto-create: 2nd and further executions of PS or SP fail to create partition +--echo # +create table t (a int) with system versioning + partition by system_time interval 1 hour auto; + +insert into t values (1), (2); +prepare stmt from "update t set a= a + 1"; +set @@timestamp= @@timestamp + 3601; +execute stmt; +set @@timestamp= @@timestamp + 3601; +execute stmt; +drop prepare stmt; +--replace_result $default_engine DEFAULT_ENGINE +show create table t; + +create procedure sp() update t set a= a + 1; +set @@timestamp= @@timestamp + 3601; +call sp(); +set @@timestamp= @@timestamp + 3601; +call sp(); +drop procedure sp; +--replace_result $default_engine DEFAULT_ENGINE +show create table t; + +# Cleanup +drop table t; + +--echo # +--echo # MDEV-23639 Auto-create does not work under LOCK TABLES or inside triggers +--echo # +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create or replace table t1 (x int) with system versioning +partition by system_time interval 1 hour auto +partitions 3; + +create table t2 (x int); +create table t3 (x int); +insert into t3 values (3); + +create trigger tr after insert on t2 for each row update t1 set x= x + 11; +create or replace procedure sp() update t1 set x= x + 5; +create or replace procedure sp2() insert into t2 values (5); +prepare ps from 'update t1 set x= x + 6'; +prepare ps2 from 'insert into t2 values (6)'; + +insert into t1 values (1); +set timestamp= unix_timestamp('2000-01-01 02:00:00'); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +insert into t2 values (2); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +set timestamp= unix_timestamp('2000-01-01 03:00:00'); +call sp; call sp; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +set timestamp= unix_timestamp('2000-01-01 04:00:00'); +call sp2; call sp2; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +set timestamp= unix_timestamp('2000-01-01 05:00:00'); +execute ps; execute ps; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +set timestamp= unix_timestamp('2000-01-01 06:00:00'); +execute ps2; execute ps2; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +set timestamp= unix_timestamp('2000-01-01 08:00:00'); +lock tables t1 write, t2 write; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +set timestamp= unix_timestamp('2000-01-01 09:00:00'); +update t1 set x= x + 1; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +set timestamp= unix_timestamp('2000-01-01 10:00:00'); +update t1 set x= x + 2; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +update t2 set x= x + 1; +set timestamp= unix_timestamp('2000-01-01 11:00:00'); +insert into t2 values (4); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +--error ER_TABLE_NOT_LOCKED +update t3 set x= x + 1; + +set timestamp= unix_timestamp('2000-01-01 12:00:00'); +call sp; call sp; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +set timestamp= unix_timestamp('2000-01-01 13:00:00'); +call sp2; call sp2; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +set timestamp= unix_timestamp('2000-01-01 14:00:00'); +execute ps; execute ps; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +set timestamp= unix_timestamp('2000-01-01 15:00:00'); +execute ps2; execute ps2; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +unlock tables; +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + +# Cleanup +drop tables t1, t2, t3; +drop procedure sp; +drop procedure sp2; +drop prepare ps; +drop prepare ps2; + +--echo # +--echo # MDEV-27456 Assertion `!thd->is_error()' fails in vers_create_partitions upon DML with ER_UNKNOWN_PARTITION +--echo # +create table t (a int) with system versioning +partition by system_time interval 1 minute auto; +set @@timestamp= @@timestamp + 61; +select * from t; +--error ER_UNKNOWN_PARTITION +delete from t partition (px); +lock tables t write; +--error ER_UNKNOWN_PARTITION +delete from t partition (px); +unlock tables; +drop table t; +set timestamp= default; + +--echo # +--echo # MDEV-28978 Assertion failure in THD::binlog_query or unexpected +--echo # ER_ERROR_ON_WRITE with auto-partitioning +--echo # +create table t (a int) with system versioning partition by system_time limit 6 auto; +insert into t () values (),(),(),(),(),(); +update t set a = 1; +update t set a = 2 limit 0; +# cleanup +drop table t; + +--echo # +--echo # MDEV-31244 Assertion "not SELECT" in vers_set_hist_part() +--echo # +create table t (a int) with system versioning partition by system_time; +--delimiter $ +create function f() returns int +begin + update t set a = 1; + return 1; +end $ +--delimiter ; +create procedure p() select f(); +call p(); +call p(); +# cleanup +drop procedure p; +drop function f; +drop table t; + +--echo # +--echo # MDEV-29873 MSAN uninitialized value errors in bcmp / +--echo # prep_alter_part_table upon re-partitioning by system time +--echo # +create table t (a int) with system versioning partition by system_time interval 5 week; +alter table t partition by system_time interval 10 week; +# cleanup +drop table t; + +--echo # +--echo # MDEV-16546 System versioning setting to allow history modification +--echo # +create table t1 (a varchar(100)) with system versioning +partition by system_time interval 1 day +starts '2021-09-30 00:00:00' partitions 3; +set system_versioning_insert_history=1; +insert into t1 (a,row_start,row_end) values +('p0', '2021-09-30', '2021-09-30 10:00:00'), +('p1', '2021-09-30', '2021-10-01 10:00:00'), +('overflows, so also p1','2021-09-30', '2021-10-10 10:00:00'), +('pn, current', '2021-09-30', '2038-01-19 03:14:07.999999'); +select table_name,partition_name,partition_ordinal_position,partition_method,partition_description,table_rows +from information_schema.partitions where table_schema='test'; +drop table t1; +set system_versioning_insert_history=0; + +--disable_prepare_warnings + +--echo # +--echo # MDEV-29727 ALTER and CREATE with default partitioning +--echo # differently react to SQL_MODE => unusable SHOW CREATE +--echo # +create table t (a int) with system versioning; +--error WARN_VERS_PARAMETERS +alter table t partition by system_time partitions 3; +drop table t; +--error WARN_VERS_PARAMETERS +create table t (a int) with system versioning partition by system_time partitions 3; + +--echo # +--echo # End of 10.5 tests +--echo # + +set global innodb_stats_persistent= @save_persistent; +--source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/t/replace.test b/mysql-test/suite/versioning/t/replace.test new file mode 100644 index 00000000..83489f4a --- /dev/null +++ b/mysql-test/suite/versioning/t/replace.test @@ -0,0 +1,80 @@ +--source suite/versioning/key_type.inc +if ($MTR_COMBINATION_SEC) +{ + --skip pk or unique only +} +--source suite/versioning/common.inc +--source suite/versioning/engines.inc + +--replace_result $sys_datatype_expl SYS_DATATYPE "$KEY_TYPE" KEY_TYPE +eval create or replace table t( + id int, + $KEY_TYPE(id), + x int, + row_start $sys_datatype_expl as row start invisible, + row_end $sys_datatype_expl as row end invisible, + period for system_time(row_start, row_end) +) with system versioning; + +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 table t; + +--replace_result $sys_datatype_expl SYS_DATATYPE +eval create table t ( + id int unique, + x int, + row_start $sys_datatype_expl as row start invisible, + row_end $sys_datatype_expl as row end invisible, + period for system_time (row_start, row_end) +) with system versioning; + +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 table t; + +--echo # MDEV-15645 Assertion `table->insert_values' failed in write_record upon REPLACE into a view with underlying versioned table +create or replace table t1 (a int, b int, primary key (a), unique(b)) with system versioning; +insert into t1 values (1,1); +create or replace table t2 (c int); +create or replace view v as select t1.* from t1 join t2; +replace into v (a, b) select a, b from t1; +drop view v; +drop tables t1, t2; + +--replace_result $sys_datatype_expl SYS_DATATYPE +eval CREATE TABLE t1 ( + pk INT AUTO_INCREMENT, + f INT, + row_start $sys_datatype_expl AS ROW START INVISIBLE, + row_end $sys_datatype_expl AS ROW END INVISIBLE, + PRIMARY KEY(pk), + UNIQUE(f), + PERIOD FOR SYSTEM_TIME(row_start, row_end) +) WITH SYSTEM VERSIONING; +INSERT INTO t1 () VALUES (),(),(),(),(),(); +UPDATE IGNORE t1 SET f = 1; +REPLACE t1 SELECT * FROM t1; +DROP TABLE t1; + +--echo # MDEV-22540 ER_DUP_ENTRY upon REPLACE or Assertion failed +set timestamp=1589245268.41934; +create table t1 (a int primary key) with system versioning; +insert into t1 values (1),(2); + +--connect (con1,localhost,root,,test) +set timestamp=1589245268.52093; +replace into t1 values (1),(2); + +--connection default +replace into t1 values (1),(2); + +--connection con1 +--error ER_DUP_ENTRY +replace into t1 values (1),(2); + +drop table t1; + +--source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/t/rpl.test b/mysql-test/suite/versioning/t/rpl.test new file mode 100644 index 00000000..c723751a --- /dev/null +++ b/mysql-test/suite/versioning/t/rpl.test @@ -0,0 +1,446 @@ +--source suite/versioning/engines.inc +--source include/have_partition.inc +--source suite/versioning/common.inc +--source include/master-slave.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; +--source suite/versioning/common.inc +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); +set @@session.time_zone='+00:00'; + +connection master; +CREATE TABLE t1 (x int) with system versioning; +insert into t1 values (1); +select * from t1 order by x; +delete from t1; +select * from t1 order by x; +select * from t1 for system_time all order by row_end, x; +sync_slave_with_master; +select * from t1 order by x; +select * from t1 for system_time all order by row_end, x; + +connection master; +insert into t1 values (2); +sync_slave_with_master; +select * from t1 order by x; + +connection master; +update t1 set x = 3; +sync_slave_with_master; +select * from t1 order by x; +select * from t1 for system_time all order by row_end, x; + +--echo # 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 order by x; +select * from t1 for system_time all order by row_end, x; + +connection master; +update t1 set x= 2 where x = 1; +sync_slave_with_master; +select * from t1 order by x; +select * from t1 for system_time all order by row_end, x; + +connection master; +delete from t1; +sync_slave_with_master; +select * from t1 order by x; +select * from t1 for system_time all order by row_end, x; + +--echo # 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 order by x; +select * from t1 for system_time all order by row_end, x; + +connection master; +delete from t1; +sync_slave_with_master; +select * from t1 order by x; +select * from t1 for system_time all order by row_end, x; + +--echo # 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 order by x; +select * from t2 order by x; +select * from t1 for system_time all order by row_end, x; +select * from t2 for system_time all order by row_end, x; + +--echo # MDEV-14767 system_versioning_alter_history breaks ALTER replication +--echo ## Case 1: KEEP on the master, ALTER will work on the slave +connection master; +create or replace table t1 (a int) with system versioning; +set system_versioning_alter_history= KEEP; +alter table t1 add column b int; +sync_slave_with_master; +--replace_result InnoDB ENGINE MyISAM ENGINE MEMORY ENGINE +show create table t1; + +--echo ## Case 2: ERROR on the master, it'll fail on the master, the slave won't see it +connection master; +set system_versioning_alter_history= ERROR; +--error ER_VERS_ALTER_NOT_ALLOWED +alter table t1 drop column b; +sync_slave_with_master; +--replace_result InnoDB ENGINE MyISAM ENGINE MEMORY ENGINE +show create table t1; + +--echo ## Case 3: table is not versioned on the master, ALTER will work on the slave +connection master; +create or replace table t1 (a int); +sync_slave_with_master; +create or replace table t1 (a int) with system versioning; +connection master; +alter table t1 add column b int; +sync_slave_with_master; +--replace_result InnoDB ENGINE MyISAM ENGINE MEMORY ENGINE +show create table t1; + +connection master; +drop table t1, t2; + +# +# MDEV-15395 Wrong result or Assertion `old_part_id == m_last_part' failed in ha_partition::update_row on slave +# +create table t1 (i int) with system versioning partition by system_time limit 8 ( partition p1 history, partition p2 history, partition pn current ); +insert into t1 values (1); +update t1 set i = 1; +update t1 set i = 0; +sync_slave_with_master; +connection master; +drop table t1; + + +# +# MDEV-30430: Enabling system versioning on tables without primary key breaks replication +# Note that bugs are only present with row binlog format +# +--echo # check versioned -> versioned replication without any keys on duplicate records +connection master; +create table t1 (a INT) with system versioning; +insert into t1 values (1); +insert into t1 values (1); +delete from t1; +sync_slave_with_master; +--let $diff_tables= master:test.t1,slave:test.t1 +--source include/diff_tables.inc +connection master; +drop table t1; +sync_slave_with_master; + +--echo # check unversioned -> versioned replication with non-unique keys on duplicate records +connection master; +set statement sql_log_bin=0 for create table t1 (a INT NOT NULL, b INT, INDEX(a,b)); +connection slave; +set statement sql_log_bin=0 for create table t1 (a INT NOT NULL, b INT, INDEX(a,b)) with system versioning; +connection master; +insert into t1 values (1,1); +insert into t1 values (1,1); +delete from t1; +sync_slave_with_master; +--let $diff_tables= master:test.t1,slave:test.t1 +--source include/diff_tables.inc + +connection master; +drop table t1; + +--echo # +--echo # MDEV-31313 SYSTEM VERSIONING and FOREIGN KEY CASCADE create orphan rows on replica +--echo # +create table parent ( + id int(11) not null auto_increment, + processdate datetime default null, + primary key (id) +) engine=innodb with system versioning; + +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +insert into parent values (1, now()); + +create table child ( + id int(11) not null auto_increment, + ch_name varchar(30), + andreid int(11) default null, + primary key (id), + key andreid (andreid), + constraint fk_andreid foreign key (andreid) references parent (id) on delete cascade +) engine=innodb with system versioning; + +set timestamp= unix_timestamp('2000-01-01 00:00:01'); +insert into child values (null, 'vimtomar', 1); + +set timestamp= unix_timestamp('2000-01-01 00:00:02'); +delete from parent where id = 1; + +select check_row(row_start, row_end) from parent for system_time all; +select check_row(row_start, row_end) from child for system_time all; +select * from child; +select * from parent; + +sync_slave_with_master; + +# Annoying tweaking of microseconds in slave row_end, so row_end can be <= row_start +select check_row_slave(row_start, row_end) from parent for system_time all; +select check_row_slave(row_start, row_end) from child for system_time all; +select * from child; +select * from parent; + +# Cleanup +--source suite/versioning/common_finish.inc +--connection master +set timestamp= default; +drop table child; +drop table parent; + +sync_slave_with_master; +connection master; + +--source suite/versioning/common_finish.inc +--echo # +--echo # MDEV-17554 Auto-create new partition for system versioned tables +--echo # with history partitioned by INTERVAL/LIMIT +--echo # +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create or replace table t1 (x int) with system versioning +partition by system_time interval 1 hour auto; +insert t1 values (); +set timestamp= unix_timestamp('2000-01-01 01:00:00'); +delete from t1; +--replace_result InnoDB ENGINE MyISAM ENGINE MEMORY ENGINE +show create table t1; +--sync_slave_with_master +--replace_result InnoDB ENGINE MyISAM ENGINE MEMORY ENGINE +show create table t1; +--connection master +drop table t1; +set timestamp= default; + +--echo # +--echo # MDEV-25477 Auto-create breaks replication when triggering event was not replicated +--echo # + +set timestamp= unix_timestamp('2001-01-01 01:00:00'); +--echo # ROLLBACK +create table t (a int) with system versioning +partition by system_time interval 1 hour auto; +insert into t values (1), (2); +set @@timestamp= @@timestamp + 3601; + +start transaction; +delete from t; +--disable_warnings +rollback; +# Warning: Some non-transactional changed tables couldn't be rolled back +--enable_warnings + +--replace_result InnoDB ENGINE MyISAM ENGINE MEMORY ENGINE +show create table t; +--sync_slave_with_master +--replace_result InnoDB ENGINE MyISAM ENGINE MEMORY ENGINE +show create table t; +--connection master +alter table t drop partition p0; +--sync_slave_with_master + +--echo # INSERT .. ODKU +--connection master +create or replace table t (a int primary key) with system versioning +partition by system_time interval 1 hour auto; +insert into t values (1), (2); + +set @@timestamp= @@timestamp + 3601; +insert into t values (1) on duplicate key update a= a; +--replace_result InnoDB ENGINE MyISAM ENGINE MEMORY ENGINE +show create table t; +--sync_slave_with_master +--replace_result InnoDB ENGINE MyISAM ENGINE MEMORY ENGINE +show create table t; +--connection master +alter table t drop partition p0; +--sync_slave_with_master + +--echo # INSERT .. SELECT .. ODKU +--connection master +create or replace table t (a int primary key) with system versioning +partition by system_time interval 1 hour auto; +insert into t values (1), (2); + +set @@timestamp= @@timestamp + 3601; +--disable_warnings +call mtr.add_suppression("Unsafe statement written to the binary log"); +insert t select a from t where a = 1 limit 0 on duplicate key update a= 1; +--enable_warnings +--replace_result InnoDB ENGINE MyISAM ENGINE MEMORY ENGINE +show create table t; +--sync_slave_with_master +--replace_result InnoDB ENGINE MyISAM ENGINE MEMORY ENGINE +show create table t; +--connection master +alter table t drop partition p0; +--sync_slave_with_master + +--echo # UPDATE +--connection master +create or replace table t (a int) with system versioning +partition by system_time interval 1 hour auto; +insert into t values (1), (2); + +set @@timestamp= @@timestamp + 3601; +update t set a= 3 limit 0; +--replace_result InnoDB ENGINE MyISAM ENGINE MEMORY ENGINE +show create table t; +--sync_slave_with_master +--replace_result InnoDB ENGINE MyISAM ENGINE MEMORY ENGINE +show create table t; +--connection master +alter table t drop partition p0; +--sync_slave_with_master + +--echo # DELETE +--connection master +create or replace table t (a int) with system versioning +partition by system_time interval 1 hour auto; +insert into t values (1), (2); + +set @@timestamp= @@timestamp + 3601; +delete from t limit 0; +--replace_result InnoDB ENGINE MyISAM ENGINE MEMORY ENGINE +show create table t; +--sync_slave_with_master +--replace_result InnoDB ENGINE MyISAM ENGINE MEMORY ENGINE +show create table t; +--connection master +alter table t drop partition p0; +--sync_slave_with_master + +--echo # Multi-update +--connection master +create or replace table t (a int) with system versioning +partition by system_time interval 1 hour auto; +create or replace table t2 (b int); + +insert into t values (0), (1); +insert into t2 values (10), (20); +set @@timestamp= @@timestamp + 3601; +# Note: limit 0 is not important for multi-update/delete because they work +# via mysql_select(). OTOH limit 0 makes unwanted "unsafe" warning. +update t left join t2 on a > b set a= 4; + +--replace_result InnoDB ENGINE MyISAM ENGINE MEMORY ENGINE +show create table t; +--sync_slave_with_master +--replace_result InnoDB ENGINE MyISAM ENGINE MEMORY ENGINE +show create table t; +--connection master +alter table t drop partition p0; +--sync_slave_with_master + +--echo # Multi-delete +--connection master +create or replace table t (a int) with system versioning +partition by system_time interval 1 hour auto; +create or replace table t2 (b int); + +insert into t values (0), (1); +insert into t2 values (10), (20); +set @@timestamp= @@timestamp + 3601; +delete t, t2 from t join t2 where a > b; + +--replace_result InnoDB ENGINE MyISAM ENGINE MEMORY ENGINE +show create table t; +--sync_slave_with_master +--replace_result InnoDB ENGINE MyISAM ENGINE MEMORY ENGINE +show create table t; +--connection master +alter table t drop partition p0; +--sync_slave_with_master + +--connection master +drop tables t, t2; +set timestamp= default; + + +--source suite/versioning/common.inc +--echo # +--echo # MDEV-16546 System versioning setting to allow history modification +--echo # +create table t1(x int) with system versioning; +insert into t1(x) values (1); +--error ER_BAD_FIELD_ERROR +insert into t1(x, row_start, row_end) values (2, '1980-01-01 00:00:00', '1980-01-01 00:00:01'); +set @@system_versioning_insert_history= 1; +insert into t1(x, row_start, row_end) values (3, '1980-01-01 00:00:00', '1980-01-01 00:00:01'); +update t1 set x= x + 1; +sync_slave_with_master; +set @@session.time_zone='+00:00'; +select x, check_row_ts(row_start, row_end) from t1 for system_time all order by x; +select row_start = '1980-01-01 00:00:00', row_end = '1980-01-01 00:00:01' from t1 for system_time all where x = 3; + +--echo ## INSERT..SELECT +connection master; +create or replace table t2 like t1; +set @@system_versioning_insert_history= 1; +insert into t2 (x, row_start, row_end) select x, row_start, row_end from t1 for system_time all; +sync_slave_with_master; +select x, check_row_ts(row_start, row_end) from t2 for system_time all order by x; +select row_start = '1980-01-01 00:00:00', row_end = '1980-01-01 00:00:01' from t2 for system_time all where x = 3; + +--echo # LOAD DATA +connection master; +--let DATAFILE= $MYSQLTEST_VARDIR/tmp/test_versioning_t3.data +--replace_result $DATAFILE DATAFILE +--disable_ps2_protocol +eval select x, row_start, row_end into outfile '$DATAFILE' from t1 for system_time all; +--enable_ps2_protocol +create or replace table t3 like t1; +set @@system_versioning_insert_history= 1; +--replace_result $DATAFILE DATAFILE +eval load data infile '$DATAFILE' into table t3 (x, row_start, row_end); +sync_slave_with_master; +select x, check_row_ts(row_start, row_end) from t3 for system_time all order by x; +select row_start = '1980-01-01 00:00:00', row_end = '1980-01-01 00:00:01' from t3 for system_time all where x = 3; +--remove_file $DATAFILE + +--echo # why a slave cannot have system_versioning_insert_history always on +connection master; +set @@system_versioning_insert_history= 0; +set sql_mode=''; +create or replace table t1 (a int, + rs timestamp(6) as row start, re timestamp(6) as row end, + period for system_time (rs,re)) with system versioning; +insert t1 values (1, '2000-01-01 02:03:04', '2001-01-01 02:03.04'); +select a,check_row_ts(rs,re) from t1 for system_time all; +sync_slave_with_master; +select a,check_row_ts(rs,re) from t1 for system_time all; +set sql_mode=default; + +connection master; +drop tables t1, t2, t3; + +--source suite/versioning/common_finish.inc +--source include/rpl_end.inc diff --git a/mysql-test/suite/versioning/t/rpl_common.inc b/mysql-test/suite/versioning/t/rpl_common.inc new file mode 100644 index 00000000..37e1d76c --- /dev/null +++ b/mysql-test/suite/versioning/t/rpl_common.inc @@ -0,0 +1,30 @@ +--source include/have_partition.inc + +--echo # +--echo # MDEV-25347 DML events for auto-partitioned tables are written into binary log twice +--echo # +flush binary logs; +--source include/wait_for_binlog_checkpoint.inc +create table t1 (a int) with system versioning +partition by system_time limit 1 auto; + +insert into t1 values (1); +update t1 set a= a + 1; +update t1 set a= a + 2; +--replace_result InnoDB ENGINE MyISAM ENGINE MEMORY ENGINE +show create table t1; +select * from t1; + +--let $binlog_file=master-bin.000002 +--source include/show_binlog_events.inc + +--sync_slave_with_master +--replace_result InnoDB ENGINE MyISAM ENGINE MEMORY ENGINE +show create table t1; + +select * from t1; +--connection master +# cleanup +drop table t1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/versioning/t/rpl_mix.test b/mysql-test/suite/versioning/t/rpl_mix.test new file mode 100644 index 00000000..bf4e0b93 --- /dev/null +++ b/mysql-test/suite/versioning/t/rpl_mix.test @@ -0,0 +1,19 @@ +--source include/have_binlog_format_mixed.inc +--source include/master-slave.inc + +# +# MDEV-15405 Mixed replication fails with "Could not execute Delete_rows_v1 event" upon DELETE HISTORY +# + +CREATE TABLE t1 (pk INT PRIMARY KEY, i INT) WITH SYSTEM VERSIONING; +INSERT INTO t1 VALUES (1,10),(2,20); +UPDATE t1 SET i = 100; +# This is to imitiate any real-life situation which causes a switch to row format +SET BINLOG_FORMAT= ROW; +DELETE HISTORY FROM t1; +--sync_slave_with_master + +connection master; +drop table t1; + +--source rpl_common.inc diff --git a/mysql-test/suite/versioning/t/rpl_row.test b/mysql-test/suite/versioning/t/rpl_row.test new file mode 100644 index 00000000..e36d77fc --- /dev/null +++ b/mysql-test/suite/versioning/t/rpl_row.test @@ -0,0 +1,59 @@ +--source include/have_binlog_format_row.inc +--source include/master-slave.inc +--source include/have_innodb.inc + +--echo # MDEV-16252: MINIMAL binlog_row_image does not work for versioned tables +set @old_row_image= @@binlog_row_image; +set binlog_row_image= minimal; + +create or replace table t1 (pk int, i int, primary key(pk)) +with system versioning; +insert into t1 values (1,10),(2,20); +update t1 set i = 0; + +--sync_slave_with_master +--connection master +drop table t1; +set binlog_row_image= @old_row_image; + +--echo # +--echo # MDEV-28254 Wrong position for row_start, row_end after adding column +--echo # to implicit versioned table +--echo # +--let TMP= $MYSQLTEST_VARDIR/tmp +--let $MYSQLD_DATADIR= `select @@datadir` +set @@system_versioning_alter_history= keep; +set @@session.time_zone='+00:00'; + +create table t1 (x int) with system versioning engine innodb; +alter table t1 add column y int, algorithm=inplace; +check table t1; +--exec $MYSQL_DUMP --databases test > $TMP/dump.sql + +--sync_slave_with_master +drop table t1; +--exec $MYSQL_SLAVE test < $TMP/dump.sql +show create table t1; + +--connection master +set timestamp= 12345; +--let $start_pos= query_get_value("SHOW MASTER STATUS", Position, 1) +insert t1 values (1, 1); +select *, unix_timestamp(row_start) as row_start, unix_timestamp(row_end) as row_end from t1; +--let $stop_pos= query_get_value("SHOW MASTER STATUS", Position, 1) +set timestamp= default; + +# NOTE: pipe grep is not Windows-compatible +--let grep_file= $TMP/out.txt +--let grep_regex= ^### +--exec $MYSQL_BINLOG -v -j $start_pos --stop-position=$stop_pos -o 3 $MYSQLD_DATADIR/master-bin.000001 > $grep_file +--source include/grep.inc +--sync_slave_with_master +select * from t1; + +--connection master +drop table t1; +--remove_files_wildcard $TMP *.txt +--remove_files_wildcard $TMP *.sql + +--source rpl_common.inc diff --git a/mysql-test/suite/versioning/t/rpl_stmt.test b/mysql-test/suite/versioning/t/rpl_stmt.test new file mode 100644 index 00000000..dca4e8cb --- /dev/null +++ b/mysql-test/suite/versioning/t/rpl_stmt.test @@ -0,0 +1,4 @@ +--source include/have_binlog_format_statement.inc +--source include/master-slave.inc + +--source rpl_common.inc diff --git a/mysql-test/suite/versioning/t/select.test b/mysql-test/suite/versioning/t/select.test new file mode 100644 index 00000000..9142a8fa --- /dev/null +++ b/mysql-test/suite/versioning/t/select.test @@ -0,0 +1,490 @@ +if (`SELECT $PS_PROTOCOL != 0`) +{ + --skip Need regular protocol but ps-protocol was specified +} +--source suite/versioning/engines.inc +--source suite/versioning/common.inc +--source include/default_optimizer_switch.inc + +SET @saved_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = OFF; + +--enable_prepare_warnings +# 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 trt_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 '1970-01-01 00:00:00' to timestamp @t1; +select x as BETWAND_x, y from t1 for system_time between timestamp '1970-01-01 00:00:00' 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 transaction @x0; + select x as FROMTO2_x, y from t1 for system_time from transaction @x0 to transaction @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 '1970-01-01 00:00:00' to timestamp @t1; + select x as BETWAND2_x, y from t1 for system_time between timestamp '1970-01-01 00:00:00' 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; + +# Query conditions check + +create or replace table t1(x int) with system versioning; +insert into t1 values (1); +delete from t1; +insert into t1 values (2); +delete from t1; +insert into t1 values (3); +delete from t1; + +select row_start into @start1 from t1 for system_time all where x = 1; +select row_end into @end1 from t1 for system_time all where x = 1; +select row_start into @start2 from t1 for system_time all where x = 2; +select row_end into @end2 from t1 for system_time all where x = 2; +select row_start into @start3 from t1 for system_time all where x = 3; +select row_end into @end3 from t1 for system_time all where x = 3; + +select x as ASOF_x from t1 for system_time as of @start2; +select x as ASOF_x from t1 for system_time as of @end2; +select x as FROMTO_x from t1 for system_time from @start1 to @end3; +select x as FROMTO_x from t1 for system_time from @end1 to @start2; +select x as BETWAND_x from t1 for system_time between @start1 and @end3; +select x as BETWAND_x from t1 for system_time between @end1 and @start2; + +drop table t1; + +# 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); +--error ER_TABLE_NOT_LOCKED_FOR_WRITE +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 ('1970-01-01 00:00:00')) 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); +explain extended +select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1; +select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1; + +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; +--echo # MDEV-18929 2nd execution of SP does not detect ER_VERS_NOT_VERSIONED +create or replace procedure sp() +select * from t1 for system_time as of transaction 1; +--error ER_VERS_ENGINE_UNSUPPORTED +call sp; +--error ER_VERS_ENGINE_UNSUPPORTED +call sp; +create or replace table t1 (a int); +create or replace procedure sp() +select * from t1 for system_time all; +--error ER_VERS_NOT_VERSIONED +call sp; +--error ER_VERS_NOT_VERSIONED +call sp; +drop procedure sp; + +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; + +set @ts= timestamp'1-1-1 0:0:0'; + +select x from t1 for system_time as of timestamp @ts; + +--echo ## TRANSACTION specifier +select x from t1 for system_time as of transaction @trx_start; + +--echo ## no specifier (defaults to timestamp) +select x from t1 for system_time as of @ts; + +--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 # +--echo # Issue #406, MDEV-14633 Assertion on TRT read +--echo # +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 # +--echo # MDEV-14816 Assertion `join->best_read < double(1.797...e+308L)' failed in bool greedy_search +--echo # +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; + +--echo # +--echo # MDEV-15004 parser greedily parses AS OF TIMESTAMP +--echo # +--error ER_WRONG_VALUE +select timestamp'2016-02-30 08:07:06'; +--error ER_WRONG_VALUE +select * from t1 for system_time as of timestamp'2016-02-30 08:07:06'; +select timestamp('2003-12-31 12:00:00','12:00:00'); +select * from t1 for system_time as of timestamp('2003-12-31 12:00:00','12:00:00'); + + +--echo # +--echo # MDEV-15391 Server crashes in JOIN::fix_all_splittings_in_plan or Assertion `join->best_read < double(1.79...e+308L)' failed [tempesta-tech#475] +--echo # +create or replace table t1 (f1 int) with system versioning; +insert t1 values (1),(2); +create or replace table t2 (f2 int); +create or replace table t3 (f3 int); +create or replace table t4 (f4 int) with system versioning; +select f1 from t1 join t2 left join t3 left join t4 on f3 = f4 on f3 = f2; +insert t2 values (1),(2); +insert t3 values (1),(2); +insert t4 values (1),(2); +explain extended +select f1 from t1 join t2 left join t3 left join t4 on f3 = f4 on f3 = f2; + +drop view v1; +drop table t1, t2, t3, t4; + +--echo # +--echo # MDEV-15980 FOR SYSTEM_TIME BETWEEN and FROM .. TO work with negative intervals +--echo # +--replace_result $sys_datatype_expl SYS_DATATYPE +eval create or replace table t1 ( + a int, + row_start $sys_datatype_expl as row start invisible, + row_end $sys_datatype_expl as row end invisible, + period for system_time (row_start, row_end) +) with system versioning; +insert into t1 values (1); +delete from t1; +select row_start from t1 for system_time all into @t1; +select row_end from t1 for system_time all into @t2; +--disable_query_log +if($MTR_COMBINATION_TRX_ID) { + set @t1= trt_begin_ts(@t1); + set @t2= trt_commit_ts(@t2); +} +--enable_query_log +select * from t1 for system_time between @t1 and @t2; +select * from t1 for system_time between @t2 and @t1; +select * from t1 for system_time from @t1 to @t2; +select * from t1 for system_time from @t2 to @t1; +drop table t1; + +--echo # +--echo # MDEV-15991 Server crashes in setup_on_expr upon calling SP or function executing DML on versioned tables +--echo # +create or replace table t1 (i int); +insert into t1 values (1); +--delimiter $ +create or replace procedure p(n int) +begin + select * from t1; +end $ +--delimiter ; +call p(1); +alter table t1 add system versioning; +call p(2); +call p(3); + +--echo # +--echo # MDEV-15947 ASAN heap-use-after-free in Item_ident::print or in my_strcasecmp_utf8 or unexpected ER_BAD_FIELD_ERROR upon call of stored procedure reading from versioned table +--echo # +create or replace table t1 (i int) with system versioning; +create or replace procedure p() select * from t1; +call p; +flush tables; +call p; +call p; +drop procedure p; +drop table t1; + +--echo # +--echo # MDEV-21234 Server crashes in in setup_on_expr upon 3rd execution of SP +--echo # +create table t1 (a varchar(8)); +insert into t1 values ('foo'),('bar'); +create table t2 (b date); + +create procedure pr() insert into t2 select * from t1; +--error ER_TRUNCATED_WRONG_VALUE +call pr; +prepare stmt from 'insert into t2 select * from t1'; +--error ER_TRUNCATED_WRONG_VALUE +execute stmt; +alter table t1 add system versioning; +--error ER_TRUNCATED_WRONG_VALUE +call pr; +--error ER_TRUNCATED_WRONG_VALUE +call pr; +--error ER_TRUNCATED_WRONG_VALUE +execute stmt; +--error ER_TRUNCATED_WRONG_VALUE +execute stmt; +drop prepare stmt; + +# cleanup +drop procedure pr; +drop table t1, t2; + +--echo # +--echo # MDEV-23799 CREATE .. SELECT wrong result on join versioned table +--echo # +create or replace table x (id Int) with system versioning; +create or replace table x_p (elementId Int, pkey varchar(20), pvalue varchar(20)) with system versioning; + +insert into x values (1), (2), (3); +insert into x_p values (1, 'gender', 'male'); +insert into x_p values (2, 'gender', 'female'); +insert into x_p values (3, 'gender', 'male'); + +create table tmp1 +select xgender.pvalue as gender, xtitle.pvalue as title +from x + left join x_p as xgender on x.id = xgender.elementId and xgender.pkey = 'gender' + left join x_p as xtitle on x.id = xtitle.elementId and xtitle.pkey = 'title'; + +select * from tmp1; + +drop table tmp1; +drop tables x, x_p; + +call verify_trt_dummy(34); +--disable_prepare_warnings + +SET GLOBAL innodb_stats_persistent = @saved_stats_persistent; + +-- 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 00000000..53840b39 --- /dev/null +++ b/mysql-test/suite/versioning/t/select2.test @@ -0,0 +1,220 @@ +--source suite/versioning/engines.inc +--source suite/versioning/common.inc + +replace_result $default_engine ENGINE $sys_datatype_expl SYS_TYPE; +eval create table t1( + x int unsigned, + y int unsigned, + 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=$default_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); +--enable_prepare_warnings +select sys_start from t1 limit 1 into @x0; +--disable_prepare_warnings +delete from t1 where x = 3; +delete from t1 where x > 7; + +insert into t1(x, y) values(3, 33); +--enable_prepare_warnings +select sys_start from t1 where x = 3 and y = 33 into @t1; +--disable_prepare_warnings +if($MTR_COMBINATION_TRX_ID) { + set @x1= @t1; + select trt_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 '1970-01-01 00:00' to timestamp @t1; +select x as BETWAND_x, y from t1 for system_time between '1970-01-01 00:00' and timestamp @t1; +select x as ALL_x, y from t1 for system_time all; + +if($MTR_COMBINATION_TRX_ID) { + select x as ASOF2_x, y from t1 for system_time as of transaction @x0; + select x as FROMTO2_x, y from t1 for system_time from transaction @x0 to transaction @x1; + select x as BETWAND2_x, y from t1 for system_time between transaction @x0 and transaction @x1; +} +if(!$MTR_COMBINATION_TRX_ID) { + 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 '1970-01-01 00:00' to @t1; + select x as BETWAND2_x, y from t1 for system_time between '1970-01-01 00:00' and timestamp @t1; +} + +drop table t1; + +replace_result $default_engine ENGINE $sys_datatype_expl SYS_TYPE; +eval create table t1( + x int, + y 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)) +with system versioning engine=$default_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); +--error ER_TABLE_NOT_LOCKED_FOR_WRITE +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 ('1970-01-01 00:00')) 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; + +--echo # MDEV-16043 Assertion thd->Item_change_list::is_empty() failed in mysql_parse upon SELECT from a view reading from a versioned table +create or replace table t1 (a int) with system versioning; +create or replace view v1 as select * from t1; +prepare stmt from "select * from t1 where exp( '20010609211642053929' )"; +--error ER_DATA_OUT_OF_RANGE +execute stmt; +select a from v1; + +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 00000000..b550b396 --- /dev/null +++ b/mysql-test/suite/versioning/t/simple.test @@ -0,0 +1,89 @@ +-- 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 restrict + 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; + +# +# MDEV-16804 SYSTEM VERSIONING columns not showing as GENERATED +# +create table t1 ( + a timestamp(6), + b timestamp(6) generated always as (a + interval 1 day), + c timestamp(6) generated always as (a + interval 1 month) stored, + d timestamp(6) generated always as row start, + e timestamp(6) generated always as row end, + period for system_time(d,e) +) with system versioning; +show columns from t1; +query_vertical select table_catalog,table_schema,table_name,column_name,ordinal_position,column_default,is_nullable,data_type,character_maximum_length,character_octet_length,numeric_precision,numeric_scale,datetime_precision,character_set_name,collation_name,column_type,column_key,extra,column_comment,is_generated,generation_expression,'---' from information_schema.columns where table_name='t1'; +drop table t1; + diff --git a/mysql-test/suite/versioning/t/sysvars.test b/mysql-test/suite/versioning/t/sysvars.test new file mode 100644 index 00000000..91dd278a --- /dev/null +++ b/mysql-test/suite/versioning/t/sysvars.test @@ -0,0 +1,206 @@ +create table t (a int) with system versioning; +set @before= UNIX_TIMESTAMP(now(6)); +insert into t values (1); +set @after= UNIX_TIMESTAMP(now(6)); +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; +--error ER_WRONG_VALUE_FOR_VAR +set global system_versioning_asof= '2011-02-29 00:00'; +--error ER_WRONG_VALUE_FOR_VAR +set global system_versioning_asof= '2011-02-28 24:00'; +--error ER_WRONG_VALUE_FOR_VAR +set global system_versioning_asof= '2011-00-28 00:00'; +--error ER_WRONG_VALUE_FOR_VAR +set global system_versioning_asof= '0000-00-00 00:00'; + +# 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; +--error ER_WRONG_VALUE_FOR_VAR +set system_versioning_asof= '2011-02-29 00:00'; +--error ER_WRONG_VALUE_FOR_VAR +set system_versioning_asof= '2011-02-28 24:00'; +--error ER_WRONG_VALUE_FOR_VAR +set system_versioning_asof= '2011-00-28 00:00'; +--error ER_WRONG_VALUE_FOR_VAR +set system_versioning_asof= '0000-00-00 00:00'; + +--echo # GLOBAL @@system_versioning_asof +set global system_versioning_asof= '1991-11-11 11:11:11.1111119'; +show global variables like 'system_versioning_asof'; + +set global system_versioning_asof= '1990-01-01 00:00:00'; +show global variables like 'system_versioning_asof'; + +--enable_prepare_warnings +set global system_versioning_asof= timestamp'1991-11-11 11:11:11.1111119'; +--disable_prepare_warnings +show global variables like 'system_versioning_asof'; + +set @ts= timestamp'1990-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= '1991-11-11 11:11:11.1111119'; +show variables like 'system_versioning_asof'; + +set system_versioning_asof= '1990-01-01 00:00:00'; +show variables like 'system_versioning_asof'; + +--enable_prepare_warnings +set system_versioning_asof= timestamp'1991-11-11 11:11:11.1111119'; +--disable_prepare_warnings +show variables like 'system_versioning_asof'; + +set @ts= timestamp'1990-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 time_zone= "+03:00"; +set time_zone= "+10:00"; +set global system_versioning_asof= timestamp'1991-11-11 11:11:11.111111'; +set system_versioning_asof= '1990-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 different; +set global system_versioning_asof= default; +select @@global.system_versioning_asof = @@system_versioning_asof as equal; + +set global time_zone= DEFAULT; +set time_zone= DEFAULT; +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 '1970-01-01 00:00' to current_timestamp(6); +select * from t for system_time between '1970-01-01 00:00' and current_timestamp(6); + +-- echo # MDEV-16026: Global system_versioning_asof must not be used if client sessions can have non-default time zone +-- echo # changing time zone should not abuse `system_versioning_asof` + +set session time_zone = '+10:00'; +set global system_versioning_asof = '1999-09-08 00:00:00.000000'; +show global variables like 'system_versioning_asof'; +set session time_zone = '+03:00'; +show global variables like 'system_versioning_asof'; + +set session time_zone = '+03:00'; +set session system_versioning_asof = '2000-09-08 00:00:00.000000'; +show session variables like 'system_versioning_asof'; +set session time_zone = '+10:00'; +show session variables like 'system_versioning_asof'; +-- echo # global and local time zones should not interfere +show global variables like 'system_versioning_asof'; + +set time_zone= "+10:00"; +set system_versioning_asof= FROM_UNIXTIME(@before); +select * from t as empty; +set system_versioning_asof= FROM_UNIXTIME(@after); +select * from t as nonempty; + +set time_zone= "+03:00"; +set system_versioning_asof= FROM_UNIXTIME(@before); +select * from t as empty; +set system_versioning_asof= FROM_UNIXTIME(@after); +select * from t as nonempty; + +--echo # MDEV-16481: set global system_versioning_asof=sf() crashes in specific case +--echo # Using global variable inside a stored function should not crash +create or replace function now_global() returns timestamp + return CONVERT_TZ(now(), @@session.time_zone, @@global.time_zone); +set global system_versioning_asof= now_global(); +drop function now_global; + +set global time_zone= "SYSTEM"; +set time_zone= "SYSTEM"; +set global system_versioning_asof= default; +set system_versioning_asof= default; + +show status like "Feature_system_versioning"; + +drop table t; + +--echo # +--echo # MDEV-22906 Disallow system_versioning_asof in DML +--echo # +create or replace table t1 (x int) with system versioning; +create or replace table t2 (y int); +insert into t1 values (1); +insert into t2 values (1); +set system_versioning_asof= '1970-01-02 00:00:00'; +delete t1, t2 from t1 join t2 where t1.x = t2.y; +select * from t1 for system_time as of timestamp now(6); + +insert into t1 values (1); +insert into t2 values (1); +update t1, t2 set x= 2, y= 2 where x = y; +select * from t1 for system_time as of timestamp now(6); + +replace t2 select x + 1 from t1; +select * from t2; + +insert t2 select x + 2 from t1; +select * from t2; + +drop tables t1, t2; + + +--echo # +--echo # MDEV-16991 Rounding vs truncation for TIME, DATETIME, TIMESTAMP +--echo # + +SET sql_mode=TIME_ROUND_FRACTIONAL; +--enable_prepare_warnings +SET @@global.system_versioning_asof= timestamp'2001-12-31 23:59:59.9999999'; +--disable_prepare_warnings +SELECT @@global.system_versioning_asof; +SET @@global.system_versioning_asof= DEFAULT; + +--echo # +--echo # MDEV-23562 Assertion `time_type == MYSQL_TIMESTAMP_DATETIME' failed upon SELECT from versioned table +--echo # + +CREATE TABLE t1 (a INT) WITH SYSTEM VERSIONING; +SET system_versioning_asof= DATE(NOW()); +SELECT * FROM t1; +DROP TABLE t1; +SET system_versioning_asof= DEFAULT; + +--echo # End of 10.4 tests diff --git a/mysql-test/suite/versioning/t/trx_id.opt b/mysql-test/suite/versioning/t/trx_id.opt new file mode 100644 index 00000000..f900254f --- /dev/null +++ b/mysql-test/suite/versioning/t/trx_id.opt @@ -0,0 +1,2 @@ +--log_bin +--binlog_do_db=foo 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 00000000..60836279 --- /dev/null +++ b/mysql-test/suite/versioning/t/trx_id.test @@ -0,0 +1,633 @@ +if (!$TEST_VERSIONING_SO) +{ + --skip needs test_versioning plugin +} +--source include/have_innodb.inc +--source include/have_partition.inc +--source include/default_charset.inc + +--disable_query_log +--eval install plugin test_versioning soname '$TEST_VERSIONING_SO' +--enable_query_log + +set default_storage_engine= innodb; + +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; + +--enable_prepare_warnings + +--echo # No history inside the transaction +start transaction; +insert into t1 (x) values (1); +update t1 set x= x + 1; +update t1 set x= x + 1; +commit; +select *, sys_trx_start > 1, sys_trx_end from t1 for system_time all; + +--echo # ALTER ADD SYSTEM VERSIONING should write to mysql.transaction_registry +set @@system_versioning_alter_history=keep; + +create or replace table t1 (x int); +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 count(*) = 1 from mysql.transaction_registry where transaction_id = @trx_start; + +create or replace table t1 (x int); +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 count(*) = @tmp from mysql.transaction_registry; + +create or replace table t1 (x int); +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 count(*) = 1 from mysql.transaction_registry where transaction_id = @trx_start; + +create or replace table t1 (x int); +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; +# With MDEV-14511 the transaction will be registered even for empty tables. +select count(*) = @tmp + 1 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) +) with system versioning; +insert into t1 values (1); +alter table t1 drop column sys_start, drop column sys_end; +select row_end = 18446744073709551615 as transaction_based from t1 for system_time all; + +--echo # Simple vs SEES algorithms +create or replace table t1 ( + x int, + sys_start bigint(20) unsigned as row start invisible, + sys_end bigint(20) unsigned as row end invisible, + period for system_time (sys_start, sys_end) +) with system versioning; + +# MDEV-515 takes X-lock on the table for the first insert +# So concurrent DML won't happen on the table +INSERT INTO t1 VALUES(100); + +set transaction isolation level read committed; +start transaction; +insert into t1 values (1); +--connect (con1,localhost,root,,test) +set transaction isolation level read committed; +start transaction; +insert into t1 values (2); +--connect (con2,localhost,root,,test) +set transaction isolation level read committed; +start transaction; +insert into t1 values (3); +commit; +--disconnect con2 +--connection default +--sleep 0.01 +set @ts1= sysdate(6); +--connection con1 +commit; +--disconnect con1 +--connection default +--sleep 0.01 +set @ts2= sysdate(6); +commit; +--sleep 0.01 +set @ts3= sysdate(6); + +select sys_start from t1 where x = 1 into @trx_id1; +select sys_start from t1 where x = 2 into @trx_id2; +select sys_start from t1 where x = 3 into @trx_id3; + +select @trx_id1 < @trx_id2, @trx_id2 < @trx_id3; +select @ts1 < @ts2, @ts2 < @ts3; + +--echo # MVCC is resolved +select * from t1 for system_time as of transaction @trx_id1; +select * from t1 for system_time as of timestamp @ts1; +select * from t1 for system_time as of transaction @trx_id2; +select * from t1 for system_time as of timestamp @ts2; +select * from t1 for system_time as of transaction @trx_id3; +select * from t1 for system_time as of timestamp @ts3; + +--echo # +--echo # MDEV-15427 IB: TRX_ID based operations inside transaction generate history +--echo # +create or replace table t1( + x int(10), + row_start bigint(20) unsigned as row start, + row_end bigint(20) unsigned as row end, + period for system_time(row_start, row_end) +) with system versioning; + +begin; +insert into t1 (x) values (1); +delete from t1; +commit; +select x from t1 for system_time all; + +insert into t1 (x) values (2); +begin; +update t1 set x= 3; +update t1 set x= 4; +commit; +select x, row_start < row_end from t1 for system_time all; + +--echo # +--echo # MDEV-15951 system versioning by trx id doesn't work with partitioning +--echo # currently trx_id does not support partitioning by system_time +--echo # +--error ER_VERS_FIELD_WRONG_TYPE +create or replace table t1( + i int, + row_start bigint unsigned generated always as row start, + row_end bigint unsigned generated always as row end, + period for system_time(row_start, row_end) +) engine=InnoDB with system versioning partition by system_time ( + partition p0 history, + partition pn current +); + +create or replace table t1( + i int, + row_start bigint unsigned generated always as row start, + row_end bigint unsigned generated always as row end, + period for system_time(row_start, row_end) +) engine=InnoDB with system versioning; + +--replace_regex /#sql-[0-9a-f_]*/#sql-temporary/ +--error ER_VERS_FIELD_WRONG_TYPE +alter table t1 partition by system_time ( + partition p0 history, + partition pn current +); + +drop table t1; + +--error ER_VERS_TRX_PART_HISTORIC_ROW_NOT_SUPPORTED +create or replace table t ( + a int primary key, + row_start bigint unsigned as row start invisible, + row_end bigint unsigned as row end invisible, + period for system_time(row_start, row_end) +) engine=innodb with system versioning +partition by key() ( + partition p1, + partition p2 +); + +--error ER_VERS_TRX_PART_HISTORIC_ROW_NOT_SUPPORTED +create or replace table t ( + a int primary key, + row_start bigint unsigned as row start invisible, + row_end bigint unsigned as row end invisible, + period for system_time(row_start, row_end) +) engine=innodb with system versioning +partition by key(a, row_start) ( + partition p1, + partition p2 +); + +--error ER_VERS_TRX_PART_HISTORIC_ROW_NOT_SUPPORTED +create or replace table t ( + a int primary key, + row_start bigint unsigned as row start invisible, + row_end bigint unsigned as row end invisible, + period for system_time(row_start, row_end) +) engine=innodb with system versioning +partition by hash(a + row_end * 2) ( + partition p1, + partition p2 +); + +--error ER_VERS_TRX_PART_HISTORIC_ROW_NOT_SUPPORTED +create or replace table t ( + a int primary key, + row_start bigint unsigned as row start invisible, + row_end bigint unsigned as row end invisible, + period for system_time(row_start, row_end) +) engine=innodb with system versioning +partition by range columns (a, row_start) ( + partition p1 values less than (100, 100) +); + +--echo # +--echo # MDEV-16010 Too many rows with AS OF point_in_the_past_or_NULL +--echo # +create or replace table t1 ( + x int, + row_start bigint unsigned as row start invisible, + row_end bigint unsigned as row end invisible, + period for system_time (row_start, row_end) +) with system versioning engine innodb; +insert into t1 (x) values (1); +delete from t1; +select * from t1 for system_time as of timestamp'1990-1-1 00:00'; +select * from t1 for system_time as of NULL; + +--echo # MDEV-16024 transaction_registry.begin_timestamp is wrong for explicit transactions +create or replace table t1 ( + x int(11) default null, + row_start bigint(20) unsigned generated always as row start invisible, + row_end bigint(20) unsigned generated always as row end invisible, + period for system_time (row_start, row_end) +) engine=innodb with system versioning; +begin; +set @ts1= now(6); +--sleep 0.01 +insert into t1 values (1); +commit; + +select row_start from t1 into @trx_id; +select trt_begin_ts(@trx_id) <= @ts1 as BEGIN_TS_GOOD; + +drop table t1; + +--echo # +--echo # MDEV-16100 FOR SYSTEM_TIME erroneously resolves string user variables as transaction IDs +--echo # + +CREATE TABLE t1 ( + x INT, + sys_trx_start BIGINT UNSIGNED AS ROW START, + sys_trx_end BIGINT UNSIGNED AS ROW END, + PERIOD FOR SYSTEM_TIME (sys_trx_start, sys_trx_end) +) WITH SYSTEM VERSIONING ENGINE=INNODB; +INSERT INTO t1 (x) VALUES (1); +SET @ts= DATE_ADD(NOW(), INTERVAL 1 YEAR); +EXPLAIN EXTENDED SELECT x FROM t1 FOR SYSTEM_TIME AS OF TRANSACTION @ts; +EXPLAIN EXTENDED SELECT x FROM t1 FOR SYSTEM_TIME AS OF TIMESTAMP @ts; +EXPLAIN EXTENDED SELECT x FROM t1 FOR SYSTEM_TIME AS OF @ts; +DROP TABLE t1; + + +--echo # +--echo # Testing AS OF with expressions of various kinds and data types +--echo # + +CREATE 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; +INSERT INTO t1 VALUES (1); + +CREATE TABLE t2 +( + x INT, + sys_trx_start TIMESTAMP(6) AS ROW START INVISIBLE, + sys_trx_end TIMESTAMP(6) AS ROW END INVISIBLE, + PERIOD FOR SYSTEM_TIME (sys_trx_start, sys_trx_end) +) WITH SYSTEM VERSIONING; +INSERT INTO t2 VALUES (1); + +--echo # +--echo # ROW is not supported +--echo # + +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT * FROM t1 FOR SYSTEM_TIME AS OF (1,1); +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT * FROM t2 FOR SYSTEM_TIME AS OF (1,1); + + +--echo # +--echo # DOUBLE is not supported, use explicit CAST +--echo # + +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT * FROM t1 FOR SYSTEM_TIME AS OF TRANSACTION RAND(); +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT * FROM t1 FOR SYSTEM_TIME AS OF TRANSACTION (RAND()); +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT * FROM t1 FOR SYSTEM_TIME AS OF TRANSACTION COALESCE(RAND()); + +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT * FROM t2 FOR SYSTEM_TIME AS OF TRANSACTION RAND(); +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT * FROM t2 FOR SYSTEM_TIME AS OF TRANSACTION (RAND()); +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT * FROM t2 FOR SYSTEM_TIME AS OF TRANSACTION COALESCE(RAND()); + + +--echo # +--echo # DECIMAL is not supported, use explicit CAST +--echo # + +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT * FROM t1 FOR SYSTEM_TIME AS OF TRANSACTION 10.1; +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT * FROM t1 FOR SYSTEM_TIME AS OF TRANSACTION COALESCE(10.1); + +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT * FROM t2 FOR SYSTEM_TIME AS OF TRANSACTION 10.1; +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT * FROM t2 FOR SYSTEM_TIME AS OF TRANSACTION COALESCE(10.1); + + +--echo # +--echo # YEAR is not supported, use explicit CAST +--echo # + +DELIMITER $$; +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +BEGIN NOT ATOMIC + DECLARE var YEAR; + SELECT * FROM t1 FOR SYSTEM_TIME AS OF TRANSACTION var; +END; +$$ +DELIMITER ;$$ + +DELIMITER $$; +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +BEGIN NOT ATOMIC + DECLARE var YEAR; + SELECT * FROM t2 FOR SYSTEM_TIME AS OF TRANSACTION var; +END; +$$ +DELIMITER ;$$ + + +--echo # +--echo # ENUM is not supported, use explicit CAST +--echo # + +DELIMITER $$; +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +BEGIN NOT ATOMIC + DECLARE var ENUM('xxx') DEFAULT 'xxx'; + SELECT * FROM t1 FOR SYSTEM_TIME AS OF TRANSACTION var; +END; +$$ +DELIMITER ;$$ + + +DELIMITER $$; +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +BEGIN NOT ATOMIC + DECLARE var ENUM('xxx') DEFAULT 'xxx'; + SELECT * FROM t2 FOR SYSTEM_TIME AS OF TRANSACTION var; +END; +$$ +DELIMITER ;$$ + + +--echo # +--echo # SET is not supported, use explicit CAST +--echo # + +DELIMITER $$; +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +BEGIN NOT ATOMIC + DECLARE var SET('xxx') DEFAULT 'xxx'; + SELECT * FROM t1 FOR SYSTEM_TIME AS OF TRANSACTION var; +END; +$$ +DELIMITER ;$$ + +DELIMITER $$; +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +BEGIN NOT ATOMIC + DECLARE var SET('xxx') DEFAULT 'xxx'; + SELECT * FROM t2 FOR SYSTEM_TIME AS OF TRANSACTION var; +END; +$$ +DELIMITER ;$$ + + +DELIMITER $$; +--error ER_VERS_ENGINE_UNSUPPORTED +BEGIN NOT ATOMIC + DECLARE var BIT(10); + SELECT * FROM t2 FOR SYSTEM_TIME AS OF TRANSACTION var; +END; +$$ +DELIMITER ;$$ + + +--echo # +--echo # String literals resolve to TIMESTAMP +--echo # + +SELECT * FROM t1 FOR SYSTEM_TIME AS OF '2038-12-30 00:00:00'; +SELECT * FROM t2 FOR SYSTEM_TIME AS OF '2038-12-30 00:00:00'; +DROP TABLE t1, t2; + + +--echo # +--echo # MDEV-16094 Crash when using AS OF with a stored function +--echo # + +CREATE FUNCTION fts() RETURNS DATETIME RETURN '2001-01-01 10:20:30'; +CREATE FUNCTION ftx() RETURNS BIGINT UNSIGNED RETURN 1; + +CREATE TABLE ttx +( + x INT, + start_timestamp BIGINT UNSIGNED GENERATED ALWAYS AS ROW START, + end_timestamp BIGINT UNSIGNED GENERATED ALWAYS AS ROW END, + PERIOD FOR SYSTEM_TIME(start_timestamp, end_timestamp) +) ENGINE=InnoDB WITH SYSTEM VERSIONING; + +CREATE TABLE tts +( + x INT, + start_timestamp TIMESTAMP(6) GENERATED ALWAYS AS ROW START, + end_timestamp TIMESTAMP(6) GENERATED ALWAYS AS ROW END, + PERIOD FOR SYSTEM_TIME(start_timestamp, end_timestamp) +) ENGINE=InnoDB WITH SYSTEM VERSIONING; + +SELECT * FROM tts FOR SYSTEM_TIME AS OF fts(); +--error ER_VERS_ENGINE_UNSUPPORTED +SELECT * FROM tts FOR SYSTEM_TIME AS OF TRANSACTION ftx(); +SELECT * FROM ttx FOR SYSTEM_TIME AS OF fts(); +SELECT * FROM ttx FOR SYSTEM_TIME AS OF TRANSACTION ftx(); + +DROP TABLE tts; +DROP TABLE ttx; +DROP FUNCTION fts; +DROP FUNCTION ftx; + +--echo # +--echo # MDEV-16330 Allow instant change of WITH SYSTEM VERSIONING column attribute +--echo # + +SET @@SYSTEM_VERSIONING_ALTER_HISTORY=KEEP; +CREATE TABLE t ( + a INT, + b INT, + row_start BIGINT UNSIGNED AS ROW START INVISIBLE, + row_end BIGINT UNSIGNED AS ROW END INVISIBLE, + PERIOD FOR SYSTEM_TIME(row_start, row_end) +) WITH SYSTEM VERSIONING ENGINE=INNODB; + +INSERT INTO t VALUES (1,1); + +--echo # without table rebuild +SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c + INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t + ON c.table_id=t.table_id + WHERE t.name='test/t' AND c.name='a'; +--enable_info +ALTER TABLE t + CHANGE a a INT WITHOUT SYSTEM VERSIONING; +--disable_info +SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c + INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t + ON c.table_id=t.table_id + WHERE t.name='test/t' AND c.name='a'; + +UPDATE t SET a=11; +SELECT COUNT(*) FROM t FOR SYSTEM_TIME ALL; + +--echo # with table rebuild +SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c + INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t + ON c.table_id=t.table_id + WHERE t.name='test/t' AND c.name='a'; +--enable_info +ALTER TABLE t + CHANGE a a INT WITH SYSTEM VERSIONING, + ADD PRIMARY KEY pk(a); +--disable_info +SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c + INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t + ON c.table_id=t.table_id + WHERE t.name='test/t' AND c.name='a'; + +UPDATE t SET a=1; +SELECT COUNT(*) FROM t FOR SYSTEM_TIME ALL; + +SHOW CREATE TABLE t; + +-- echo # handles VIRTUAL columns too +CREATE OR REPLACE TABLE t ( + a INT AS (b + 1), + b INT, + row_start BIGINT UNSIGNED AS ROW START INVISIBLE, + row_end BIGINT UNSIGNED AS ROW END INVISIBLE, + PERIOD FOR SYSTEM_TIME(row_start, row_end) +) WITH SYSTEM VERSIONING ENGINE=INNODB; + +INSERT INTO t VALUES (DEFAULT, 1); + +SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c + INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t + ON c.table_id=t.table_id + WHERE t.name='test/t' AND c.name='b'; +--enable_info +ALTER TABLE t + CHANGE b b INT WITHOUT SYSTEM VERSIONING; +--disable_info +SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c + INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t + ON c.table_id=t.table_id + WHERE t.name='test/t' AND c.name='b'; + +UPDATE t SET b=11; +SELECT COUNT(*) FROM t FOR SYSTEM_TIME ALL; + +DROP TABLE t; +SET @@SYSTEM_VERSIONING_ALTER_HISTORY=ERROR; + +SELECT count(*) from mysql.transaction_registry where begin_timestamp>=commit_timestamp; + +--echo # MDEV-18875 Assertion `thd->transaction.stmt.ha_list == __null || +--echo # trans == &thd->transaction.stmt' failed or bogus ER_DUP_ENTRY upon +--echo # ALTER TABLE with versioning +create or replace table t (x int) engine=innodb; +set autocommit= 0; +alter table t + algorithm=copy, + add column row_start bigint unsigned as row start, + add column row_end bigint unsigned as row end, + add period for system_time(row_start,row_end), + with system versioning; +set autocommit= 1; + +--echo # MDEV-18865 Assertion `t->first->versioned_by_id()' +--echo # failed in innodb_prepare_commit_versioned + +create or replace table t (x int) engine=innodb; +insert into t values (0); +alter table t add `row_start` bigint unsigned as row start, + add `row_end` bigint unsigned as row end, + add period for system_time(`row_start`,`row_end`), + modify x int after row_start, + with system versioning; +drop table t; + +--echo # +--echo # MDEV-20842 Crash using versioning plugin functions after plugin was removed from server +--echo # +uninstall plugin test_versioning; +--error ER_SP_DOES_NOT_EXIST +select trt_begin_ts(0); + +--disable_prepare_warnings + +--echo # +--echo # MDEV-21650 Non-empty statement transaction on global rollback after TRT update error +--echo # +create table t1 (s date, e date, period for app(s,e)) engine=innodb; +alter table t1 + add row_start bigint unsigned as row start, + add row_end bigint unsigned as row end, + add period for system_time(row_start,row_end), + with system versioning, + add period if not exists for app(x,y); + +set transaction isolation level serializable; +start transaction; +insert into t1 (s,e) values ('2021-07-04','2024-08-18'); + +--connect (con1,localhost,root,,test) +start transaction; +insert into t1 (s,e) values ('2018-06-01','2021-09-15'); + +--connection default +--replace_regex /TRX_ID \d+/TRX_ID .../ +--error ER_VERS_NO_TRX_ID +select * from t1 for system_time as of now(); + +--connection con1 +set innodb_lock_wait_timeout= 1, lock_wait_timeout= 1; +# can be existing or non-existing table, does not matter +--error ER_LOCK_WAIT_TIMEOUT +alter table xx; + +# cleanup +--disconnect con1 +--connection default +drop table t1; diff --git a/mysql-test/suite/versioning/t/update-big.test b/mysql-test/suite/versioning/t/update-big.test new file mode 100644 index 00000000..98767cef --- /dev/null +++ b/mysql-test/suite/versioning/t/update-big.test @@ -0,0 +1,108 @@ +source include/big_test.inc; +source suite/versioning/engines.inc; +source suite/versioning/common.inc; +source include/have_partition.inc; + +--echo # +--echo # MDEV-15458 Segfault in heap_scan() upon UPDATE after ADD SYSTEM VERSIONING +--echo # +create or replace table t1 (a int); +insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8); +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; + +--connect (con1,localhost,root,,test) +alter table t1 add system versioning; + +--connection default +update t1 set a= 7 where a = 3; +update t1 set a= 2 where a = 7; +update t1 set a= 5 where a = 2; +update t1 set a= 1 where a = 5; +update t1 set a= 8 where a = 1; +update t1 set a= 4 where a = 8; +update t1 set a= 6; + +--disconnect con1 +drop table t1; + +call mtr.add_suppression("need more HISTORY partitions"); + +--echo # +--echo # MDEV-23642 Locking timeout caused by auto-creation affects original DML +--echo # +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create or replace table t1 (x int primary key) with system versioning engine innodb +partition by system_time interval 1 hour auto; + +insert into t1 values (1); +start transaction; +insert into t1 values (2); + +--connect con1, localhost, root +set lock_wait_timeout= 1; +set innodb_lock_wait_timeout= 1; +set timestamp= unix_timestamp('2000-01-01 01:00:01'); +update t1 set x= x + 122 where x = 1; +--disconnect con1 +--connection default +select * from t1; + +# cleanup +drop table t1; +set timestamp= default; + +--echo # +--echo # MDEV-25339 Assertion `thd->transaction.stmt.is_empty() || thd->in_sub_stmt' failed +--echo # +create or replace table t1 (x int) with system versioning engine innodb +partition by system_time interval 1 hour auto; +start transaction; +insert into t1 values (1); +select * from t1; + +--connect con1, localhost, root +set lock_wait_timeout= 1; +set innodb_lock_wait_timeout= 1; +--error ER_LOCK_WAIT_TIMEOUT +update t1 set x= x + 111; +select * from t1; + +# cleanup +--disconnect con1 +--connection default +drop table t1; + +--echo # +--echo # MDEV-25482 Auto-create: Server hangs after a failed attempt to create partition +--echo # +set timestamp= default; +create table t (pk int primary key, a int) engine=InnoDB + with system versioning partition by system_time interval 1 hour auto; + +insert into t values (1,1),(2,2),(3,3),(4,4),(5,5); + +start transaction; +update t set a= 20 where pk = 2; + +--connect (con1,localhost,root,,) +set lock_wait_timeout= 1; +set @@timestamp= @@timestamp+3601; +update t set a= 40 where pk = 4; +update t set a= 400 where pk = 4; + +# Cleanup +--disconnect con1 +--connection default +select * from t where pk = 4; +rollback; +drop tables t; + +source suite/versioning/common_finish.inc; diff --git a/mysql-test/suite/versioning/t/update.test b/mysql-test/suite/versioning/t/update.test new file mode 100644 index 00000000..6930fecc --- /dev/null +++ b/mysql-test/suite/versioning/t/update.test @@ -0,0 +1,419 @@ +source suite/versioning/engines.inc; +source suite/versioning/common.inc; + +replace_result $sys_datatype_expl SYS_DATATYPE; +eval create 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 (1, 1000), (2, 2000), (3, 3000), (4, 4000), (5, 5000), (6, 6000), (7, 7000), (8, 8000), (9, 9000); +select x, y from t1 order by x, y; +update t1 set y = y + 1 where x > 7; +select x, y from t1 order by x, y; +select x, y from t1 for system_time all order by sys_trx_end, x, y; +drop table t1; + +replace_result $sys_datatype_expl SYS_DATATYPE; +eval create table t1 ( + id bigint primary key, + x int, + y int without system versioning, + 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; +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +insert into t1 values(1, 1, 1); +select sys_trx_start into @tmp1 from t1; +set timestamp= unix_timestamp('2000-01-01 01:00:00'); +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; +set timestamp= unix_timestamp('2000-01-01 02:00:00'); +update t1 set y= 1 where id = 1; +select @tmp1 = sys_trx_start as A2, x from t1; +drop table t1; +set timestamp= default; + +replace_result $sys_datatype_expl SYS_DATATYPE; +eval create table t1 ( + x int, + y int, + 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 (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; + +replace_result $sys_datatype_max MAXVAL; +eval select x, y, sys_trx_end = $sys_datatype_max as current from t1 for system_time all order by sys_trx_end, x, y; + +drop table t1; + +replace_result $sys_datatype_expl SYS_DATATYPE; +eval create table t1 ( + id int primary key auto_increment, + x int, + 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; + +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; + +replace_result $sys_datatype_expl SYS_DATATYPE; +eval create table t1( + x int unsigned, + sys_trx_end $sys_datatype_expl as row end invisible, + sys_trx_start $sys_datatype_expl as row start invisible, + y int unsigned, + period for system_time (sys_trx_start, sys_trx_end), + primary key(x, y)) +with system versioning; +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 order by sys_trx_end, x, y; +select x, y from t1 order by x, y; +drop table t1; + +replace_result $sys_datatype_expl SYS_DATATYPE; +eval create 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; +create table t2 like t1; +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 all order by sys_trx_end, x, y; +select x, y from t1 order by x, y; +select x, y from t2 for system_time all order by sys_trx_end, x, y; +select x, y from t2 order by x, y; +drop table t1; +drop table t2; + +replace_result $sys_datatype_expl SYS_DATATYPE; +eval create table t1 ( + id bigint primary key without system versioning, + name varchar(128), + salary bigint without system versioning, + 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; +create table t2 like t1; + +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; + +--echo # Ensure FTS retains correct history +replace_result $sys_datatype_expl SYS_DATATYPE; +eval create table t1 ( + x int, y text, fulltext (y), + row_start $sys_datatype_expl as row start invisible, + row_end $sys_datatype_expl as row end invisible, + period for system_time (row_start, row_end)) +with system versioning engine innodb; +insert into t1 values (1, repeat('LONG', 2048)); +update t1 set x= x + 1; +select x, left(y, 4), length(y), check_row(row_start, row_end) from t1 for system_time all order by x, y; +update t1 set y= 'SHORT'; +select x, left(y, 4), length(y), check_row(row_start, row_end) from t1 for system_time all order by x, y; +drop tables t1; + +--echo ### Issue tempesta-tech/mariadb#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); + +--echo # +--echo # MDEV-14829 Assertion `0' failed in Protocol::end_statement upon concurrent UPDATE +--echo # +set @old_lock_wait_timeout= @@innodb_lock_wait_timeout; +set @@innodb_lock_wait_timeout= 100000000; +create or replace table t1 (pk int, a char(3), b char(3), primary key(pk)) + engine=innodb with system versioning; + +insert into t1 (pk) values (1); +connect (con1,localhost,root,,test); +start transaction; +select * from t1 for update; +connection default; +send update t1 set b = 'foo'; +connection con1; +let $wait_condition= select count(*) from information_schema.innodb_lock_waits; +source include/wait_condition.inc; +error ER_LOCK_DEADLOCK; +update t1 set a = 'bar'; +disconnect con1; +connection default; +reap; +drop table t1; +set @@innodb_lock_wait_timeout= @old_lock_wait_timeout; + +--echo # +--echo # MDEV-19406 Assertion on updating view of join with versioned table +--echo # +--disable_warnings +create or replace table t1 (pk int primary key, a date, b int, index(b)) engine=innodb with system versioning; +create or replace table t2 (c int); +create or replace view v as select * from t1 join t2; + +insert into t1 (pk) values (1); +update t1 set a= '2012-12-12'; +update v set a= '2000-01-01' order by b limit 1; # point of failure +drop view v; +drop table t1, t2; +--enable_warnings + +--echo # +--echo # MDEV-20441 ER_CRASHED_ON_USAGE upon update on versioned Aria table +--echo # +create or replace table t1 (a varchar(8)) +engine=aria row_format=fixed +with system versioning; + +insert into t1 (a) values ('foo'); +update t1 set a = 'bar'; +drop table t1; + +--echo # +--echo # MDEV-21147 Assertion `marked_for_read()' upon UPDATE on versioned table via view +--echo # +create or replace table t1 ( + pk int, a char(8), b char(8), + primary key (pk) +) with system versioning; + +create or replace view v1 as select * from t1; +insert into t1 values (1, null, 'd') , (2, null, 'i') ; +update v1 set a= null where b = ''; + +create or replace table t1 (id int, k int, primary key (id)) engine=innodb with system versioning; +insert into t1 values (1,1),(2,2); +create or replace view v1 as select * from t1; +update v1 set id= 2 where k = 0; + +create or replace table t1 (a int) with system versioning; +create or replace view v1 as select * from t1; +create or replace procedure sp() update v1 set xx = 1; +--error ER_BAD_FIELD_ERROR +call sp; +--error ER_BAD_FIELD_ERROR +call sp; + +# cleanup +drop procedure sp; +drop view v1; +drop table t1; + +--echo # +--echo # MDEV-21342 Assertion in set_ok_status() upon spatial field error on system-versioned table +--echo # +create or replace table t1 (f point, key(f)) with system versioning engine=myisam; +--error ER_CANT_CREATE_GEOMETRY_OBJECT +update t1 set f = null where f = 'foo'; + +# cleanup +drop table t1; + +--echo # +--echo # MDEV-22061 InnoDB: Assertion of missing row in sec index row_start upon REPLACE on a system-versioned table +--echo # +create or replace table t1 ( + a int, + b int, + row_start bigint(20) unsigned generated always as row start, + row_end bigint(20) unsigned generated always as row end, + unique key (b,row_end), + key (row_start), + period for system_time (row_start,row_end) +) engine=innodb with system versioning; + +insert into t1 (a, b) values (1, 2); +replace into t1 (a, b) values (3, 2); +replace into t1 (a, b) values (4, 2); + +# cleanup +drop table t1; + +--echo # +--echo # MDEV-20661 Virtual fields are not recalculated on system fields value assignment +--echo # + +replace_result $sys_datatype_expl SYS_DATATYPE; +eval create table t1 ( + a int, + row_start $sys_datatype_expl as row start invisible, + row_end $sys_datatype_expl as row end invisible, + period for system_time (row_start, row_end), + v1 bigint unsigned as (a ^ row_start) unique, + v2 bigint unsigned as (a ^ row_end) unique +) engine=innodb with system versioning; + +insert into t1 (a) values (1), (2); +update ignore t1 set a= 3; +delete history from t1; + +# cleanup +drop table t1; + +--echo # +--echo # MDEV-23446 UPDATE does not insert history row if the row is not changed +--echo # +replace_result $sys_datatype_expl SYS_DATATYPE; +eval create table t1 ( + a int, + row_start $sys_datatype_expl as row start invisible, + row_end $sys_datatype_expl as row end invisible, + period for system_time (row_start, row_end)) with system versioning; +insert into t1 values (1); +update t1 set a= 1; +select *, check_row(row_start, row_end) from t1 for system_time all order by row_end; + +--echo # multi-update +create or replace table t2 like t1; +create or replace table t3 like t1; +insert into t2 values (1); +insert into t3 values (1); +update t2, t3 set t2.a= 1, t3.a= 1 where t2.a = t3.a; +select *, check_row(row_start, row_end) from t2 for system_time all order by row_end; +select *, check_row(row_start, row_end) from t2 for system_time all order by row_end; + +# cleanup +drop tables t1, t2, t3; + +--echo # +--echo # MDEV-26778 row_start is not updated in current row for InnoDB +--echo # +create or replace table t1 (x int) with system versioning; +insert t1 values (1); +update t1 set x= 1; +select row_start into @r from t1; +select check_row_ts(row_start, row_end) from t1 for system_time all where row_start = @r; +drop table t1; + +--echo # +--echo # MDEV-22973 Assertion in compare_record upon multi-update involving versioned table via view +--echo # +create or replace table t1 (a int, primary key (a)) engine=myisam; +insert into t1 values (0); +create or replace table t2 (pk int, b int, primary key (pk), key(b)) engine=innodb with system versioning; +insert into t2 values (1, 0), (2, 0); +create or replace view v as select a, b from t1, t2; +update v set b= null where a = 0 order by b; +# cleanup +drop view v; +drop table t1, t2; + +--echo # +--echo # MDEV-24522 Assertion `inited==NONE' fails upon UPDATE on versioned table with unique blob +--echo # +create table t1 (a int, b int, c text, unique(c), key (b)) engine=myisam with system versioning; +insert into t1 values (1, 1, 'foo'), (2, 11, 'bar'); + +update t1 set a = 3 where b <= 9; +update t1 set a = 3 where b <= 10; + +# cleanup +drop table t1; + +create table t1 (a int, b int, c text, unique(c), key (b)) engine=myisam with system versioning; +create table t2 (a int, b int, c text, unique(c), key (b)) engine=myisam with system versioning; +insert into t1 values (1, 1, 'foo'), (2, 11, 'bar'); +insert into t2 values (1, 1, 'foo'), (2, 11, 'bar'); + +update t1 set a = 3 where b <= 9; +update t2 set a = 3 where b <= 9; +update t1, t2 set t1.a = 3, t2.a = 3 where t1.b <= 10 and t2.b <= 10 and t1.b = t2.b; + +# cleanup +drop tables t1, t2; + +--echo # +--echo # MDEV-23100 ODKU of non-versioning column inserts history row +--echo # +create table t1 ( + x int unique, + y int without system versioning +) with system versioning; + +insert into t1 (x, y) values ('1', '1'); +insert into t1 (x, y) values ('1', '2') + on duplicate key update y = 3; + +select x, y, check_row_ts(row_start, row_end) from t1 for system_time all order by row_end; + +drop table t1; + +--echo # +--echo # MDEV-25644 UPDATE not working properly on transaction precise system versioned table +--echo # +create or replace table t1 (nid int primary key, nstate int, ntype int) engine innodb; +--replace_result $sys_datatype_expl SYS_DATATYPE +eval alter table t1 add + row_start $sys_datatype_expl generated always as row start invisible, + add row_end $sys_datatype_expl generated always as row end invisible, + add period for system_time(row_start, row_end), + add system versioning; +insert into t1 values (1, 1, 1); +select nid, nstate, check_row(row_start, row_end) from t1 for system_time all order by row_start, row_end; +start transaction; +update t1 set nstate= nstate where nid = 1; +select nid, nstate, check_row(row_start, row_end) from t1 for system_time all order by row_start, row_end; +--echo # Bug: ERROR 1761 (23000): Foreign key constraint for table 'xxx', record '1-18446744073709551615' would lead to a duplicate entry in table 'xxx', key 'PRIMARY' +update t1 set nstate= 3 where nid= 1; +# Under one transaction trx_id generates only one history row, that differs from timestamp +select nid, nstate, check_row(row_start, row_end) from t1 for system_time all order by row_start, row_end; +commit; +drop tables t1; + +--echo # End of 10.4 tests + +source suite/versioning/common_finish.inc; diff --git a/mysql-test/suite/versioning/t/view.test b/mysql-test/suite/versioning/t/view.test new file mode 100644 index 00000000..9bb915f7 --- /dev/null +++ b/mysql-test/suite/versioning/t/view.test @@ -0,0 +1,229 @@ +--source suite/versioning/engines.inc +--source suite/versioning/common.inc +--source include/have_partition.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 [tempesta-tech/mariadb#151] +create or replace table t1 (x int) with system versioning; +create or replace view vt1(c) as select x from t1; +--replace_result 18446744073709551615 MAX_RESULT "TIMESTAMP'2038-01-19 03:14:07.999999'" MAX_RESULT +show create view vt1; + +--echo # VIEW over JOIN of versioned tables [tempesta-tech/mariadb#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 ('1970-01-01 00:00') cross join t2; +select * from vt12; + +--echo # VIEW improvements [tempesta-tech/mariadb#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 [tempesta-tech/mariadb#269] +create or replace view vt1 as select * from t1 union select * from t1; +select * from vt1; + +--echo # VIEW over UNION with non-versioned [tempesta-tech/mariadb#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 # +--echo # MDEV-14689 crash on second PS execute +--echo # +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 view v1; +drop tables t1, t2; + +--echo # +--echo # MDEV-15146 SQLError[4122]: View is not system versioned +--echo # +create or replace table t1 (a int) with system versioning; +insert t1 values (1),(2); +set @a=now(6); +create or replace view v1 as select * from t1; +delete from t1; +select * from v1; +select * from v1 for system_time as of @a; +show create view v1; + +--echo # +--echo # MDEV-15378 Valid query causes invalid view definition due to syntax limitation in FOR SYSTEM_TIME +--echo # +create or replace table t1 (i int) with system versioning; +select * from t1 for system_time as of now() - interval 6 second; +create or replace view v1 as select * from t1 for system_time as of date_sub(now(), interval 6 second); +show create view v1; + +drop view v1, vt1, vt12; +drop tables t1, t3; + +--echo # +--echo # MDEV-18727 improve DML operation of System Versioning +--echo # +--replace_result $sys_datatype_expl SYS_DATATYPE +eval create or replace table t1 ( + x int, + row_start $sys_datatype_expl as row start invisible, + row_end $sys_datatype_expl as row end invisible, + period for system_time (row_start, row_end) +) with system versioning; +insert into t1 values (1), (2); +create or replace view v1 as select * from t1 where x > 1; +--echo # update, delete +update v1 set x= x + 1; +select *, check_row(row_start, row_end) from t1 for system_time all order by x; +insert v1 values (4); +select *, check_row(row_start, row_end) from t1 for system_time all order by x; +delete from v1 where x < 4; +select *, check_row(row_start, row_end) from t1 for system_time all order by x; +--echo # multi-update +create or replace table t2 like t1; +insert into t2 values (1), (2); +create or replace view v2 as select * from t2 where x > 1; +update v1, v2 set v1.x= v1.x + 1, v2.x= v2.x + 1 where v1.x = v2.x + 2; +select *, check_row(row_start, row_end) from t1 for system_time all order by x; +select *, check_row(row_start, row_end) from t2 for system_time all order by x; +--echo # multi-delete +delete v1, v2 from v1 join v2 where v1.x = v2.x + 2; +select *, check_row(row_start, row_end) from t1 for system_time all order by x; +select *, check_row(row_start, row_end) from t2 for system_time all order by x; +--echo # replace +--replace_result $sys_datatype_expl SYS_DATATYPE +eval create or replace table t1 ( + x int primary key, y int, + row_start $sys_datatype_expl as row start invisible, + row_end $sys_datatype_expl as row end invisible, + period for system_time (row_start, row_end) +) with system versioning; +insert into t1 values (1, 0), (2, 0); +create or replace view v1 as select * from t1 where x > 1; +replace v1 values (1, 1); +replace v1 values (2, 1); +replace v1 values (3, 1); +--echo # REPLACE ignores VIEW condition because itself doesn't use WHERE +select *, check_row(row_start, row_end) from t1 for system_time all order by x, row_end; +--echo # insert-select, on duplicate key +insert v1 select * from t1 where x = 1 on duplicate key update x = v1.x - 1; +select *, check_row(row_start, row_end) from t1 for system_time all order by x, row_end; +drop view v1, v2; +drop tables t1, t2; + +--echo # +--echo # MDEV-21146 Assertion `m_lock_type == 2' in handler::ha_drop_table upon LOAD DATA +--echo # +create table t1 (a int); +create view v1 as select * from t1; +create or replace table t1 (b int) with system versioning; +--error ER_VIEW_INVALID +load data infile 'xx' into table v1; + +# cleanup +drop view v1; +drop table t1; + +--echo # +--echo # MDEV-21155 Assertion with versioned table upon DELETE from view of view after replacing first view +--echo # +create table t1 (a int); +insert into t1 values (1); +--replace_result $sys_datatype_expl SYS_DATATYPE +eval create table t2 ( + b int, + row_start $sys_datatype_expl as row start invisible, + row_end $sys_datatype_expl as row end invisible, + period for system_time (row_start, row_end) +) with system versioning; +insert into t2 values (2); +create view v1 as select * from t1; +create view v2 as select * from v1; +create or replace view v1 as select * from t2; +delete from v2; +select * from t1; +select *, check_row(row_start, row_end) from t2 for system_time all; + +# cleanup +drop view v2; +drop view v1; +drop table t1, t2; + +--echo # +--echo # MDEV-23779 Error upon querying the view, that selecting from versioned table with partitions +--echo # +create table t1 (i int) with system versioning +partition by system_time (partition p0 history, partition pn current); +create view v1 as select * from t1 partition (pn); +show create view v1; + +# cleanup +drop view v1; +drop table t1; + +--source suite/versioning/common_finish.inc |