summaryrefslogtreecommitdiffstats
path: root/mysql-test/suite/versioning
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 12:24:36 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 12:24:36 +0000
commit06eaf7232e9a920468c0f8d74dcf2fe8b555501c (patch)
treee2c7b5777f728320e5b5542b6213fd3591ba51e2 /mysql-test/suite/versioning
parentInitial commit. (diff)
downloadmariadb-06eaf7232e9a920468c0f8d74dcf2fe8b555501c.tar.xz
mariadb-06eaf7232e9a920468c0f8d74dcf2fe8b555501c.zip
Adding upstream version 1:10.11.6.upstream/1%10.11.6
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'mysql-test/suite/versioning')
-rw-r--r--mysql-test/suite/versioning/common.inc123
-rw-r--r--mysql-test/suite/versioning/common.opt1
-rw-r--r--mysql-test/suite/versioning/common_finish.inc12
-rw-r--r--mysql-test/suite/versioning/disabled.def11
-rw-r--r--mysql-test/suite/versioning/engines.combinations16
-rw-r--r--mysql-test/suite/versioning/engines.inc1
-rw-r--r--mysql-test/suite/versioning/innodb.combinations5
-rw-r--r--mysql-test/suite/versioning/innodb.inc1
-rw-r--r--mysql-test/suite/versioning/key_type.combinations3
-rw-r--r--mysql-test/suite/versioning/key_type.inc14
-rw-r--r--mysql-test/suite/versioning/r/alter.result812
-rw-r--r--mysql-test/suite/versioning/r/autoinc.result75
-rw-r--r--mysql-test/suite/versioning/r/binlog.result57
-rw-r--r--mysql-test/suite/versioning/r/commit_id.result114
-rw-r--r--mysql-test/suite/versioning/r/create.result661
-rw-r--r--mysql-test/suite/versioning/r/cte.result316
-rw-r--r--mysql-test/suite/versioning/r/data.result208
-rw-r--r--mysql-test/suite/versioning/r/debug.result106
-rw-r--r--mysql-test/suite/versioning/r/delete.result170
-rw-r--r--mysql-test/suite/versioning/r/delete_history.result242
-rw-r--r--mysql-test/suite/versioning/r/derived.result295
-rw-r--r--mysql-test/suite/versioning/r/foreign.result573
-rw-r--r--mysql-test/suite/versioning/r/insert.result321
-rw-r--r--mysql-test/suite/versioning/r/insert2.result86
-rw-r--r--mysql-test/suite/versioning/r/load_data.result10
-rw-r--r--mysql-test/suite/versioning/r/misc.result62
-rw-r--r--mysql-test/suite/versioning/r/not_embedded.result95
-rw-r--r--mysql-test/suite/versioning/r/online.result159
-rw-r--r--mysql-test/suite/versioning/r/optimized.result75
-rw-r--r--mysql-test/suite/versioning/r/partition,heap.rdiff221
-rw-r--r--mysql-test/suite/versioning/r/partition.result3450
-rw-r--r--mysql-test/suite/versioning/r/replace.result63
-rw-r--r--mysql-test/suite/versioning/r/rpl.result531
-rw-r--r--mysql-test/suite/versioning/r/rpl_mix.result66
-rw-r--r--mysql-test/suite/versioning/r/rpl_row.result107
-rw-r--r--mysql-test/suite/versioning/r/rpl_stmt.result50
-rw-r--r--mysql-test/suite/versioning/r/select,trx_id.rdiff11
-rw-r--r--mysql-test/suite/versioning/r/select.result710
-rw-r--r--mysql-test/suite/versioning/r/select2,trx_id.rdiff38
-rw-r--r--mysql-test/suite/versioning/r/select2.result347
-rw-r--r--mysql-test/suite/versioning/r/simple.result200
-rw-r--r--mysql-test/suite/versioning/r/sysvars.result256
-rw-r--r--mysql-test/suite/versioning/r/trx_id.result613
-rw-r--r--mysql-test/suite/versioning/r/update,trx_id.rdiff24
-rw-r--r--mysql-test/suite/versioning/r/update-big.result99
-rw-r--r--mysql-test/suite/versioning/r/update.result485
-rw-r--r--mysql-test/suite/versioning/r/view.result292
-rw-r--r--mysql-test/suite/versioning/t/alter.test705
-rw-r--r--mysql-test/suite/versioning/t/autoinc.test63
-rw-r--r--mysql-test/suite/versioning/t/binlog.test18
-rw-r--r--mysql-test/suite/versioning/t/commit_id.test98
-rw-r--r--mysql-test/suite/versioning/t/create.test498
-rw-r--r--mysql-test/suite/versioning/t/cte.test237
-rw-r--r--mysql-test/suite/versioning/t/data.test169
-rw-r--r--mysql-test/suite/versioning/t/debug.test108
-rw-r--r--mysql-test/suite/versioning/t/delete.test122
-rw-r--r--mysql-test/suite/versioning/t/delete_history.test246
-rw-r--r--mysql-test/suite/versioning/t/derived.test238
-rw-r--r--mysql-test/suite/versioning/t/foreign.combinations5
-rw-r--r--mysql-test/suite/versioning/t/foreign.test629
-rw-r--r--mysql-test/suite/versioning/t/insert.test269
-rw-r--r--mysql-test/suite/versioning/t/insert2.test86
-rw-r--r--mysql-test/suite/versioning/t/load_data.test18
-rw-r--r--mysql-test/suite/versioning/t/misc.test51
-rw-r--r--mysql-test/suite/versioning/t/not_embedded.test107
-rw-r--r--mysql-test/suite/versioning/t/online.test198
-rw-r--r--mysql-test/suite/versioning/t/optimized.test40
-rw-r--r--mysql-test/suite/versioning/t/partition.test2677
-rw-r--r--mysql-test/suite/versioning/t/replace.test80
-rw-r--r--mysql-test/suite/versioning/t/rpl.test446
-rw-r--r--mysql-test/suite/versioning/t/rpl_common.inc30
-rw-r--r--mysql-test/suite/versioning/t/rpl_mix.test19
-rw-r--r--mysql-test/suite/versioning/t/rpl_row.test59
-rw-r--r--mysql-test/suite/versioning/t/rpl_stmt.test4
-rw-r--r--mysql-test/suite/versioning/t/select.test490
-rw-r--r--mysql-test/suite/versioning/t/select2.test220
-rw-r--r--mysql-test/suite/versioning/t/simple.test89
-rw-r--r--mysql-test/suite/versioning/t/sysvars.test206
-rw-r--r--mysql-test/suite/versioning/t/trx_id.opt2
-rw-r--r--mysql-test/suite/versioning/t/trx_id.test633
-rw-r--r--mysql-test/suite/versioning/t/update-big.test108
-rw-r--r--mysql-test/suite/versioning/t/update.test419
-rw-r--r--mysql-test/suite/versioning/t/view.test229
-rw-r--r--mysql-test/suite/versioning/wait_system_clock.inc10
84 files changed, 21813 insertions, 0 deletions
diff --git a/mysql-test/suite/versioning/common.inc b/mysql-test/suite/versioning/common.inc
new file mode 100644
index 00000000..9b901846
--- /dev/null
+++ b/mysql-test/suite/versioning/common.inc
@@ -0,0 +1,123 @@
+if (!$TEST_VERSIONING_SO)
+{
+ --skip needs test_versioning plugin
+}
+source include/have_innodb.inc;
+--disable_query_log
+
+set @@session.time_zone='+00:00';
+set @@global.time_zone='+00:00';
+select ifnull(max(transaction_id), 0) into @start_trx_id from mysql.transaction_registry;
+set @test_start=now(6);
+
+delimiter ~~;
+create procedure if not exists verify_trt()
+begin
+ set @i= 0;
+ select
+ @i:= @i + 1 as No,
+ transaction_id > 0 as A,
+ commit_id > transaction_id as B,
+ begin_timestamp > @test_start as C,
+ commit_timestamp >= begin_timestamp as D
+ from mysql.transaction_registry
+ where transaction_id > @start_trx_id;
+ select ifnull(max(transaction_id), 0)
+ into @start_trx_id
+ from mysql.transaction_registry;
+end~~
+
+create procedure if not exists verify_trt_dummy(recs int)
+begin
+ declare i int default 1;
+ create temporary table tmp (No int, A bool, B bool, C bool, D bool);
+ while i <= recs do
+ insert into tmp values (i, 1, 1, 1, 1);
+ set i= i + 1;
+ end while;
+ select * from tmp;
+ drop table tmp;
+end~~
+
+delimiter ;~~
+
+let $default_engine= `select @@default_storage_engine`;
+let $non_default_engine= `select if(@@default_storage_engine = 'InnoDB', 'MyISAM', 'InnoDB')`;
+let $sys_datatype_expl= timestamp(6);
+let $sys_datatype_expl_uc= TIMESTAMP(6);
+let $sys_datatype_max= TIMESTAMP'2038-01-19 03:14:07.999999';
+
+if ($MTR_COMBINATION_MYISAM)
+{
+ --let $MTR_COMBINATION_TIMESTAMP= 1
+}
+if ($MTR_COMBINATION_TRADITIONAL)
+{
+ --let $MTR_COMBINATION_TIMESTAMP= 1
+}
+if ($MTR_COMBINATION_HEAP)
+{
+ --let $MTR_COMBINATION_TIMESTAMP= 1
+}
+if ($MTR_COMBINATION_TRX_ID)
+{
+ let $sys_datatype_expl= bigint(20) unsigned;
+ let $sys_datatype_expl_uc= BIGINT(20) UNSIGNED;
+ let $sys_datatype_max= 18446744073709551615;
+}
+
+eval create or replace function current_row(sys_trx_end $sys_datatype_expl)
+returns int
+deterministic
+ return sys_trx_end = $sys_datatype_max;
+
+eval create or replace function current_row_ts(sys_trx_end timestamp(6))
+returns int
+deterministic
+ return convert_tz(sys_trx_end, '+00:00', @@time_zone) = TIMESTAMP'2038-01-19 03:14:07.999999';
+
+delimiter ~~;
+eval create or replace function check_row(row_start $sys_datatype_expl, row_end $sys_datatype_expl)
+returns varchar(255)
+deterministic
+begin
+ if row_end < row_start then
+ return "ERROR: row_end < row_start";
+ elseif row_end = row_start then
+ return "ERROR: row_end == row_start";
+ elseif current_row(row_end) then
+ return "CURRENT ROW";
+ end if;
+ return "HISTORICAL ROW";
+end~~
+delimiter ;~~
+
+delimiter ~~;
+eval create or replace function check_row_slave(row_start $sys_datatype_expl, row_end $sys_datatype_expl)
+returns varchar(255)
+deterministic
+begin
+ if current_row(row_end) then
+ return "CURRENT ROW";
+ end if;
+ return "HISTORICAL ROW";
+end~~
+delimiter ;~~
+
+delimiter ~~;
+eval create or replace function check_row_ts(row_start timestamp(6), row_end timestamp(6))
+returns varchar(255)
+deterministic
+begin
+ if row_end < row_start then
+ return "ERROR: row_end < row_start";
+ elseif row_end = row_start then
+ return "ERROR: row_end == row_start";
+ elseif current_row_ts(row_end) then
+ return "CURRENT ROW";
+ end if;
+ return "HISTORICAL ROW";
+end~~
+delimiter ;~~
+
+--enable_query_log
diff --git a/mysql-test/suite/versioning/common.opt b/mysql-test/suite/versioning/common.opt
new file mode 100644
index 00000000..b55a187c
--- /dev/null
+++ b/mysql-test/suite/versioning/common.opt
@@ -0,0 +1 @@
+--plugin-load-add=$TEST_VERSIONING_SO
diff --git a/mysql-test/suite/versioning/common_finish.inc b/mysql-test/suite/versioning/common_finish.inc
new file mode 100644
index 00000000..503a692f
--- /dev/null
+++ b/mysql-test/suite/versioning/common_finish.inc
@@ -0,0 +1,12 @@
+--disable_query_log
+--disable_warnings
+drop procedure if exists verify_trt;
+drop procedure if exists verify_trt_dummy;
+drop function if exists current_row;
+drop function if exists check_row;
+drop function if exists check_row_slave;
+drop function if exists current_row_ts;
+drop function if exists check_row_ts;
+set @@global.time_zone= default;
+--enable_warnings
+--enable_query_log
diff --git a/mysql-test/suite/versioning/disabled.def b/mysql-test/suite/versioning/disabled.def
new file mode 100644
index 00000000..888298bb
--- /dev/null
+++ b/mysql-test/suite/versioning/disabled.def
@@ -0,0 +1,11 @@
+##############################################################################
+#
+# List the test cases that are to be disabled temporarily.
+#
+# Separate the test case name and the comment with ':'.
+#
+# <testcasename> : BUG#<xxxx> <date disabled> <disabler> <comment>
+#
+# Do not use any TAB characters for whitespace.
+#
+##############################################################################
diff --git a/mysql-test/suite/versioning/engines.combinations b/mysql-test/suite/versioning/engines.combinations
new file mode 100644
index 00000000..57e2af6c
--- /dev/null
+++ b/mysql-test/suite/versioning/engines.combinations
@@ -0,0 +1,16 @@
+[timestamp]
+default-storage-engine=innodb
+
+[trx_id]
+default-storage-engine=innodb
+
+[myisam]
+default-storage-engine=myisam
+
+[traditional]
+default-storage-engine=myisam
+sql-mode=traditional
+
+[heap]
+default-storage-engine=memory
+
diff --git a/mysql-test/suite/versioning/engines.inc b/mysql-test/suite/versioning/engines.inc
new file mode 100644
index 00000000..c841fece
--- /dev/null
+++ b/mysql-test/suite/versioning/engines.inc
@@ -0,0 +1 @@
+--source include/have_innodb.inc
diff --git a/mysql-test/suite/versioning/innodb.combinations b/mysql-test/suite/versioning/innodb.combinations
new file mode 100644
index 00000000..1a0812cf
--- /dev/null
+++ b/mysql-test/suite/versioning/innodb.combinations
@@ -0,0 +1,5 @@
+[timestamp]
+default-storage-engine=innodb
+
+[trx_id]
+default-storage-engine=innodb
diff --git a/mysql-test/suite/versioning/innodb.inc b/mysql-test/suite/versioning/innodb.inc
new file mode 100644
index 00000000..c841fece
--- /dev/null
+++ b/mysql-test/suite/versioning/innodb.inc
@@ -0,0 +1 @@
+--source include/have_innodb.inc
diff --git a/mysql-test/suite/versioning/key_type.combinations b/mysql-test/suite/versioning/key_type.combinations
new file mode 100644
index 00000000..93c0ea8b
--- /dev/null
+++ b/mysql-test/suite/versioning/key_type.combinations
@@ -0,0 +1,3 @@
+[unique]
+[pk]
+[sec]
diff --git a/mysql-test/suite/versioning/key_type.inc b/mysql-test/suite/versioning/key_type.inc
new file mode 100644
index 00000000..888a1d97
--- /dev/null
+++ b/mysql-test/suite/versioning/key_type.inc
@@ -0,0 +1,14 @@
+--disable_query_log
+if ($MTR_COMBINATION_UNIQUE)
+{
+ let $KEY_TYPE= unique;
+}
+if ($MTR_COMBINATION_PK)
+{
+ let $KEY_TYPE= primary key;
+}
+if ($MTR_COMBINATION_SEC)
+{
+ let $KEY_TYPE= key;
+}
+--enable_query_log
diff --git a/mysql-test/suite/versioning/r/alter.result b/mysql-test/suite/versioning/r/alter.result
new file mode 100644
index 00000000..9751f7c7
--- /dev/null
+++ b/mysql-test/suite/versioning/r/alter.result
@@ -0,0 +1,812 @@
+select @@system_versioning_alter_history;
+@@system_versioning_alter_history
+ERROR
+create table t(
+a int
+);
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+alter table t drop system versioning;
+ERROR HY000: Table `t` is not system-versioned
+alter table t add system versioning;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+alter table t add column y int;
+ERROR HY000: Not allowed for system-versioned `test`.`t`. Change @@system_versioning_alter_history to proceed with ALTER.
+alter table t add primary key (a);
+ERROR HY000: Not allowed for system-versioned `test`.`t`. Change @@system_versioning_alter_history to proceed with ALTER.
+alter table t add unique key (a);
+ERROR HY000: Not allowed for system-versioned `test`.`t`. Change @@system_versioning_alter_history to proceed with ALTER.
+alter table t engine innodb;
+ERROR HY000: Not allowed for system-versioned `test`.`t`. Change to/from native system versioning engine is not supported.
+alter table t drop system versioning;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+set system_versioning_alter_history= keep;
+alter table t add system versioning;
+alter table t drop system versioning, drop column row_start;
+ERROR 42000: Can't DROP COLUMN `row_start`; check that it exists
+alter table t drop system versioning;
+alter table t
+add column trx_start bigint(20) unsigned as row start invisible,
+add column trx_end bigint(20) unsigned as row end invisible,
+add period for system_time(trx_start, trx_end),
+add system versioning;
+ERROR HY000: `trx_start` must be of type TIMESTAMP(6) for system-versioned table `t`
+alter table t
+add column trx_start timestamp as row start invisible,
+add column trx_end timestamp as row end invisible,
+add period for system_time(trx_start, trx_end),
+add system versioning;
+ERROR HY000: `trx_start` must be of type TIMESTAMP(6) for system-versioned table `t`
+alter table t
+add column trx_start timestamp(6) not null as row start invisible,
+add column trx_end timestamp(6) not null as row end invisible,
+add period for system_time(trx_start, trx_end),
+add system versioning;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'as row start invisible,
+add column trx_end timestamp(6) not null as row end i...' at line 2
+alter table t
+add column trx_start timestamp(6) as row start invisible,
+add column trx_end timestamp(6) as row end invisible,
+add period for system_time(trx_start, trx_end),
+add system versioning;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `trx_start` timestamp(6) GENERATED ALWAYS AS ROW START INVISIBLE,
+ `trx_end` timestamp(6) GENERATED ALWAYS AS ROW END INVISIBLE,
+ PERIOD FOR SYSTEM_TIME (`trx_start`, `trx_end`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+alter table t drop system versioning;
+ERROR HY000: Wrong parameters for `t`: missing 'DROP COLUMN `trx_start`'
+alter table t drop column trx_start, drop column trx_end;
+select row_start from t;
+row_start
+alter table t drop system versioning;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+alter table t add column trx_start timestamp(6) as row start;
+ERROR HY000: Table `t` is not system-versioned
+alter table t add system versioning;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+alter table t add column trx_start timestamp(6) as row start;
+ERROR HY000: Duplicate ROW START column `trx_start`
+alter table t modify a int as row start;
+ERROR HY000: Duplicate ROW START column `a`
+alter table t add column b int;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+alter table t add column c int;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+alter table t add column d int first;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `d` int(11) DEFAULT NULL,
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+alter table t add column e int after d;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `d` int(11) DEFAULT NULL,
+ `e` int(11) DEFAULT NULL,
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+alter table t drop column a;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `d` int(11) DEFAULT NULL,
+ `e` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+create or replace table t (
+a int,
+row_start timestamp(6) as row start invisible,
+row_end timestamp(6) as row end invisible,
+period for system_time(row_start, row_end))
+with system versioning;
+select * from t for system_time all;
+a
+alter table t drop column row_start;
+ERROR HY000: Wrong parameters for `t`: missing 'DROP COLUMN `row_end`'
+alter table t drop column row_end;
+ERROR HY000: Wrong parameters for `t`: missing 'DROP COLUMN `row_start`'
+alter table t drop column row_start, drop column row_end;
+select * from t for system_time all;
+a
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+alter table t drop column row_start;
+ERROR 42000: Can't DROP COLUMN `row_start`; check that it exists
+alter table t drop column row_end;
+ERROR 42000: Can't DROP COLUMN `row_end`; check that it exists
+create or replace table t (
+a int,
+row_start timestamp(6) as row start invisible,
+row_end timestamp(6) as row end invisible,
+period for system_time(row_start, row_end))
+with system versioning;
+select * from t for system_time all;
+a
+alter table t drop column row_start, drop column row_end;
+select * from t for system_time all;
+a
+create or replace table t(
+a int
+);
+insert into t values(1);
+alter table t add system versioning;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+insert into t values(2);
+select * from t for system_time all;
+a
+1
+2
+select * from t;
+a
+1
+2
+update t set a=3 where a=1;
+select * from t;
+a
+3
+2
+select * from t for system_time all;
+a
+3
+2
+1
+select row_start from t where a=3 into @tm;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+alter table t add column b int;
+select @tm=row_start from t where a=3;
+@tm=row_start
+1
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+select * from t;
+a b
+3 NULL
+2 NULL
+select * from t for system_time all;
+a b
+3 NULL
+2 NULL
+1 NULL
+alter table t drop system versioning;
+select * from t;
+a b
+3 NULL
+2 NULL
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+alter table t modify a int with system versioning;
+ERROR HY000: Table `t` is not system-versioned
+alter table t modify a int without system versioning;
+ERROR HY000: Table `t` is not system-versioned
+alter table t add system versioning;
+alter table t modify a int without system versioning;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL WITHOUT SYSTEM VERSIONING,
+ `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+alter table t modify a int with system versioning;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+create or replace table t(
+a int
+) engine=innodb;
+alter table t
+add column trx_start timestamp(6) as row start invisible,
+add column trx_end timestamp(6) as row end invisible,
+add period for system_time(trx_start, trx_end),
+add system versioning;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `trx_start` timestamp(6) GENERATED ALWAYS AS ROW START INVISIBLE,
+ `trx_end` timestamp(6) GENERATED ALWAYS AS ROW END INVISIBLE,
+ PERIOD FOR SYSTEM_TIME (`trx_start`, `trx_end`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+# Issue #211: drop of system columns required before drop system versioning
+alter table t drop column trx_start, drop column trx_end;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+alter table t drop system versioning;
+insert into t values(1);
+call verify_trt;
+No A B C D
+alter table t
+add column trx_start bigint(20) unsigned as row start invisible,
+add column trx_end bigint(20) unsigned as row end invisible,
+add period for system_time(trx_start, trx_end),
+add system versioning;
+call verify_trt;
+No A B C D
+1 1 1 1 1
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START INVISIBLE,
+ `trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END INVISIBLE,
+ PERIOD FOR SYSTEM_TIME (`trx_start`, `trx_end`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+alter table t drop column trx_start, drop column trx_end;
+call verify_trt;
+No A B C D
+alter table t drop system versioning, algorithm=copy;
+call verify_trt;
+No A B C D
+alter table t add system versioning, algorithm=copy;
+call verify_trt;
+No A B C D
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+update t set a= 2;
+select * from t for system_time all;
+a
+2
+1
+alter table t add column b int, algorithm=copy;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+select * from t;
+a b
+2 NULL
+call verify_trt;
+No A B C D
+alter table t drop column b, algorithm=copy;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+select * from t for system_time all;
+a
+2
+1
+call verify_trt;
+No A B C D
+alter table t drop system versioning, algorithm=copy;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+call verify_trt;
+No A B C D
+create or replace table t (a int);
+insert t values (1),(2),(3),(4);
+alter table t add b int auto_increment null unique;
+select * from t;
+a b
+1 1
+2 2
+3 3
+4 4
+drop table t;
+create or replace table t (a int) with system versioning engine=innodb;
+insert into t values (1), (2), (3);
+delete from t where a<3;
+alter table t add b int not null unique;
+Got one of the listed errors
+alter table t add b int auto_increment unique;
+Got one of the listed errors
+alter table t add b int auto_increment null unique;
+select * from t;
+a b
+3 1
+select * from t for system_time all;
+a b
+1 NULL
+2 NULL
+3 1
+insert into t values (4, 0);
+select * from t for system_time all;
+a b
+1 NULL
+2 NULL
+3 1
+4 2
+alter table t add c int, drop system versioning;
+select * from t;
+a b c
+3 1 NULL
+4 2 NULL
+create or replace table t (a int) with system versioning;
+insert into t values (1), (2), (3);
+delete from t where a<3;
+alter table t add b int not null unique;
+Got one of the listed errors
+alter table t add b int auto_increment unique;
+Got one of the listed errors
+alter table t add b int auto_increment null unique;
+select * from t;
+a b
+3 1
+select * from t for system_time all;
+a b
+1 NULL
+2 NULL
+3 1
+insert into t values (4, 0);
+select * from t for system_time all;
+a b
+1 NULL
+2 NULL
+3 1
+4 2
+create or replace table t (a int, 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;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) NOT NULL,
+ `c` int(11) DEFAULT NULL,
+ PRIMARY KEY (`b`),
+ UNIQUE KEY `c` (`c`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+select * from t;
+a b c
+1 2 3
+1 3 4
+1 4 5
+create or replace table t (
+a int,
+row_start timestamp(6) as row start invisible,
+row_end timestamp(6) as row end invisible,
+period for system_time(row_start, row_end)
+) with system versioning;
+alter table t change column row_start asdf timestamp(6);
+ERROR HY000: Can not change system versioning field `row_start`
+insert into t values (1);
+alter table t modify column row_start bigint unsigned;
+ERROR HY000: Can not change system versioning field `row_start`
+set system_versioning_alter_history= SURVIVE;
+ERROR 42000: Variable 'system_versioning_alter_history' can't be set to the value of 'SURVIVE'
+set system_versioning_alter_history= 'DROP';
+ERROR 42000: Variable 'system_versioning_alter_history' can't be set to the value of 'DROP'
+create or replace table t (a int) with system versioning;
+alter table t add system versioning;
+ERROR HY000: Table `t` is already system-versioned
+alter table t add system versioning, drop system versioning;
+ERROR HY000: Table `t` is already system-versioned
+set @@system_versioning_alter_history=keep;
+create or replace table t(x int, y int) with system versioning engine=innodb;
+alter table t modify y int without system versioning;
+insert into t values(1, 1);
+update t set y=2;
+# MDEV-14681 Bogus ER_UNSUPPORTED_EXTENSION
+create or replace table t1 (pk int auto_increment unique) with system versioning;
+insert into t1 values (1);
+delete from t1;
+alter table t1 engine=myisam;
+# MDEV-14692 crash in MDL_context::upgrade_shared_lock()
+create or replace temporary table t (a int);
+alter table t change column if exists b c bigint unsigned generated always as row start;
+ERROR HY000: System-versioned tables do not support CREATE TEMPORARY TABLE
+alter table t change column if exists b c bigint unsigned generated always as row end;
+ERROR HY000: System-versioned tables do not support CREATE TEMPORARY TABLE
+alter table t add system versioning;
+ERROR HY000: System-versioned tables do not support CREATE TEMPORARY TABLE
+drop table t;
+# MDEV-14744 trx_id-based and transaction-based mixup in assertion
+create or replace table t (c text) engine=innodb with system versioning;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `c` text DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+alter table t add fulltext key (c);
+create or replace table t (a int) with system versioning;
+alter table t drop column a;
+ERROR HY000: Table `t` must have at least one versioned column
+alter table t drop column a, drop column a;
+ERROR 42000: Can't DROP COLUMN `a`; check that it exists
+create or replace table t1 (row_start int);
+alter table t1 with system versioning;
+ERROR 42S21: Duplicate column name 'row_start'
+create or replace table t1 (row_end int);
+alter table t1 with system versioning;
+ERROR 42S21: Duplicate column name 'row_end'
+create or replace table t1 (a int, row_start int) with system versioning;
+ERROR 42S21: Duplicate column name 'row_start'
+create or replace table t1 (a int) with system versioning;
+set statement system_versioning_alter_history=keep for
+alter table t1 add column row_start int;
+ERROR 42S21: Duplicate column name 'row_start'
+set statement system_versioning_alter_history=keep for
+alter table t1 add column row_start timestamp(6);
+ERROR 42S21: Duplicate column name 'row_start'
+# MDEV-14798 Add, drop system versioning semantic and syntax
+create or replace table t (
+a int,
+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;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `row_start` timestamp(6) GENERATED ALWAYS AS ROW START,
+ `row_end` timestamp(6) GENERATED ALWAYS AS ROW END,
+ PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+alter table t
+drop column row_start,
+drop column row_end,
+drop period for system_time,
+drop system versioning;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+alter table t drop period for system_time;
+ERROR HY000: Table `t` is not system-versioned
+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;
+alter table t drop period for system_time;
+ERROR HY000: Wrong parameters for `t`: missing 'DROP COLUMN `row_start`, DROP COLUMN `row_end`'
+alter table t drop column sys_trx_start, drop period for system_time;
+ERROR HY000: Wrong parameters for `t`: missing 'DROP COLUMN `row_start`, DROP COLUMN `row_end`'
+alter table t drop column sys_trx_end, drop period for system_time;
+ERROR HY000: Wrong parameters for `t`: missing 'DROP COLUMN `row_start`, DROP COLUMN `row_end`'
+alter table t add period for system_time(sys_trx_start, sys_trx_end);
+ERROR HY000: Table `t` is already system-versioned
+#
+# MDEV-14790 System versioning for system tables does not work as expected
+#
+use mysql;
+create or replace table t (x int) with system versioning;
+ERROR HY000: System-versioned tables in the `mysql` database are not supported
+alter table db add system versioning;
+ERROR HY000: System-versioned tables in the `mysql` database are not supported
+use test;
+# 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;
+alter table t1 modify s timestamp(6) as row start;
+ERROR HY000: Duplicate ROW START column `s`
+# 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;
+alter table t add check (a > 1);
+ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t`
+alter table t add check (a > 0);
+insert into t values (0);
+ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t`
+insert into t values (2);
+drop table t;
+#
+# MDEV-18869 Assertion `!((field)->vcol_info && (field)->stored_in_db())' failed in innodb_col_no upon altering table with system versioning
+#
+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);
+alter table t1 modify a int without system versioning, algorithm=copy;
+affected rows: 1
+info: Records: 1 Duplicates: 0 Warnings: 0
+alter table t1 modify a int with system versioning, algorithm=copy;
+affected rows: 1
+info: Records: 1 Duplicates: 0 Warnings: 0
+alter table t1 modify a int without system versioning;
+affected rows: 0
+info: Records: 0 Duplicates: 0 Warnings: 0
+alter table t1 modify a int with system versioning;
+affected rows: 0
+info: Records: 0 Duplicates: 0 Warnings: 0
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) GENERATED ALWAYS AS (0) STORED
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+select * from t1;
+a b
+1 0
+alter table t1 modify b int generated always as (0) stored without system versioning;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'without system versioning' at line 1
+alter table t1 modify b int generated always as (0) stored with system versioning;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'system versioning' at line 1
+alter table t1 modify b int without system versioning;
+affected rows: 1
+info: Records: 1 Duplicates: 0 Warnings: 0
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL WITHOUT SYSTEM VERSIONING
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+select * from t1;
+a b
+1 0
+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);
+alter table t1 modify a int without system versioning, algorithm=copy;
+affected rows: 1
+info: Records: 1 Duplicates: 0 Warnings: 0
+alter table t1 modify a int with system versioning, algorithm=copy;
+affected rows: 1
+info: Records: 1 Duplicates: 0 Warnings: 0
+alter table t1 modify a int without system versioning;
+affected rows: 0
+info: Records: 0 Duplicates: 0 Warnings: 0
+alter table t1 modify a int with system versioning;
+affected rows: 0
+info: Records: 0 Duplicates: 0 Warnings: 0
+select * from t1;
+a b
+1 0
+affected rows: 1
+#
+# MDEV-19304 Segfault in ALTER TABLE after UPDATE for SIMULTANEOUS_ASSIGNMENT
+#
+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;
+Warnings:
+Warning 1906 The value specified for generated column 'e' in table 't1' has been ignored
+Warning 1906 The value specified for generated column 'e' in table 't1' has been ignored
+alter table t1 force;
+set sql_mode= default;
+#
+# MDEV-18862 Unfortunate error message upon attempt to drop system versioning
+#
+set system_versioning_alter_history= keep;
+create or replace table t1 (x int) with system versioning;
+alter table t1 drop column `row_start`, drop column `row_end`, drop period for system_time, drop system versioning;
+ERROR 42000: Can't DROP PERIOD FOR SYSTEM_TIME on `t1`; check that it exists
+alter table t1 drop period for system_time;
+ERROR 42000: Can't DROP PERIOD FOR SYSTEM_TIME on `t1`; check that it exists
+alter table t1 drop column `row_start`, drop column `row_end`, drop system versioning;
+ERROR 42000: Can't DROP COLUMN `row_start`; check that it exists
+alter table t1 drop column `row_end`;
+ERROR 42000: Can't DROP COLUMN `row_end`; check that it exists
+#
+# MDEV-19127 Assertion `row_start_field' failed in vers_prepare_keys upon ALTER TABLE
+#
+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;
+alter table t1 drop system versioning, add f2 int with system versioning;
+ERROR HY000: Table `t1` is not system-versioned
+drop table t1;
+# 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;
+alter table t change column a a int without system versioning;
+ERROR HY000: Table `t` must have at least one versioned column
+alter table t
+change column a a int without system versioning,
+add column b int with system versioning;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL WITHOUT SYSTEM VERSIONING,
+ `b` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+alter table t
+change column a new_a int,
+drop system versioning;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `new_a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+alter table t add system versioning;
+alter table t change column new_a a int without system versioning;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL WITHOUT SYSTEM VERSIONING,
+ `b` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+alter table t
+add column c int,
+change column c c int without system versioning,
+change column b b int without system versioning;
+ERROR HY000: Table `t` must have at least one versioned column
+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;
+#
+# MDEV-21688 Assertion or ER_WARN_DATA_OUT_OF_RANGE upon ALTER on previously versioned table
+#
+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;
+drop table t1;
+#
+# MDEV-24690 Dropping primary key column from versioned table always fails with 1072
+#
+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;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) NOT NULL,
+ `row_start` timestamp(6) GENERATED ALWAYS AS ROW START,
+ `row_end` timestamp(6) GENERATED ALWAYS AS ROW END,
+ PRIMARY KEY (`b`,`row_end`),
+ PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+alter table t1 drop column b;
+ERROR 42000: Key column 'b' doesn't exist in table
+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;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) NOT NULL,
+ `row_start` timestamp(6) GENERATED ALWAYS AS ROW START INVISIBLE,
+ `row_end` timestamp(6) GENERATED ALWAYS AS ROW END INVISIBLE,
+ PRIMARY KEY (`b`,`row_end`),
+ PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+alter table t1 drop column b;
+ERROR 42000: Key column 'b' doesn't exist in table
+drop table t1;
+#
+# MDEV-25172 Wrong error message for ADD COLUMN .. AS ROW START
+#
+create or replace table t1 (x int);
+alter table t1 add column y timestamp(6) as row start;
+ERROR HY000: Table `t1` is not system-versioned
+drop table t1;
+#
+# MDEV-25327 Unexpected ER_DUP_ENTRY upon dropping PK column from system-versioned table
+#
+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;
+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;
+drop table t1;
+#
+# MDEV-22660 SIGSEGV on adding system versioning and modifying system column
+#
+create or replace table t1 (a int);
+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 HY000: PERIOD FOR SYSTEM_TIME must use columns `row_start` and `row_end`
+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);
+ERROR HY000: PERIOD FOR SYSTEM_TIME must use columns `row_start` and `row_end`
+drop table t1;
+#
+# MDEV-21941 RENAME doesn't work for system time or period fields
+#
+create or replace table t1 (a int) with system versioning;
+alter table t1 rename column row_start to x;
+ERROR 42S22: Unknown column 'row_start' in 't1'
+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;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `x` timestamp(6) GENERATED ALWAYS AS ROW START INVISIBLE,
+ `y` timestamp(6) GENERATED ALWAYS AS ROW END INVISIBLE,
+ PERIOD FOR SYSTEM_TIME (`x`, `y`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+drop table t1;
+# End of 10.5 tests
diff --git a/mysql-test/suite/versioning/r/autoinc.result b/mysql-test/suite/versioning/r/autoinc.result
new file mode 100644
index 00000000..e785c5d3
--- /dev/null
+++ b/mysql-test/suite/versioning/r/autoinc.result
@@ -0,0 +1,75 @@
+create table t1(
+id int unsigned auto_increment primary key,
+x int unsigned,
+y int unsigned,
+sys_start SYS_DATATYPE as row start invisible,
+sys_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_start, sys_end))
+with system versioning;
+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;
+A x y x y
+1 1 11 1 11
+1 2 12 2 12
+1 3 13 3 13
+1 4 14 4 14
+1 5 15 5 15
+1 6 16 6 16
+1 7 17 7 17
+1 8 18 8 18
+1 9 19 9 19
+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;
+A x y x y
+1 1 11 1 11
+1 3 13 3 13
+1 4 14 4 14
+1 5 15 5 15
+1 6 16 6 16
+1 7 17 7 17
+1 8 18 8 18
+1 9 19 9 19
+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;
+A x y x y
+1 1 11 1 11
+1 3 13 3 13
+1 4 14 4 14
+1 5 15 5 15
+1 6 16 6 16
+1 7 17 7 17
+drop table t1;
+drop table t2;
+#
+# MDEV-22562 Assertion `next_insert_id == 0' upon UPDATE on system-versioned table
+#
+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;
+drop table t1;
diff --git a/mysql-test/suite/versioning/r/binlog.result b/mysql-test/suite/versioning/r/binlog.result
new file mode 100644
index 00000000..0ebbf5fb
--- /dev/null
+++ b/mysql-test/suite/versioning/r/binlog.result
@@ -0,0 +1,57 @@
+#
+# MDEV-29741 SHOW BINLOG EVENTS shows garbage with system_versioning_insert_history=on
+# MDEV-29732 mysqlbinlog produces syntactically incorrect output with system_versioning_insert_history
+#
+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;
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `test`; create table t (a int) with system versioning
+master-bin.000001 # Gtid # # BEGIN GTID #-#-#
+master-bin.000001 # Query # # use `test`; set @@system_versioning_insert_history=1; insert into t (a) values (1)
+master-bin.000001 # Query # # set @@system_versioning_insert_history=1; COMMIT
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `test`; DROP TABLE `t` /* generated by server */
+flush binary logs;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
+/*!40019 SET @@session.max_delayed_threads=0*/;
+/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+DELIMITER /*!*/;
+ROLLBACK/*!*/;
+use `test`/*!*/;
+SET TIMESTAMP=1000000000/*!*/;
+SET @@session.pseudo_thread_id=999999999/*!*/;
+SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1, @@session.check_constraint_checks=1, @@session.sql_if_exists=0, @@session.explicit_defaults_for_timestamp=1, @@session.system_versioning_insert_history=0/*!*/;
+SET @@session.sql_mode=1411383296/*!*/;
+SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
+/*!\C latin1 *//*!*/;
+SET @@session.character_set_client=latin1,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
+SET @@session.lc_time_names=0/*!*/;
+SET @@session.collation_database=DEFAULT/*!*/;
+create table t (a int) with system versioning
+/*!*/;
+START TRANSACTION
+/*!*/;
+SET TIMESTAMP=1000000000/*!*/;
+SET @@session.system_versioning_insert_history=1/*!*/;
+insert into t (a) values (1)
+/*!*/;
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+SET TIMESTAMP=1000000000/*!*/;
+SET @@session.system_versioning_insert_history=0/*!*/;
+DROP TABLE `t` /* generated by server */
+/*!*/;
+DELIMITER ;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
+/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
+set timestamp=default;
diff --git a/mysql-test/suite/versioning/r/commit_id.result b/mysql-test/suite/versioning/r/commit_id.result
new file mode 100644
index 00000000..88156132
--- /dev/null
+++ b/mysql-test/suite/versioning/r/commit_id.result
@@ -0,0 +1,114 @@
+create table t1(
+id int auto_increment primary key,
+sys_trx_start bigint unsigned as row start invisible,
+sys_trx_end bigint unsigned as row end invisible,
+period for system_time (sys_trx_start, sys_trx_end)
+)
+with system versioning
+engine innodb;
+insert into t1 values ();
+set @ts0= now(6);
+insert into t1 values ();
+select sys_trx_start from t1 where id = last_insert_id() into @tx0;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+select transaction_id = @tx0 from mysql.transaction_registry
+order by transaction_id desc limit 1;
+transaction_id = @tx0
+1
+set @ts1= now(6);
+insert into t1 values ();
+select sys_trx_start from t1 where id = last_insert_id() into @tx1;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+select transaction_id = @tx1 from mysql.transaction_registry
+order by transaction_id desc limit 1;
+transaction_id = @tx1
+1
+set @ts2= now(6);
+insert into t1 values ();
+select sys_trx_start from t1 where id = last_insert_id() into @tx2;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+select transaction_id = @tx2 from mysql.transaction_registry
+order by transaction_id desc limit 1;
+transaction_id = @tx2
+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;
+A B C D E F G H
+1 1 1 1 1 1 1 1
+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;
+A B C D E F G H
+1 1 1 1 1 1 1 1
+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;
+A B C D E F
+1 1 1 1 1 1
+select trt_trx_sees(0, @tx2);
+trt_trx_sees(0, @tx2)
+0
+set transaction isolation level read uncommitted;
+insert into t1 values ();
+select sys_trx_start from t1 where id = last_insert_id() into @tx3;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+select isolation_level = 'READ-UNCOMMITTED' from mysql.transaction_registry where transaction_id = @tx3;
+isolation_level = 'READ-UNCOMMITTED'
+1
+set transaction isolation level read committed;
+insert into t1 values ();
+select sys_trx_start from t1 where id = last_insert_id() into @tx4;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+select isolation_level = 'READ-COMMITTED' from mysql.transaction_registry where transaction_id = @tx4;
+isolation_level = 'READ-COMMITTED'
+1
+set transaction isolation level serializable;
+insert into t1 values ();
+select sys_trx_start from t1 where id = last_insert_id() into @tx5;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+select isolation_level = 'SERIALIZABLE' from mysql.transaction_registry where transaction_id = @tx5;
+isolation_level = 'SERIALIZABLE'
+1
+set transaction isolation level repeatable read;
+insert into t1 values ();
+select sys_trx_start from t1 where id = last_insert_id() into @tx6;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+select isolation_level = 'REPEATABLE-READ' from mysql.transaction_registry where transaction_id = @tx6;
+isolation_level = 'REPEATABLE-READ'
+1
+drop table t1;
+call verify_trt;
+No A B C D
+1 1 1 1 1
+2 1 1 1 1
+3 1 1 1 1
+4 1 1 1 1
+5 1 1 1 1
+6 1 1 1 1
+7 1 1 1 1
+8 1 1 1 1
diff --git a/mysql-test/suite/versioning/r/create.result b/mysql-test/suite/versioning/r/create.result
new file mode 100644
index 00000000..c9d68f15
--- /dev/null
+++ b/mysql-test/suite/versioning/r/create.result
@@ -0,0 +1,661 @@
+create table t1 (
+x1 int unsigned,
+Sys_start SYS_DATATYPE as row start invisible comment 'start',
+Sys_end SYS_DATATYPE as row end invisible comment 'end',
+period for system_time (Sys_start, Sys_end)
+) with system versioning;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x1` int(10) unsigned DEFAULT NULL,
+ `Sys_start` SYS_DATATYPE GENERATED ALWAYS AS ROW START INVISIBLE COMMENT 'start',
+ `Sys_end` SYS_DATATYPE GENERATED ALWAYS AS ROW END INVISIBLE COMMENT 'end',
+ PERIOD FOR SYSTEM_TIME (`Sys_start`, `Sys_end`)
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+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';
+table_catalog def
+table_schema test
+table_name t1
+table_type SYSTEM VERSIONED
+version 10
+table_rows 0
+data_free 0
+auto_increment NULL
+check_time NULL
+table_collation latin1_swedish_ci
+checksum NULL
+create_options
+table_comment
+select table_catalog,table_schema,table_name,column_name,ordinal_position,column_default,character_maximum_length,character_octet_length,character_set_name,collation_name,column_key,extra,column_comment,is_generated,generation_expression from information_schema.columns where table_name='t1';
+table_catalog def
+table_schema test
+table_name t1
+column_name x1
+ordinal_position 1
+column_default NULL
+character_maximum_length NULL
+character_octet_length NULL
+character_set_name NULL
+collation_name NULL
+column_key
+extra
+column_comment
+is_generated NEVER
+generation_expression NULL
+table_catalog def
+table_schema test
+table_name t1
+column_name Sys_start
+ordinal_position 2
+column_default NULL
+character_maximum_length NULL
+character_octet_length NULL
+character_set_name NULL
+collation_name NULL
+column_key
+extra STORED GENERATED, INVISIBLE
+column_comment start
+is_generated ALWAYS
+generation_expression ROW START
+table_catalog def
+table_schema test
+table_name t1
+column_name Sys_end
+ordinal_position 3
+column_default NULL
+character_maximum_length NULL
+character_octet_length NULL
+character_set_name NULL
+collation_name NULL
+column_key
+extra STORED GENERATED, INVISIBLE
+column_comment end
+is_generated ALWAYS
+generation_expression ROW END
+# Implicit fields test
+create or replace table t1 (
+x2 int unsigned
+) with system versioning;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x2` int(10) unsigned DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+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;
+ERROR HY000: PERIOD FOR SYSTEM_TIME must use columns `Sys_start` and `Sys_end`
+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;
+ERROR HY000: PERIOD FOR SYSTEM_TIME must use columns `Sys_start` and `Sys_end2`
+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 HY000: PERIOD FOR SYSTEM_TIME must use columns `Sys_start` and `Sys_end`
+create or replace table t1 (
+x6 int unsigned,
+period for system_time (Sys_start, Sys_end)
+) with system versioning;
+ERROR HY000: Wrong parameters for `t1`: missing 'AS ROW START'
+create or replace table t1 (
+x7 int unsigned,
+Sys_start timestamp(6) as row start invisible,
+Sys_end timestamp(6) as row end invisible,
+period for system_time (Sys_start, Sys_end)
+);
+ERROR HY000: Wrong parameters for `t1`: missing 'WITH SYSTEM VERSIONING'
+create or replace table t1 (
+x8 int unsigned,
+Sys_start 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;
+ERROR HY000: PERIOD FOR SYSTEM_TIME must use columns `Sys_start` and `Sys_end`
+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)
+);
+ERROR HY000: Wrong parameters for `t1`: missing 'WITH SYSTEM VERSIONING'
+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 HY000: Wrong parameters for `t1`: missing 'WITH SYSTEM VERSIONING'
+create or replace table t1 (
+x11 int unsigned,
+Sys_start bigint unsigned as row start invisible,
+Sys_end timestamp(6) as row end invisible,
+period for system_time (Sys_start, Sys_end)
+) with system versioning;
+Got one of the listed errors
+create or replace table t1 (
+x12 int unsigned,
+Sys_start timestamp(6) as row start invisible,
+Sys_end bigint unsigned as row end invisible,
+period for system_time (Sys_start, Sys_end)
+) with system versioning;
+Got one of the listed errors
+create or replace table t1 (
+x13 int unsigned,
+Sys_start bigint as row start invisible,
+Sys_end bigint unsigned as row end invisible,
+period for system_time (Sys_start, Sys_end)
+) with system versioning engine innodb;
+ERROR HY000: `Sys_start` must be of type BIGINT(20) UNSIGNED for system-versioned table `t1`
+create or replace table t1 (
+x14 int unsigned,
+Sys_start bigint unsigned as row start invisible,
+Sys_end bigint as row end invisible,
+period for system_time (Sys_start, Sys_end)
+) with system versioning engine innodb;
+ERROR HY000: `Sys_end` must be of type BIGINT(20) UNSIGNED for system-versioned table `t1`
+create or replace table t1 (
+x15 int with system versioning,
+B int
+);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x15` int(11) DEFAULT NULL,
+ `B` int(11) DEFAULT NULL WITHOUT SYSTEM VERSIONING
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+create or replace table t1 (
+x16 int with system versioning,
+B int
+) with system versioning;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x16` int(11) DEFAULT NULL,
+ `B` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+create or replace table t1 (
+x17 int,
+B int without system versioning
+);
+create or replace table t1 (
+x18 int,
+B int without system versioning
+) with system versioning;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x18` int(11) DEFAULT NULL,
+ `B` int(11) DEFAULT NULL WITHOUT SYSTEM VERSIONING
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+create or replace table t1 (
+x19 int with system versioning,
+B int without system versioning
+);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x19` int(11) DEFAULT NULL,
+ `B` int(11) DEFAULT NULL WITHOUT SYSTEM VERSIONING
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+create or replace table t1 (
+x20 int with system versioning,
+B int without system versioning
+) with system versioning;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x20` int(11) DEFAULT NULL,
+ `B` int(11) DEFAULT NULL WITHOUT SYSTEM VERSIONING
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+create or replace table t1 (
+x21 int without system versioning
+);
+create or replace table t1 (
+x22 int without system versioning
+) with system versioning;
+ERROR HY000: Table `t1` must have at least one versioned column
+create or replace table t1 (a int) with system versioning;
+create table tt1 like t1;
+show create table tt1;
+Table Create Table
+tt1 CREATE TABLE `tt1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+drop table tt1;
+create temporary table tt1 like t1;
+Warnings:
+Warning 1105 System versioning is stripped from temporary `test.tt1`
+# Temporary is stripped from versioning
+show create table tt1;
+Table Create Table
+tt1 CREATE TEMPORARY TABLE `tt1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+# CREATE TABLE ... SELECT
+create or replace table t1 (x23 int) with system versioning;
+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;
+## For non-versioned table:
+### 1. invisible fields are not included
+create or replace table t2 as select * from t1;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `x23` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+### 2. all visible fields are included
+create or replace table t3 as select * from t0;
+select * from t0;
+y st en
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `y` int(11) DEFAULT NULL,
+ `st` timestamp(6) NOT NULL,
+ `en` timestamp(6) NOT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+## For versioned table
+insert into t1 values (1);
+select row_start from t1 into @row_start;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+insert into t0 (y) values (2);
+select st from t0 into @st;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+create or replace table t2 with system versioning as select * from t1;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `x23` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+#### invisible fields are not copied
+select * from t2;
+x23
+1
+select * from t2 where row_start <= @row_start;
+x23
+### 2. source table with visible system fields, target with invisible
+create or replace table t3 with system versioning as select * from t0;
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `y` int(11) DEFAULT NULL,
+ `st` timestamp(6) NOT NULL,
+ `en` timestamp(6) NOT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+select * from t3 where y > 2;
+y st en
+select y from t3 where st = @st and row_start > @st;
+y
+2
+### 3. source and target table with visible system fields
+create or replace table t3 (
+st 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;
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `y` int(11) DEFAULT NULL,
+ `st` timestamp(6) GENERATED ALWAYS AS ROW START INVISIBLE,
+ `en` timestamp(6) GENERATED ALWAYS AS ROW END INVISIBLE,
+ PERIOD FOR SYSTEM_TIME (`st`, `en`)
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+select y from t3;
+y
+2
+select y from t3 where st = @st;
+y
+### 4. system fields not or wrongly selected
+create or replace table t3 with system versioning select x23 from t1;
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `x23` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+select * from t3;
+x23
+1
+create or replace table t3 with system versioning select x23, row_start from t1;
+ERROR 42S21: Duplicate column name 'row_start'
+create or replace table t3 with system versioning select x23, row_end from t1;
+ERROR 42S21: Duplicate column name 'row_end'
+# Prepare checking for historical row
+delete from t1;
+select row_end from t1 for system_time all into @row_end;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+delete from t0;
+select en from t0 for system_time all into @en;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+## Combinations of versioned + non-versioned
+create or replace table t2 (y int);
+insert into t2 values (3);
+create or replace table t3 with system versioning select * from t1 for system_time all, t2;
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `x23` int(11) DEFAULT NULL,
+ `y` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+select * from t3 for system_time all;
+x23 y
+1 3
+select * from t3 for system_time all where row_start = @row_start and row_end = @row_end;
+x23 y
+create or replace table t2 like t0;
+insert into t2 (y) values (1), (2);
+delete from t2 where y = 2;
+create or replace table t3 select * from t2 for system_time all;
+select st, en from t3 where y = 1 into @st, @en;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+select y from t2 for system_time all where st = @st and en = @en;
+y
+1
+select st, en from t3 where y = 2 into @st, @en;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+select y from t2 for system_time all where st = @st and en = @en;
+y
+2
+## Default engine detection
+create or replace table t1 (x25 int) with system versioning engine NON_DEFAULT_ENGINE;
+create or replace table t2
+as select x25, row_start, row_end from t1 for system_time all;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `x25` int(11) DEFAULT NULL,
+ `row_start` timestamp(6) NOT NULL,
+ `row_end` timestamp(6) NOT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+create or replace table t2 with system versioning
+as select x25, row_start rs, row_end re from t1;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `x25` int(11) DEFAULT NULL,
+ `rs` timestamp(6) NOT NULL,
+ `re` timestamp(6) NOT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+create or replace table t1 (
+x26 int,
+st bigint unsigned as row start,
+en bigint unsigned as row end,
+period for system_time (st, en)
+) with system versioning engine innodb;
+create or replace table t2 with system versioning engine myisam
+as select * from t1;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `x26` int(11) DEFAULT NULL,
+ `st` bigint(20) unsigned NOT NULL,
+ `en` bigint(20) unsigned NOT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+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;
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `b` int(11) DEFAULT NULL,
+ `x27` int(11) DEFAULT NULL,
+ `rs` timestamp(6) NOT NULL,
+ `re` timestamp(6) NOT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+## Errors
+create or replace temporary table t (x28 int) with system versioning;
+ERROR HY000: System-versioned tables do not support CREATE TEMPORARY TABLE
+create or replace table t1 (
+x29 int unsigned,
+Sys_start0 timestamp(6) as row start invisible,
+Sys_start timestamp(6) as row start invisible,
+Sys_end timestamp(6) as row end invisible,
+period for system_time (Sys_start, Sys_end)
+) with system versioning;
+ERROR HY000: Duplicate ROW START column `Sys_start`
+create or replace table t1 (
+x29 int unsigned,
+Sys_end0 timestamp(6) as row end invisible,
+Sys_start timestamp(6) as row start invisible,
+Sys_end timestamp(6) as row end invisible,
+period for system_time (Sys_start, Sys_end)
+) with system versioning;
+ERROR HY000: Duplicate ROW END column `Sys_end`
+## System fields detection
+create or replace table t1 (x30 int) with system versioning;
+create or replace table t2 (
+y int,
+st 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;
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `x30` int(11) DEFAULT NULL,
+ `y` int(11) DEFAULT NULL,
+ `row_start` timestamp(6) NOT NULL,
+ `row_end` timestamp(6) NOT NULL,
+ `st` timestamp(6) NOT NULL,
+ `en` timestamp(6) NOT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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;
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `x30` int(11) DEFAULT NULL,
+ `y` int(11) DEFAULT NULL,
+ `row_start` timestamp(6) NOT NULL,
+ `row_end` timestamp(6) NOT NULL,
+ `st` timestamp(6) GENERATED ALWAYS AS ROW START INVISIBLE,
+ `en` timestamp(6) GENERATED ALWAYS AS ROW END INVISIBLE,
+ PERIOD FOR SYSTEM_TIME (`st`, `en`)
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+# MDEV-14828 Server crashes in JOIN::prepare / setup_fields on 2nd execution of PS [#437]
+create or replace table t1 (x int) with system versioning;
+prepare bad from 'create or replace table t2 with system versioning as select * from t1';
+execute bad;
+execute bad;
+execute bad;
+execute bad;
+execute bad;
+execute bad;
+execute bad;
+execute bad;
+# bad is good.
+# 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;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` int(1) NOT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+create or replace table t1 (i int) with system versioning as select 1 as i;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+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 HY000: `row_start` must be of type BIGINT(20) UNSIGNED for system-versioned table `t1`
+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 HY000: `row_start` must be of type BIGINT(20) UNSIGNED for system-versioned table `t1`
+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;
+ERROR HY000: `row_start` must be of type TIMESTAMP(6) for system-versioned table `t`
+# 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;
+create or replace table t1 (x int without system versioning)
+with system versioning
+select 1 as x;
+ERROR HY000: Table `t1` must have at least one versioned column
+drop tables t0, t1, t2, t3;
+#
+# MDEV-23968 CREATE TEMPORARY TABLE .. LIKE (system versioned table) returns error if unique index is defined in the table
+#
+create table t1 (id int primary key, index(row_start)) with system versioning;
+ERROR 42000: Key column 'row_start' doesn't exist in table
+create table t1 (id int primary key, index(row_end)) with system versioning;
+ERROR 42000: Key column 'row_end' doesn't exist in table
+create table t1 (id int, primary key(id, row_end, row_end)) with system versioning;
+ERROR 42000: Key column 'row_end' doesn't exist in table
+create table t1 (id int primary key) with system versioning;
+create temporary table t2 like t1;
+Warnings:
+Warning 1105 System versioning is stripped from temporary `test.t2`
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+show create table t2;
+Table Create Table
+t2 CREATE TEMPORARY TABLE `t2` (
+ `id` int(11) NOT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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;
+Warnings:
+Warning 1105 System versioning is stripped from temporary `test.t2`
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL,
+ `row_start` timestamp(6) GENERATED ALWAYS AS ROW START,
+ `row_end` timestamp(6) GENERATED ALWAYS AS ROW END,
+ PRIMARY KEY (`row_end`,`a`,`row_start`),
+ KEY `row_start` (`row_start`),
+ KEY `row_end` (`row_end`),
+ KEY `row_end_2` (`row_end`,`row_start`,`a`),
+ PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`)
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+show create table t2;
+Table Create Table
+t2 CREATE TEMPORARY TABLE `t2` (
+ `a` int(11) NOT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+drop temporary table t2;
+drop table t1;
+#
+# MDEV-16857 system-invisible row_end is displayed in SHOW INDEX
+#
+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';
+table_schema table_name non_unique index_schema index_name seq_in_index column_name
+test t1 0 test PRIMARY 1 id
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment Ignored
+t1 0 PRIMARY 1 id # # # # # # NO
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) NOT NULL,
+ `x` int(11) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+drop table t1;
+#
+# MDEV-26928 Column-inclusive WITH SYSTEM VERSIONING doesn't work with explicit system fields
+#
+create or replace table t1 (x int, y int with system versioning);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL WITHOUT SYSTEM VERSIONING,
+ `y` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+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));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL WITHOUT SYSTEM VERSIONING,
+ `y` int(11) DEFAULT NULL,
+ `row_start` timestamp(6) GENERATED ALWAYS AS ROW START,
+ `row_end` timestamp(6) GENERATED ALWAYS AS ROW END,
+ PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`)
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+drop table t1;
+#
+# MDEV-27452 TIMESTAMP(0) system field is allowed for certain creation of system-versioned table
+#
+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 HY000: `s` must be of type TIMESTAMP(6) for system-versioned table `t`
+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));
+ERROR HY000: `s` must be of type TIMESTAMP(6) for system-versioned table `t`
+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 (),();
+drop table t;
diff --git a/mysql-test/suite/versioning/r/cte.result b/mysql-test/suite/versioning/r/cte.result
new file mode 100644
index 00000000..6ca9c238
--- /dev/null
+++ b/mysql-test/suite/versioning/r/cte.result
@@ -0,0 +1,316 @@
+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;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 8 100.00
+2 DERIVED e ALL NULL NULL NULL NULL 4 100.00 Using where
+3 UNION e ALL NULL NULL NULL NULL 4 100.00 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 with ancestors as (/* select#2 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` where `test`.`e`.`name` = 'bill' and `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1` union /* select#3 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` where `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1`)/* select#1 */ select `ancestors`.`emp_id` AS `emp_id`,`ancestors`.`name` AS `name`,`ancestors`.`mgr` AS `mgr`,`ancestors`.`salary` AS `salary` from `ancestors`
+select row_start into @ts_2 from emp where name="john";
+explain extended /* 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;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 100.00
+2 DERIVED e ALL NULL NULL NULL NULL 4 100.00 Using where
+3 RECURSIVE UNION e ALL mgr-fk NULL NULL NULL 4 100.00 Using where
+3 RECURSIVE UNION <derived2> ref key0 key0 5 test.e.mgr 2 100.00
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 with recursive ancestors as (/* select#2 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` where `test`.`e`.`name` = 'bill' and `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1` union /* select#3 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` join `ancestors` `a` where `a`.`emp_id` = `test`.`e`.`mgr` and `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1`)/* select#1 */ select `ancestors`.`emp_id` AS `emp_id`,`ancestors`.`name` AS `name`,`ancestors`.`mgr` AS `mgr`,`ancestors`.`salary` AS `salary` from `ancestors`
+/* All report to 'Bill' */
+with recursive
+ancestors
+as
+(
+select e.emp_id, e.name, e.mgr, e.salary
+from emp for system_time as of timestamp @ts_1 as e
+where name = 'bill'
+ union
+select e.emp_id, e.name, e.mgr, e.salary
+from emp for system_time as of timestamp @ts_1 as e,
+ancestors as a
+where e.mgr = a.emp_id
+)
+select * from ancestors;
+emp_id name mgr salary
+1 bill NULL 1000
+20 john 1 500
+30 jane 1 750
+explain extended 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;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 100.00
+2 DERIVED e ALL NULL NULL NULL NULL 4 100.00 Using where
+3 RECURSIVE UNION e ALL mgr-fk NULL NULL NULL 4 100.00 Using where
+3 RECURSIVE UNION <derived2> ref key0 key0 5 test.e.mgr 2 100.00
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 with recursive ancestors as (/* select#2 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` where `test`.`e`.`name` = 'bill' and `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1` union /* select#3 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` join `ancestors` `a` where `a`.`emp_id` = `test`.`e`.`mgr` and `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1`)/* select#1 */ select `ancestors`.`emp_id` AS `emp_id`,`ancestors`.`name` AS `name`,`ancestors`.`mgr` AS `mgr`,`ancestors`.`salary` AS `salary` from `ancestors`
+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;
+emp_id name mgr salary
+1 bill NULL 1000
+20 john 1 500
+30 jane 1 750
+explain extended 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);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY emp ALL PRIMARY NULL NULL NULL 4 100.00 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.emp.emp_id 2 100.00 FirstMatch(emp)
+2 DERIVED e ALL NULL NULL NULL NULL 4 100.00 Using where
+3 RECURSIVE UNION e ALL mgr-fk NULL NULL NULL 4 100.00 Using where
+3 RECURSIVE UNION <derived2> ref key0 key0 5 test.e.mgr 2 100.00
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 with recursive ancestors as (/* select#2 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` where `test`.`e`.`name` = 'bill' and `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1` union /* select#3 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` join `ancestors` `a` where `a`.`emp_id` = `test`.`e`.`mgr` and `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1`)/* select#1 */ select `test`.`emp`.`name` AS `name` from `test`.`emp` semi join (`ancestors`) where `ancestors`.`emp_id` = `test`.`emp`.`emp_id` and `test`.`emp`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999'
+with recursive
+ancestors
+as
+(
+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);
+name
+bill
+john
+jane
+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;
+emp_id name mgr salary emp_id name mgr salary
+1 bill NULL 1000 1 bill NULL 1000
+30 jane 1 750 1 bill NULL 1000
+20 john 30 500 1 bill NULL 1000
+1 bill NULL 1000 30 jane 1 750
+30 jane 1 750 30 jane 1 750
+20 john 30 500 30 jane 1 750
+1 bill NULL 1000 20 john 30 500
+30 jane 1 750 20 john 30 500
+20 john 30 500 20 john 30 500
+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 HY000: Conflicting FOR SYSTEM_TIME clauses in WITH RECURSIVE
+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 HY000: Conflicting FOR SYSTEM_TIME clauses in WITH RECURSIVE
+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 HY000: Conflicting FOR SYSTEM_TIME clauses in WITH RECURSIVE
+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);
+ERROR HY000: Conflicting FOR SYSTEM_TIME clauses in WITH RECURSIVE
+# SYSTEM_TIME to internal recursive instance is prohibited
+with recursive cte as
+(
+select * from emp
+union all
+select * from cte for system_time as of @ts_1
+)
+select * from cte;
+ERROR HY000: Table `cte` is not system-versioned
+create or replace table emp ( emp_id int, name varchar(127), mgr int) with system versioning;
+create or replace table addr ( emp_id int, address varchar(100)) with system versioning;
+insert emp values (1, 'bill', 0), (2, 'bill', 1), (3, 'kate', 1);
+insert addr values (1, 'Moscow'), (2, 'New York'), (3, 'London');
+set @ts=now(6);
+delete from emp;
+delete from addr;
+with recursive
+ancestors
+as
+(
+select e.emp_id, e.name, e.mgr
+from emp for system_time as of timestamp @ts as e
+where name = 'bill'
+ union
+select ee.emp_id, ee.name, ee.mgr
+from emp for system_time as of timestamp @ts as ee, ancestors as a
+where ee.mgr = a.emp_id
+)
+select * from ancestors;
+emp_id name mgr
+1 bill 0
+2 bill 1
+3 kate 1
+insert emp values (4, 'john', 1);
+insert addr values (4, 'Paris');
+with ancestors as (select * from emp natural join addr) select * from ancestors;
+emp_id name mgr address
+4 john 1 Paris
+with ancestors as (select * from emp natural join addr) select * from ancestors for system_time all;
+emp_id name mgr address
+1 bill 0 Moscow
+2 bill 1 New York
+3 kate 1 London
+4 john 1 Paris
+with ancestors as (select * from (select * from emp natural join addr) for system_time all as t) select * from ancestors;
+emp_id name mgr address
+1 bill 0 Moscow
+2 bill 1 New York
+3 kate 1 London
+4 john 1 Paris
+select * from (select * from emp natural join addr) for system_time all as t;
+emp_id name mgr address
+1 bill 0 Moscow
+2 bill 1 New York
+3 kate 1 London
+4 john 1 Paris
+drop table emp;
+drop table dept;
+drop table addr;
+SET GLOBAL innodb_stats_persistent = @saved_stats_persistent;
diff --git a/mysql-test/suite/versioning/r/data.result b/mysql-test/suite/versioning/r/data.result
new file mode 100644
index 00000000..c7fe141c
--- /dev/null
+++ b/mysql-test/suite/versioning/r/data.result
@@ -0,0 +1,208 @@
+#
+# MDEV-16355 Add option for mysqldump to read data as of specific timestamp from system-versioned tables
+#
+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;
+#MYSQL_DUMP --compact test
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING;
+/*!40101 SET character_set_client = @saved_cs_client */;
+INSERT INTO `t1` VALUES
+(3);
+#MYSQL_DUMP --compact --as-of="1990-01-02 00:00" test
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING;
+/*!40101 SET character_set_client = @saved_cs_client */;
+INSERT INTO `t1` VALUES
+(1),
+(2),
+(3);
+#MYSQL_DUMP --compact --as-of="1990-08-02 00:00" --databases test
+
+CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */;
+
+USE `test`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING;
+/*!40101 SET character_set_client = @saved_cs_client */;
+INSERT INTO `t1` VALUES
+(1),
+(2),
+(3);
+#MYSQL_DUMP --compact --as-of="1990-08-04 00:00" test t1
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING;
+/*!40101 SET character_set_client = @saved_cs_client */;
+INSERT INTO `t1` VALUES
+(2),
+(3);
+#MYSQL_DUMP --compact --as-of="1990-08-04 00:00' where 'abc" test 2>&1
+mariadb-dump: Incorrect DATETIME value: '1990-08-04 00:00' where 'abc'
+drop tables t1;
+#
+# MDEV-16029 mysqldump: dump and restore historical data
+#
+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;
+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;
+# 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;
+x check_fields(x, row_start, row_end)
+1 [CORRECT]
+2 [CORRECT]
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING;
+/*!40101 SET character_set_client = @saved_cs_client */;
+/*!101100 SET @old_system_versioning_insert_history=@@session.system_versioning_insert_history, @@session.system_versioning_insert_history=1 */;
+INSERT INTO `t1` (`x`, row_start, row_end) VALUES (1,'2010-10-10 10:10:10.101010','2011-11-11 11:11:11.111111'),
+(2,'2010-10-10 10:10:10.101010','2038-01-19 03:14:07.999999');
+/*!101100 SET system_versioning_insert_history=@old_system_versioning_insert_history */;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t2` (
+ `x` int(11) DEFAULT NULL,
+ `row_start` timestamp(6) GENERATED ALWAYS AS ROW START INVISIBLE,
+ `row_end` timestamp(6) GENERATED ALWAYS AS ROW END INVISIBLE,
+ PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING;
+/*!40101 SET character_set_client = @saved_cs_client */;
+/*!101100 SET @old_system_versioning_insert_history=@@session.system_versioning_insert_history, @@session.system_versioning_insert_history=1 */;
+INSERT INTO `t2` (`x`, `row_start`, `row_end`) VALUES (1,'2010-10-10 10:10:10.101010','2011-11-11 11:11:11.111111'),
+(2,'2010-10-10 10:10:10.101010','2038-01-19 03:14:07.999999');
+/*!101100 SET system_versioning_insert_history=@old_system_versioning_insert_history */;
+mariadb-dump: --dump-history can't be used with --as-of.
+mariadb-dump: --dump-history can't be used with --replace.
+mariadb-dump: --xml can't be used with --dump-history.
+# SQL dump with/without history
+## With history
+drop tables t1, t2;
+select x, check_fields(x, row_start, row_end) from t1 for system_time all order by x;
+x check_fields(x, row_start, row_end)
+1 [CORRECT]
+2 [CORRECT]
+select x, check_fields(x, row_start, row_end) from t2 for system_time all order by x;
+x check_fields(x, row_start, row_end)
+1 [CORRECT]
+2 [CORRECT]
+## Without history
+drop tables t1, t2;
+select x, check_row_ts(row_start, row_end) from t1 for system_time all order by x;
+x check_row_ts(row_start, row_end)
+2 CURRENT ROW
+select x, check_row_ts(row_start, row_end) from t2 for system_time all order by x;
+x check_row_ts(row_start, row_end)
+2 CURRENT ROW
+## History and --no-create-info --skip-comments
+create or replace table t1 (x int) with system versioning;
+delete from t2;
+delete history from t2;
+select x, check_fields(x, row_start, row_end) from t1 for system_time all order by x;
+x check_fields(x, row_start, row_end)
+1 [CORRECT]
+2 [CORRECT]
+select x, check_fields(x, row_start, row_end) from t2 for system_time all order by x;
+x check_fields(x, row_start, row_end)
+1 [CORRECT]
+2 [CORRECT]
+## compact
+select x, check_fields(x, row_start, row_end) from t1 for system_time all order by x;
+x check_fields(x, row_start, row_end)
+1 [CORRECT]
+2 [CORRECT]
+select x, check_fields(x, row_start, row_end) from t2 for system_time all order by x;
+x check_fields(x, row_start, row_end)
+1 [CORRECT]
+2 [CORRECT]
+create or replace table t1 (x int) with system versioning;
+# --tab with history
+drop tables t1, t2;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `x` int(11) DEFAULT NULL,
+ `row_start` timestamp(6) GENERATED ALWAYS AS ROW START INVISIBLE,
+ `row_end` timestamp(6) GENERATED ALWAYS AS ROW END INVISIBLE,
+ PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+set @@system_versioning_insert_history= 1;
+load data infile 'tmp/t1.txt' into table t1 (x, row_start, row_end);
+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;
+x check_row_ts(row_start, row_end)
+1 HISTORICAL ROW
+2 CURRENT ROW
+select *, check_row_ts(row_start, row_end) from t2 for system_time all;
+x check_row_ts(row_start, row_end)
+1 HISTORICAL ROW
+2 CURRENT ROW
+drop tables t1, t2;
+drop function check_fields;
+#
+# MDEV-29730 mysqldump --dump-history creates broken dump if there are precision-versioned tables
+#
+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;
+mariadb-dump: Cannot use --dump-history for table `t1` with transaction-precise history
+mariadb-dump: Cannot use --dump-history for table `t1` with transaction-precise history
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL,
+ `rs` bigint(20) unsigned GENERATED ALWAYS AS ROW START,
+ `re` bigint(20) unsigned GENERATED ALWAYS AS ROW END,
+ PERIOD FOR SYSTEM_TIME (`rs`, `re`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING;
+/*!40101 SET character_set_client = @saved_cs_client */;
+INSERT INTO `t1` VALUES
+(2,XXX,18446744073709551615);
+drop table t1;
diff --git a/mysql-test/suite/versioning/r/debug.result b/mysql-test/suite/versioning/r/debug.result
new file mode 100644
index 00000000..2c944f75
--- /dev/null
+++ b/mysql-test/suite/versioning/r/debug.result
@@ -0,0 +1,106 @@
+create table t1 (a int);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+create temporary table tt1 (a int) with system versioning;
+ERROR HY000: System-versioned tables do not support CREATE TEMPORARY TABLE
+set @old_dbug=@@global.debug_dbug;
+set global debug_dbug='+d,sysvers_force';
+create table t2 (a int);
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+create temporary table tt2 (a int) with system versioning;
+show create table tt2;
+Table Create Table
+tt2 CREATE TEMPORARY TABLE `tt2` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+connect con1, localhost, root;
+create table t3 (a int);
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+create temporary table tt3 (a int) with system versioning;
+show create table tt3;
+Table Create Table
+tt3 CREATE TEMPORARY TABLE `tt3` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+disconnect con1;
+connection default;
+set debug_dbug='+d,sysvers_show';
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+create table t4 (a int);
+show create table t4;
+Table Create Table
+t4 CREATE TABLE `t4` (
+ `a` int(11) DEFAULT NULL,
+ `row_start` timestamp(6) GENERATED ALWAYS AS ROW START,
+ `row_end` timestamp(6) GENERATED ALWAYS AS ROW END,
+ PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+drop table t1, t2, t3, t4;
+set debug_dbug= @old_dbug;
+set global debug_dbug= @old_dbug;
+#
+# MDEV-19525 remove ER_VERS_FIELD_WRONG_TYPE from init_from_binary_frm_image()
+#
+create table t1 (x int) with system versioning;
+set debug_dbug='+d,error_vers_wrong_type';
+show create table t1;
+ERROR HY000: Incorrect information in file: './test/t1.frm'
+show warnings;
+Level Code Message
+Warning 4110 `row_start` must be of type TIMESTAMP(6) for system-versioned table `t1`
+Error 1033 Incorrect information in file: './test/t1.frm'
+drop table t1;
+set debug_dbug= @old_dbug;
+#
+# MDEV-17554 Auto-create new partition for system versioned tables
+# with history partitioned by INTERVAL/LIMIT
+#
+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;
+# Both threads create partition simultaneously
+connection con1;
+set debug_sync= 'add_history_partition signal s1 wait_for s2';
+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;
+connection default;
+update t1 set x= x + 2;
+# 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';
+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;
+connection default;
+disconnect con1;
+disconnect con2;
+set @@timestamp= default;
+drop tables t1;
+set debug_sync= 'reset';
diff --git a/mysql-test/suite/versioning/r/delete.result b/mysql-test/suite/versioning/r/delete.result
new file mode 100644
index 00000000..89c1ef51
--- /dev/null
+++ b/mysql-test/suite/versioning/r/delete.result
@@ -0,0 +1,170 @@
+# Basic + delete from view
+create or replace table t1(
+XNo int unsigned,
+sys_start SYS_DATATYPE as row start invisible,
+sys_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_start, sys_end))
+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);
+select XNo, sys_end < MAXVAL from t1 for system_time all;
+XNo sys_end < MAXVAL
+0 0
+1 0
+2 0
+3 0
+4 0
+5 0
+6 0
+7 0
+8 0
+9 0
+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;
+XNo_vt1
+2
+3
+4
+5
+delete from vt1 where XNo = 3;
+select XNo as XNo_vt1 from vt1;
+XNo_vt1
+2
+4
+5
+drop view vt1;
+drop table t1;
+# Check sys_start, sys_end
+create or replace table t1(
+x int,
+sys_start SYS_DATATYPE as row start invisible,
+sys_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_start, sys_end))
+with system versioning;
+insert into t1(x) values (1);
+select sys_start into @sys_start from t1;
+delete from t1;
+select * from t1;
+x
+select x = 1 as A, sys_start = @sys_start as B, sys_end > sys_start as C from t1 for system_time all;
+A B C
+1 1 1
+drop table t1;
+# Multi-delete
+create or replace table t1(
+x int,
+y int,
+sys_start SYS_DATATYPE as row start invisible,
+sys_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_start, sys_end))
+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;
+t1_x
+1
+2
+14
+select x as t2_x from t2;
+t2_x
+11
+12
+14
+delete t1, t2 from t1 join t2 where t1.x = t2.x;
+select x as t1_x from t1;
+t1_x
+1
+2
+select x as t2_x from t2;
+t2_x
+11
+12
+select x as t1_x_all from t1 for system_time all;
+t1_x_all
+1
+2
+3
+14
+select x as t2_x_all from t2 for system_time all;
+t2_x_all
+11
+12
+13
+14
+drop table t1;
+drop table t2;
+# Update + delete
+create or replace table t1 (x int) with system versioning;
+insert into t1 values (1);
+update t1 set x= 2;
+delete from t1;
+select x from t1 for system_time all;
+x
+2
+1
+drop table t1;
+#
+# MDEV-18929 2nd execution of SP does not detect ER_VERS_NOT_VERSIONED
+#
+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;
+call pr;
+ERROR 42S02: Table 'test.xx' doesn't exist
+call pr;
+ERROR 42S02: Table 'test.xx' doesn't exist
+drop procedure pr;
+drop trigger tr;
+drop table t1;
+#
+# MDEV-21138 Assertion `col->ord_part' or `f.col->ord_part' failed in row_build_index_entry_low
+#
+# Check DELETE and multi-DELETE with foreign key
+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_TYPE as row start invisible,
+row_end SYS_TYPE 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;
+f1 f3 check_row(row_start, row_end)
+1 1 CURRENT ROW
+1 1 CURRENT ROW
+2 2 CURRENT ROW
+2 2 CURRENT ROW
+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;
+f1 f3 check_row(row_start, row_end)
+1 1 HISTORICAL ROW
+1 1 HISTORICAL ROW
+2 2 CURRENT ROW
+2 2 CURRENT ROW
+create table t2 (f1 int);
+insert into t2 values (2);
+# 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;
+f1 f3 check_row(row_start, row_end)
+1 1 HISTORICAL ROW
+1 1 HISTORICAL ROW
+2 2 HISTORICAL ROW
+2 2 HISTORICAL ROW
+# Cleanup
+drop tables t1, t2;
diff --git a/mysql-test/suite/versioning/r/delete_history.result b/mysql-test/suite/versioning/r/delete_history.result
new file mode 100644
index 00000000..4e8c6f8b
--- /dev/null
+++ b/mysql-test/suite/versioning/r/delete_history.result
@@ -0,0 +1,242 @@
+call mtr.add_suppression("need more HISTORY partitions");
+create table t (a int);
+delete history from t before system_time now();
+ERROR HY000: Table `t` is not system-versioned
+create or replace table t (
+a int,
+row_start SYS_TYPE as row start invisible,
+row_end SYS_TYPE 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;
+@test
+correct
+drop table t;
+create or replace table t (
+a int,
+row_start SYS_TYPE as row start invisible,
+row_end SYS_TYPE 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;
+set @ts1=now(6);
+update t set a=22 where a=2;
+select * from t for system_time all;
+a
+11
+22
+1
+2
+delete history from t before system_time timestamp @ts1;
+select * from t for system_time all;
+a
+11
+22
+2
+prepare stmt from 'delete history from t';
+execute stmt;
+drop prepare stmt;
+select * from t for system_time all;
+a
+11
+22
+delete from t;
+create or replace procedure truncate_sp()
+begin
+delete history from t before system_time timestamp now(6);
+end~~
+call truncate_sp;
+select * from t for system_time all;
+a
+drop procedure truncate_sp;
+# 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;
+Warnings:
+Warning 4114 Versioned table `test`.`t`: last HISTORY partition (`p1`) is out of LIMIT, need more HISTORY partitions
+# You see warning above ^
+delete history from t;
+select * from t for system_time all;
+a
+3
+# VIEW
+create or replace table t (
+i int,
+row_start SYS_TYPE as row start invisible,
+row_end SYS_TYPE 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;
+delete history from v;
+ERROR 42S02: 'v' is a view
+create or replace table t (i int);
+delete history from t;
+ERROR HY000: Table `t` is not system-versioned
+create or replace view v as select * from t;
+delete history from v;
+ERROR 42S02: 'v' is a view
+prepare stmt from 'delete history from t';
+ERROR HY000: Table `t` is not system-versioned
+drop table t;
+drop view v;
+create or replace table t (i int);
+create or replace view v as select * from t;
+drop table v;
+ERROR 42S02: 'test.v' is a view
+lock table v write;
+delete history from v before system_time now(6);
+ERROR 42S02: 'v' is a view
+unlock tables;
+drop view v;
+drop table t;
+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;
+# 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;
+# force cleaning table shares
+flush tables t1, t2;
+truncate table t1;
+truncate table t2;
+ERROR HY000: System-versioned tables do not support TRUNCATE TABLE
+# fetch table shares
+describe t1;
+Field Type Null Key Default Extra
+id int(11) YES NULL
+describe t2;
+Field Type Null Key Default Extra
+id int(11) YES NULL
+truncate table t1;
+truncate table t2;
+ERROR HY000: System-versioned tables do not support TRUNCATE TABLE
+# enter locked tables mode
+lock tables t1 WRITE, t2 WRITE;
+truncate t1;
+truncate t2;
+ERROR HY000: System-versioned tables do not support TRUNCATE TABLE
+unlock tables;
+drop table t2;
+#
+# MDEV-19814 Assertion `update->n_fields < ulint(table->n_cols + table->n_v_cols)' on DELETE HISTORY
+#
+create or replace table t1 (
+f varchar(1),
+row_start SYS_TYPE as row start,
+row_end SYS_TYPE 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;
+#
+# MDEV-20186 Wrong result or Assertion on INSERT after DELETE HISTORY
+#
+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;
+a
+1
+drop table t1;
+#
+# MDEV-25468 DELETE HISTORY may delete current data on system-versioned table
+#
+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;
+x
+1
+explain extended delete history from t1 before system_time '2039-01-01 23:00';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 1 100.00 Using where
+Warnings:
+Note 1003 delete from `test`.`t1` FOR SYSTEM_TIME BEFORE TIMESTAMP '2039-01-01 23:00' where `test`.`t1`.`row_end` < '2039-01-01 23:00' and is_history(`test`.`t1`.`row_end`)
+create or replace procedure p() delete history from t1 before system_time '2039-01-01 23:00';
+call p;
+select * from t1;
+x
+1
+call p;
+select * from t1;
+x
+1
+drop procedure p;
+prepare stmt from "delete history from t1 before system_time '2039-01-01 23:00'";
+execute stmt;
+select * from t1;
+x
+1
+execute stmt;
+select * from t1;
+x
+1
+drop prepare stmt;
+drop table t1;
+#
+# MDEV-25004 Missing row in FTS_DOC_ID_INDEX during DELETE HISTORY
+#
+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';
+InnoDB 0 transactions not purged
+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;
+#
+# MDEV-28201 Server crashes upon SHOW ANALYZE/EXPLAIN FORMAT=JSON
+#
+CREATE TABLE t1 (a INT) WITH SYSTEM VERSIONING;
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+SET optimizer_trace= 'enabled=on';
+DELETE HISTORY FROM v1 BEFORE SYSTEM_TIME '2021-01-01';
+ERROR HY000: The target table v1 of the DELETE is not updatable
+DELETE HISTORY FROM v1;
+ERROR HY000: The target table v1 of the DELETE is not updatable
+DROP VIEW v1;
+DROP TABLE t1;
+# End of 10.4 tests
+#
+# MDEV-17554 Auto-create new partition for system versioned tables with history partitioned by INTERVAL/LIMIT
+#
+# 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;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 2
+drop table t;
+# End of 10.9 tests
diff --git a/mysql-test/suite/versioning/r/derived.result b/mysql-test/suite/versioning/r/derived.result
new file mode 100644
index 00000000..700c92a8
--- /dev/null
+++ b/mysql-test/suite/versioning/r/derived.result
@@ -0,0 +1,295 @@
+create table emp
+(
+emp_id int,
+name varchar(127),
+mgr int
+) with system versioning;
+insert into emp values (1, 'bill', 0),
+(2, 'bill', 1),
+(3, 'kate', 1);
+set @ts=now(6);
+delete from emp;
+insert into emp values (4, 'john', 1);
+with ancestors as (select * from emp) select * from ancestors;
+emp_id name mgr
+4 john 1
+set @tmp= "with ancestors as (select * from emp) select * from ancestors";
+prepare stmt from @tmp;
+execute stmt;
+emp_id name mgr
+4 john 1
+drop prepare stmt;
+with ancestors as (select * from emp for system_time all) select * from ancestors;
+emp_id name mgr
+1 bill 0
+2 bill 1
+3 kate 1
+4 john 1
+set @tmp= "with ancestors as (select * from emp for system_time all) select * from ancestors";
+prepare stmt from @tmp;
+execute stmt;
+emp_id name mgr
+1 bill 0
+2 bill 1
+3 kate 1
+4 john 1
+drop prepare stmt;
+with recursive ancestors as (select * from emp) select * from ancestors;
+emp_id name mgr
+4 john 1
+set @tmp= "with recursive ancestors as (select * from emp) select * from ancestors";
+prepare stmt from @tmp;
+execute stmt;
+emp_id name mgr
+4 john 1
+drop prepare stmt;
+select emp_id from (select emp_id from emp where row_end>'2031-1-1') as tmp;
+emp_id
+4
+set @tmp= "select emp_id from (select emp_id from emp where row_end>'2031-1-1') as tmp";
+prepare stmt from @tmp;
+execute stmt;
+emp_id
+4
+drop prepare stmt;
+with recursive
+ancestors
+as
+(
+select e.emp_id, e.name, e.mgr
+from emp as e
+where name = 'john'
+ union
+select ee.emp_id, ee.name, ee.mgr
+from emp as ee, ancestors as a
+where ee.mgr = a.emp_id
+)
+select * from ancestors;
+emp_id name mgr
+4 john 1
+set @tmp= "
+with recursive
+ancestors
+as
+(
+ select e.emp_id, e.name, e.mgr
+ from emp as e
+ where name = 'john'
+ union
+ select ee.emp_id, ee.name, ee.mgr
+ from emp as ee, ancestors as a
+ where ee.mgr = a.emp_id
+)
+select * from ancestors";
+prepare stmt from @tmp;
+execute stmt;
+emp_id name mgr
+4 john 1
+drop prepare stmt;
+with recursive
+ancestors
+as
+(
+select e.emp_id, e.name, e.mgr
+from emp for system_time as of timestamp @ts as e
+where name = 'bill'
+ union
+select ee.emp_id, ee.name, ee.mgr
+from emp for system_time as of timestamp @ts as ee,
+ancestors as a
+where ee.mgr = a.emp_id
+)
+select * from ancestors;
+emp_id name mgr
+1 bill 0
+2 bill 1
+3 kate 1
+set @tmp= "
+with recursive
+ancestors
+as
+(
+ select e.emp_id, e.name, e.mgr
+ from emp for system_time as of timestamp @ts as e
+ where name = 'bill'
+ union
+ select ee.emp_id, ee.name, ee.mgr
+ from emp for system_time as of timestamp @ts as ee,
+ ancestors as a
+ where ee.mgr = a.emp_id
+)
+select * from ancestors";
+prepare stmt from @tmp;
+execute stmt;
+emp_id name mgr
+1 bill 0
+2 bill 1
+3 kate 1
+drop prepare stmt;
+drop table emp;
+create or replace table t1 (x int) with system versioning;
+create or replace table t2 (y int) with system versioning;
+insert into t1 values (1);
+set @t0= now(6);
+delete from t1;
+insert into t1 values (2);
+insert into t2 values (10);
+select * from (select *, t1.row_end, t1.row_end as endo from t1) as s0;
+x row_end endo
+2 # #
+select * from (select *, t1.row_end, t2.row_start from t1, t2) as s0;
+x y row_end row_start
+2 10 # #
+# SYSTEM_TIME propagation from inner to outer
+select * from (select * from t1 for system_time as of timestamp @t0, t2) as s0;
+x y
+1 10
+with s1 as (select * from t1 for system_time as of timestamp @t0, t2) select * from s1;
+x y
+1 10
+# leading table selection
+select * from (select *, t1.row_end from t2, t1 for system_time as of timestamp @t0) as s2;
+y x row_end
+10 1 #
+with s3 as (select *, t1.row_end from t2, t1 for system_time as of timestamp @t0) select * from s3;
+y x row_end
+10 1 #
+### VIEW instead of t1
+set @q= concat("create view vt1 as select * from t1 for system_time as of timestamp '", @t0, "'");
+prepare q from @q;
+execute q;
+drop prepare q;
+create view vt2 as select * from t1;
+# SYSTEM_TIME propagation from view
+select * from vt1;
+x
+1
+# SYSTEM_TIME propagation from inner to outer
+select * from (select * from vt1, t2) as s0;
+x y
+1 10
+### SYSTEM_TIME clash
+select * from (select * from t1 for system_time all) for system_time all as dt0;
+ERROR HY000: Table `dt0` is not system-versioned
+select * from vt1 for system_time all;
+ERROR HY000: Table `vt1` is not system-versioned
+with dt1 as (select * from t1 for system_time all)
+select * from dt1 for system_time all;
+ERROR HY000: Table `dt1` is not system-versioned
+### UNION
+set @t1= now(6);
+delete from t2;
+insert into t2 values (3);
+# SYSTEM_TIME is not propagated
+select x from t1 union
+select y from t2;
+x
+2
+3
+select x from t1 for system_time as of @t0 union
+select y from t2;
+x
+1
+3
+select x from t1 union
+select y from t2 for system_time as of @t1;
+x
+2
+10
+select x from t1 for system_time as of @t0 union
+select y from t2 for system_time as of @t1;
+x
+1
+10
+# LEFT/RIGHT JOIN
+create or replace table t1 (x int, y int) with system versioning;
+create or replace table t2 (x int, y int) with system versioning;
+insert into t1 values (1, 1), (1, 2), (1, 3), (4, 4), (5, 5);
+insert into t2 values (1, 2), (2, 1), (3, 1);
+## Outer or inner SYSTEM_TIME produces same expression
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Query A:
+Note 1003 select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t1` FOR SYSTEM_TIME AS OF TIMESTAMP current_timestamp(6) join `test`.`t2` FOR SYSTEM_TIME AS OF TIMESTAMP current_timestamp(6) where `test`.`t1`.`x` = `test`.`t2`.`x` and `test`.`t2`.`row_end` > <cache>(current_timestamp(6)) and `test`.`t2`.`row_start` <= <cache>(current_timestamp(6)) and `test`.`t1`.`row_end` > <cache>(current_timestamp(6)) and `test`.`t1`.`row_start` <= <cache>(current_timestamp(6))
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Query B:
+Note 1003 select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t1` FOR SYSTEM_TIME AS OF TIMESTAMP current_timestamp(6) join `test`.`t2` FOR SYSTEM_TIME AS OF TIMESTAMP current_timestamp(6) where `test`.`t1`.`x` = `test`.`t2`.`x` and `test`.`t2`.`row_end` > <cache>(current_timestamp(6)) and `test`.`t2`.`row_start` <= <cache>(current_timestamp(6)) and `test`.`t1`.`row_end` > <cache>(current_timestamp(6)) and `test`.`t1`.`row_start` <= <cache>(current_timestamp(6))
+Fine result: queries A and B are equal.
+## LEFT JOIN: t1, t2 versioned
+select * from (
+select t1.x as LJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2
+from t1 left join t2 on t1.x = t2.x)
+as derived;
+LJ1_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+4 4 NULL NULL
+5 5 NULL NULL
+alter table t2 drop system versioning;
+## LEFT JOIN: t1 versioned
+select * from (
+select t1.x as LJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2
+from t1 left join t2 on t1.x = t2.x)
+as derived;
+LJ2_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+4 4 NULL NULL
+5 5 NULL NULL
+alter table t1 drop system versioning;
+alter table t2 add system versioning;
+## LEFT JOIN: t2 versioned
+select * from (
+select t1.x as LJ3_x1, t1.y as y1, t2.x as x2, t2.y as y2
+from t1 left join t2 on t1.x = t2.x)
+as derived;
+LJ3_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+4 4 NULL NULL
+5 5 NULL NULL
+alter table t1 add system versioning;
+## RIGHT JOIN: t1, t2 versioned
+select * from (
+select t1.x as RJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2
+from t1 right join t2 on t1.x = t2.x)
+as derived;
+RJ1_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+NULL NULL 2 1
+NULL NULL 3 1
+alter table t2 drop system versioning;
+## RIGHT JOIN: t1 versioned
+select * from (
+select t1.x as RJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2
+from t1 right join t2 on t1.x = t2.x)
+as derived;
+RJ2_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+NULL NULL 2 1
+NULL NULL 3 1
+alter table t1 drop system versioning;
+alter table t2 add system versioning;
+## RIGHT JOIN: t2 versioned
+select * from (
+select t1.x as RJ3_x1, t1.y as y1, t2.x as x2, t2.y as y2
+from t1 right join t2 on t1.x = t2.x)
+as derived;
+RJ3_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+NULL NULL 2 1
+NULL NULL 3 1
+drop table t1, t2;
+drop view vt1, vt2;
diff --git a/mysql-test/suite/versioning/r/foreign.result b/mysql-test/suite/versioning/r/foreign.result
new file mode 100644
index 00000000..b17deba1
--- /dev/null
+++ b/mysql-test/suite/versioning/r/foreign.result
@@ -0,0 +1,573 @@
+#################
+# Test RESTRICT #
+#################
+create table parent(
+id int,
+KEY_TYPE (id)
+) engine innodb;
+create table child(
+parent_id int,
+sys_start SYS_DATATYPE as row start invisible,
+sys_end SYS_DATATYPE as row end invisible,
+period for system_time(sys_start, sys_end),
+foreign key(parent_id) references parent(id)
+on delete restrict
+on update restrict
+) engine innodb with system versioning;
+insert into parent values(1);
+insert into child values(1);
+delete from parent where id = 1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`))
+delete from child where parent_id = 1;
+delete from parent where id = 1;
+insert into parent values(1);
+insert into child values(1);
+update parent set id=id+1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`))
+delete from child;
+update parent set id=id+1;
+select * from child for system_time all;
+parent_id
+1
+1
+drop table child;
+drop table parent;
+##############################################
+# Test when clustered index is a foreign key #
+##############################################
+create table parent(
+id int(10) unsigned,
+KEY_TYPE (id)
+) engine innodb;
+create table child(
+parent_id int(10) unsigned primary key,
+sys_start SYS_DATATYPE as row start invisible,
+sys_end SYS_DATATYPE as row end invisible,
+period for system_time(sys_start, sys_end),
+foreign key(parent_id) references parent(id)
+) engine innodb with system versioning;
+insert into parent values(1);
+insert into child values(1);
+delete from parent where id = 1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`))
+drop table child;
+drop table parent;
+################
+# Test CASCADE #
+################
+create table parent(
+id int,
+KEY_TYPE (id)
+) engine innodb;
+create table child(
+parent_id int,
+sys_start SYS_DATATYPE as row start invisible,
+sys_end SYS_DATATYPE as row end invisible,
+period for system_time(sys_start, sys_end),
+foreign key(parent_id) references parent(id)
+on delete cascade
+on update cascade
+) engine innodb with system versioning;
+insert into parent values(1);
+insert into child values(1);
+delete from parent where id = 1;
+select * from child;
+parent_id
+select * from child for system_time all;
+parent_id
+1
+insert into parent values(1);
+insert into child values(1);
+update parent set id = id + 1;
+select * from child;
+parent_id
+2
+select * from child for system_time all;
+parent_id
+1
+1
+2
+drop table child;
+drop table parent;
+create or replace table parent (
+id int,
+KEY_TYPE(id),
+sys_start SYS_DATATYPE as row start invisible,
+sys_end SYS_DATATYPE as row end invisible,
+period for system_time(sys_start, sys_end)
+) with system versioning
+engine innodb;
+create or replace table child (
+x int,
+parent_id int not null,
+constraint `parent-fk`
+ foreign key (parent_id) references parent (id)
+on delete cascade
+on update restrict
+)
+engine innodb;
+insert into parent (id) values (2);
+insert into child (x, parent_id) values (2, 2);
+delete from parent;
+select * from child;
+x parent_id
+drop table child;
+drop table parent;
+create or replace table parent (
+id int,
+KEY_TYPE(id)
+)
+engine innodb;
+create or replace table child (
+id int primary key,
+parent_id int not null,
+row_start SYS_DATATYPE as row start invisible,
+row_end SYS_DATATYPE 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;
+id parent_id
+select *, check_row(row_start, row_end) from child for system_time all;
+id parent_id check_row(row_start, row_end)
+3 3 HISTORICAL ROW
+drop table child;
+drop table parent;
+#################
+# Test SET NULL #
+#################
+create table parent(
+id int,
+KEY_TYPE (id)
+) engine innodb;
+create or replace table child(
+parent_id int,
+sys_start SYS_DATATYPE as row start invisible,
+sys_end SYS_DATATYPE as row end invisible,
+period for system_time(sys_start, sys_end),
+foreign key(parent_id) references parent(id)
+on delete set null
+on update set null
+) engine innodb with system versioning;
+insert into parent values(1);
+insert into child values(1);
+delete from child;
+insert into child values(1);
+delete from parent where id = 1;
+select * from child;
+parent_id
+NULL
+select *, current_row(sys_end) as current_row from child for system_time all order by sys_end;
+parent_id current_row
+1 0
+1 0
+NULL 1
+delete from child;
+insert into parent values(1);
+insert into child values(1);
+update parent set id= id + 1;
+select * from child;
+parent_id
+NULL
+select *, current_row(sys_end) as current_row from child for system_time all order by sys_end;
+parent_id current_row
+1 0
+1 0
+NULL 0
+1 0
+NULL 1
+drop table child;
+drop table parent;
+###########################
+# Parent table is foreign #
+###########################
+create or replace table parent(
+id int,
+KEY_TYPE (id),
+sys_start SYS_DATATYPE as row start invisible,
+sys_end SYS_DATATYPE as row end invisible,
+period for system_time(sys_start, sys_end)
+) engine innodb with system versioning;
+create or replace table child(
+parent_id int,
+foreign key(parent_id) references parent(id)
+) engine innodb;
+insert into parent values(1);
+insert into child values(1);
+delete from parent;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`))
+update parent set id=2;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`))
+delete from child;
+delete from parent;
+insert into child values(1);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`))
+insert into parent values(1);
+insert into child values(1);
+delete from parent;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`))
+update parent set id=2;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`))
+drop table child;
+drop table parent;
+###################
+# crash on DELETE #
+###################
+create or replace table a (
+cola int(10),
+KEY_TYPE (cola),
+v_cola int(10) as (cola mod 10) virtual,
+sys_start SYS_DATATYPE as row start invisible,
+sys_end SYS_DATATYPE as row end invisible,
+period for system_time(sys_start, sys_end)
+) engine=innodb with system versioning;
+create index v_cola on a (v_cola);
+create or replace table b(
+cola int(10),
+v_cola int(10),
+sys_start SYS_DATATYPE as row start invisible,
+sys_end SYS_DATATYPE as row end invisible,
+period for system_time(sys_start, sys_end)
+) engine=innodb with system versioning;
+alter table b add constraint `v_cola_fk`
+foreign key (v_cola) references a (v_cola);
+insert into a(cola) values (12);
+insert into b(cola, v_cola) values (10,2);
+delete from a;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`b`, CONSTRAINT `v_cola_fk` FOREIGN KEY (`v_cola`) REFERENCES `a` (`v_cola`))
+drop table b, a;
+###############################################
+# CASCADE UPDATE foreign not system versioned #
+###############################################
+create or replace table parent (
+id smallint unsigned not null auto_increment,
+value int unsigned not null,
+primary key (id, value)
+) engine = innodb;
+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 as row start invisible,
+sys_end SYS_DATATYPE 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);
+select id, value from parent into @id, @value;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+insert into child values (default, @id, @value);
+insert into subchild values (default, @id, @value);
+select parent_id from subchild;
+parent_id
+1
+update parent set id = 11, value = value + 1;
+select parent_id from subchild;
+parent_id
+11
+select * from child;
+id parent_id parent_value
+1 11 24
+delete from parent;
+select count(*) from child;
+count(*)
+0
+select * from child for system_time all;
+id parent_id parent_value
+1 1 23
+1 11 24
+select count(*) from subchild;
+count(*)
+0
+drop table subchild, child, parent;
+#
+# MDEV-18057 Assertion `(node->state == 5) || (node->state == 6)' failed in row_upd_sec_step upon DELETE after UPDATE failed due to FK violation
+#
+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;
+update t2 set f2= 2;
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f2`) REFERENCES `t1` (`f1`))
+delete from t2;
+drop table t2, t1;
+#
+# MDEV-18879 Corrupted record inserted by FOREIGN KEY operation
+#
+SET timestamp = 1;
+SET time_zone='+02:00';
+SELECT now();
+now()
+1970-01-01 02:00:01
+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;
+SELECT * INTO OUTFILE 't1.data' FROM t1;
+SET timestamp = 3;
+UPDATE t1 SET f13 = 'q';
+SET timestamp = 4;
+LOAD DATA INFILE 't1.data' REPLACE INTO TABLE t1;
+Warnings:
+Warning 1265 Data truncated for column 'f12' at row 2
+Warning 1265 Data truncated for column 'f12' at row 4
+Warning 1265 Data truncated for column 'f12' at row 7
+SELECT * INTO OUTFILE 't1.data.2' FROM t1;
+SET timestamp = 5;
+LOAD DATA INFILE 't1.data.2' REPLACE INTO TABLE t1;
+Warnings:
+Warning 1265 Data truncated for column 'f1' at row 2
+Warning 1265 Data truncated for column 'f12' at row 2
+Warning 1265 Data truncated for column 'f12' at row 4
+Warning 1265 Data truncated for column 'f12' at row 7
+Warning 1265 Data truncated for column 'f1' at row 10
+SELECT * INTO OUTFILE 't2.data' FROM t2;
+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;
+Warnings:
+Warning 1265 Data truncated for column 'f12' at row 2
+Warning 1265 Data truncated for column 'f12' at row 4
+Warning 1265 Data truncated for column 'f12' at row 7
+SET FOREIGN_KEY_CHECKS = ON;
+SET SESSION SQL_MODE= 'NO_BACKSLASH_ESCAPES';
+SET timestamp = 8;
+LOAD DATA INFILE 't1.data' REPLACE INTO TABLE t1;
+Warnings:
+Warning 1265 Data truncated for column 'f12' at row 2
+Warning 1265 Data truncated for column 'f12' at row 4
+Warning 1265 Data truncated for column 'f12' at row 7
+SET timestamp = 9;
+REPLACE INTO t2 SELECT * FROM t2;
+DROP TABLE t1, t2;
+set timestamp= default;
+set time_zone='+00:00';
+#
+# MDEV-16210 FK constraints on versioned tables use historical rows, which may cause constraint violation
+#
+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);
+# DELETE from referenced table is not allowed
+delete from t1 where a = 1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`b`) REFERENCES `t1` (`a`))
+drop tables t2, t1;
+#
+# MDEV-20812 Unexpected ER_ROW_IS_REFERENCED_2 or server crash in row_ins_foreign_report_err upon DELETE from versioned table with FK
+#
+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;
+# 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);
+# DELETE from foreign table is allowed
+delete from t2;
+drop tables t2, t1;
+#
+# MDEV-23644 Assertion on evaluating foreign referential action for self-reference in system versioned table
+#
+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;
+pk f1 f2 left(f3, 4) check_row_ts(row_start, row_end)
+1 8 8 SHOR HISTORICAL ROW
+2 8 8 LONG HISTORICAL ROW
+drop table t1;
+# 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;
+y r f check_row_ts(row_start, row_end)
+1 6 6 HISTORICAL ROW
+2 6 6 HISTORICAL ROW
+drop tables t1;
+# 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;
+y r f check_row_ts(row_start, row_end)
+1 6 6 HISTORICAL ROW
+2 6 6 HISTORICAL ROW
+drop tables t1;
+# 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;
+y r f check_row_ts(row_start, row_end)
+1 6 6 HISTORICAL ROW
+2 6 NULL ERROR: row_end == row_start
+2 6 6 HISTORICAL ROW
+drop tables t1;
+#
+# MDEV-21555 Assertion secondary index is out of sync on delete from versioned table
+#
+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;
+drop table t1;
+#
+# MDEV-30378 Versioned REPLACE succeeds with ON DELETE RESTRICT
+# constraint
+#
+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);
+delete from t0;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t1`, CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`pk`) REFERENCES `t0` (`pk`) ON UPDATE CASCADE)
+replace t0 values (1);
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t1`, CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`pk`) REFERENCES `t0` (`pk`) ON UPDATE CASCADE)
+select * into outfile 'load_t0' from t0 ;
+load data infile 'load_t0' replace into table t0;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t1`, CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`pk`) REFERENCES `t0` (`pk`) ON UPDATE CASCADE)
+delete t0, t2 from t0 join t2;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t1`, CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`pk`) REFERENCES `t0` (`pk`) ON UPDATE CASCADE)
+select pk from t0;
+pk
+1
+# Cleanup
+drop table t1, t0, t2;
+# 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;
+a b
+1 3
+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;
+a b
+1 3
+drop table t;
+#
+# MDEV-20729 Fix REFERENCES constraint in column definition
+#
+create table t1(id int);
+# system fields can't be foreign keys:
+create or replace table t2(
+x int,
+sys_start SYS_DATATYPE as row start references t1(id),
+sys_end SYS_DATATYPE as row end,
+period for system_time(sys_start, sys_end)
+) engine innodb with system versioning;
+Got one of the listed errors
+create or replace table t2(
+x int,
+sys_start SYS_DATATYPE as row start,
+sys_end SYS_DATATYPE as row end references t1(id),
+period for system_time(sys_start, sys_end)
+) engine innodb with system versioning;
+Got one of the listed errors
+create or replace table t2(
+x int,
+sys_start SYS_DATATYPE as row start,
+sys_end SYS_DATATYPE as row end,
+period for system_time(sys_start, sys_end),
+foreign key (sys_start) references t1(id)
+) engine innodb with system versioning;
+ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed")
+create or replace table t2(
+x int,
+sys_start SYS_DATATYPE as row start,
+sys_end SYS_DATATYPE as row end,
+period for system_time(sys_start, sys_end),
+foreign key (sys_end) references t1(id)
+) engine innodb with system versioning;
+ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed")
+drop table t1;
+# End of 10.5 tests
diff --git a/mysql-test/suite/versioning/r/insert.result b/mysql-test/suite/versioning/r/insert.result
new file mode 100644
index 00000000..442d71c6
--- /dev/null
+++ b/mysql-test/suite/versioning/r/insert.result
@@ -0,0 +1,321 @@
+create or replace table t1(
+x int unsigned,
+y int unsigned,
+sys_start SYS_DATATYPE as row start invisible,
+sys_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_start, sys_end))
+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);
+select x, y, sys_end < MAXVAL from t1;
+x y sys_end < MAXVAL
+3 4 0
+2 3 0
+40 33 0
+create or replace table t1(
+id int unsigned auto_increment primary key,
+x int unsigned,
+y int unsigned,
+sys_start SYS_DATATYPE as row start invisible,
+sys_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_start, sys_end))
+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);
+select id, x, y, sys_end < MAXVAL from t1;
+id x y sys_end < MAXVAL
+1 33 44 0
+20 33 44 0
+40 33 44 0
+create or replace table t1(
+x int unsigned,
+y int unsigned,
+sys_start SYS_DATATYPE as row start invisible,
+sys_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_start, sys_end))
+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);
+select x, y, sys_end < MAXVAL from t1;
+x y sys_end < MAXVAL
+8001 9001 0
+1001 2001 0
+1002 2002 0
+select x, y from vt1_1;
+x y
+8001 9001
+1001 2001
+1002 2002
+drop view vt1_1;
+create or replace table t1( id bigint primary key, a int, b int) with system versioning;
+insert into t1 values(1, 1, 1);
+select row_start, row_end from t1 into @sys_start, @sys_end;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+select id, a, b from t1;
+id a b
+1 1 1
+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;
+id a b C D
+2 2 2 1 1
+drop table t1;
+create or replace table t1(
+x int unsigned,
+y int unsigned,
+sys_start SYS_DATATYPE as row start invisible,
+sys_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_start, sys_end))
+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;
+x y
+1 1001
+2 2001
+3 3001
+4 4001
+5 5001
+6 6001
+7 7001
+8 8001
+9 9001
+select x, y from t2;
+x y
+1 1000
+2 2000
+3 3000
+4 4000
+5 5000
+6 6000
+7 7000
+8 8000
+9 9000
+1 1001
+2 2001
+3 3001
+4 4001
+5 5001
+6 6001
+7 7001
+8 8001
+9 9001
+drop table t1;
+drop table t2;
+#
+# MDEV-16546 System versioning setting to allow history modification
+#
+set @@session.time_zone='+00:00';
+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;
+insert into t1(x, row_start, row_end) values (2, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
+ERROR 42S22: Unknown column 'row_start' in 'field list'
+insert into t2(y, row_start, row_end) values (2, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
+ERROR HY000: The value specified for generated column 'row_start' in table 't2' has been ignored
+set @@system_versioning_insert_history= 1;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) NOT NULL,
+ PRIMARY KEY (`x`)
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+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');
+insert into t3 values (5, '1980-01-02 00:00:00', '1980-01-01 00:00:01');
+ERROR HY000: Incorrect row_start value: '1980-01-02 00:00:00.000000'
+select x, row_start, row_end from t1 for system_time all;
+x row_start row_end
+3 1980-01-01 00:00:00.000000 1980-01-01 00:00:01.000000
+select y, row_start, row_end from t2 for system_time all;
+y row_start row_end
+4 1980-01-01 00:00:00.000000 1980-01-01 00:00:01.000000
+select z, row_start, row_end from t3 for system_time all;
+z row_start row_end
+5 1980-01-01 00:00:00.000000 1980-01-01 00:00:01.000000
+insert into t1(x) values (1);
+insert into t2(y) values (1);
+update t1 set x= x + 1;
+update t1 set row_start= '1971-01-01 00:00:00';
+ERROR 42S22: Unknown column 'row_start' in 'field list'
+update t2 set row_start= '1971-01-01 00:00:00';
+ERROR HY000: The value specified for generated column 'row_start' in table 't2' has been ignored
+insert t1 (x) values (2) on duplicate key update x= 3, row_end= '1970-01-01 00:00:00';
+ERROR 42S22: Unknown column 'row_end' in 'field list'
+insert t2 (y) values (1) on duplicate key update y= 3, row_end= '1970-01-01 00:00:00';
+ERROR HY000: The value specified for generated column 'row_end' in table 't2' has been ignored
+insert t2 (y,row_end) values (1, '1970-01-01 00:00:00') on duplicate key update y= 3;
+ERROR HY000: The value specified for generated column 'row_end' in table 't2' has been ignored
+insert into t1 values (4);
+insert into t1 set x= 5, row_start= '1980-01-01 00:00:00', row_end= '1980-01-01 00:00:01';
+insert into t1(x, row_start, row_end) values (6, '1980-01-01 00:00:01', '1980-01-01 00:00:00');
+ERROR HY000: Incorrect row_start value: '1980-01-01 00:00:01.000000'
+insert into t1(x, row_start, row_end) values (7, '1980-01-01 00:00:11', '1980-01-01 00:00:11');
+ERROR HY000: Incorrect row_start value: '1980-01-01 00:00:11.000000'
+insert into t1(x, row_start) values (8, '1980-01-01 00:00:22');
+insert into t1(x, row_end) values (9, '1980-01-01 00:00:33');
+ERROR HY000: Incorrect row_start value: 'now'
+insert into t1(x, row_end) values (10, TIMESTAMP'2038-01-19 03:14:07.999999');
+select x, check_row_ts(row_start, row_end) from t1 for system_time all order by x;
+x check_row_ts(row_start, row_end)
+1 HISTORICAL ROW
+2 CURRENT ROW
+3 HISTORICAL ROW
+4 CURRENT ROW
+5 HISTORICAL ROW
+8 CURRENT ROW
+10 CURRENT ROW
+select x, row_start, row_end from t1 for system_time all
+where x > 1 and row_end < TIMESTAMP'2038-01-19 03:14:07.999999' order by x, row_start, row_end;
+x row_start row_end
+3 1980-01-01 00:00:00.000000 1980-01-01 00:00:01.000000
+5 1980-01-01 00:00:00.000000 1980-01-01 00:00:01.000000
+# 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;
+insert into t2(y, row_start, row_end) values (0, 1, 2);
+ERROR HY000: The value specified for generated column 'row_start' in table 't2' has been ignored
+set @@system_versioning_insert_history= 0;
+## 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;
+x check_row_ts(row_start, row_end)
+1 HISTORICAL ROW
+2 CURRENT ROW
+3 HISTORICAL ROW
+4 CURRENT ROW
+5 HISTORICAL ROW
+8 CURRENT ROW
+10 CURRENT ROW
+select x, row_start, row_end from t2 for system_time all
+where x > 1 and row_end < TIMESTAMP'2038-01-19 03:14:07.999999' order by x, row_start, row_end;
+x row_start row_end
+3 1980-01-01 00:00:00.000000 1980-01-01 00:00:01.000000
+5 1980-01-01 00:00:00.000000 1980-01-01 00:00:01.000000
+set @@system_versioning_insert_history= 0;
+# 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;
+replace into t2 (a, row_start, row_end) values (1, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
+ERROR HY000: The value specified for generated column 'row_start' in table 't2' has been ignored
+replace into t2 (a, row_start, row_end) select x, row_start, row_end from t1;
+ERROR HY000: The value specified for generated column 'row_start' in table 't2' has been ignored
+create or replace table t2 (a int primary key) with system versioning;
+replace into t2 (a, row_start, row_end) values (1, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
+ERROR 42S22: Unknown column 'row_start' in 'field list'
+replace into t2 (a, row_start, row_end) select x, row_start, row_end from t1;
+ERROR 42S22: Unknown column 'row_start' in 'field list'
+set @@system_versioning_insert_history= 1;
+# REPLACE ignores system_versioning_insert_history
+replace into t2 (a, row_end) values (0, '1980-01-01 00:00:00');
+ERROR 42S22: Unknown column 'row_end' in 'field list'
+replace into t3 (z, row_start) values (0, '1980-01-01 00:00:00');
+ERROR HY000: The value specified for generated column 'row_start' in table 't3' has been ignored
+replace into t3 values (0, '1980-01-01 00:00:00', '1981-01-01 00:00:00');
+ERROR HY000: The value specified for generated column 'row_start' in table 't3' has been ignored
+# LOAD DATA
+select x, row_start, row_end into outfile 'DATAFILE' from t1 for system_time all;
+create or replace table t2 like t1;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `x` int(11) NOT NULL,
+ PRIMARY KEY (`x`)
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+set @@system_versioning_insert_history= 1;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `x` int(11) NOT NULL,
+ PRIMARY KEY (`x`)
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+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;
+x check_row_ts(row_start, row_end)
+1 HISTORICAL ROW
+2 CURRENT ROW
+3 HISTORICAL ROW
+4 CURRENT ROW
+5 HISTORICAL ROW
+8 CURRENT ROW
+10 CURRENT ROW
+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;
+row_start = '1980-01-01 00:00:00' row_end = '1980-01-01 00:00:01'
+1 1
+# Honor secure_timestamp option
+# restart: --secure-timestamp=YES
+set @@system_versioning_insert_history= 1;
+insert into t3(z, row_start, row_end) values (8, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
+ERROR HY000: The MariaDB server is running with the --secure-timestamp=YES option so it cannot execute this statement
+insert into t3 values (8, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
+ERROR HY000: The MariaDB server is running with the --secure-timestamp=YES option so it cannot execute this statement
+# restart: --secure-timestamp=REPLICATION
+create user nobody;
+grant all privileges on test.* to nobody;
+set @@system_versioning_insert_history= 1;
+insert into test.t3(z, row_start, row_end) values (9, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
+ERROR 42000: Access denied; you need (at least one of) the BINLOG REPLAY privilege(s) for this operation
+insert into test.t3 values (9, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
+ERROR 42000: Access denied; you need (at least one of) the BINLOG REPLAY privilege(s) for this operation
+# restart: --secure-timestamp=SUPER
+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');
+set @@system_versioning_insert_history= 1;
+insert into test.t3(z, row_start, row_end) values (7, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
+ERROR 42000: Access denied; you need (at least one of) the SUPER, BINLOG REPLAY privilege(s) for this operation
+insert into test.t3 values (7, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
+ERROR 42000: Access denied; you need (at least one of) the SUPER, BINLOG REPLAY privilege(s) for this operation
+use test;
+# restart: --secure-timestamp=NO
+drop tables t1, t2, t3;
+#
+# MDEV-29813 REPLACE/IGNORE does not work with historical records in InnoDB
+#
+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');
+select a,row_start,row_end into outfile 'mdev29813.txt' from t1 for system_time all;
+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);
+Warnings:
+Warning 1062 Duplicate entry '1' for key 'PRIMARY'
+select a,row_start,row_end from t1 for system_time all;
+a row_start row_end
+1 2022-01-01 00:00:00.000000 2023-01-01 00:00:00.000000
+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');
+Warnings:
+Warning 1062 Duplicate entry '1' for key 'PRIMARY'
+select a,row_start,row_end from t1 for system_time all;
+a row_start row_end
+1 2022-01-01 00:00:00.000000 2023-01-01 00:00:00.000000
+drop table t1;
+set sql_mode=default;
diff --git a/mysql-test/suite/versioning/r/insert2.result b/mysql-test/suite/versioning/r/insert2.result
new file mode 100644
index 00000000..f5c7b411
--- /dev/null
+++ b/mysql-test/suite/versioning/r/insert2.result
@@ -0,0 +1,86 @@
+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);
+create or replace table t1 (
+x int,
+y int as (x) virtual,
+sys_trx_start bigint unsigned as row start invisible,
+sys_trx_end bigint unsigned as row end invisible,
+period for system_time (sys_trx_start, sys_trx_end)
+) engine=innodb with system versioning;
+insert into t1 values (1, null);
+update t1 set x= x + 1;
+select x, y, sys_trx_end = 18446744073709551615 as current from t1 for system_time all;
+x y current
+2 2 1
+1 1 0
+create or replace table t1 (
+x int,
+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);
+insert into t1 (row_start) select row_end from t1;
+ERROR HY000: The value specified for generated column 'row_start' in table 't1' has been ignored
+set sql_mode='';
+insert into t1 (row_start, row_end) values (DEFAULT, 1);
+Warnings:
+Warning 1906 The value specified for generated column 'row_end' in table 't1' has been ignored
+set sql_mode=default;
+select @@sql_mode into @saved_mode;
+set sql_mode= '';
+insert into t1 (x, row_start, row_end) values (3, 4, 5);
+Warnings:
+Warning 1906 The value specified for generated column 'row_start' in table 't1' has been ignored
+Warning 1906 The value specified for generated column 'row_end' in table 't1' has been ignored
+set sql_mode= @saved_mode;
+insert into t1 (row_start, row_end) values (DEFAULT, DEFAULT);
+select * from t1;
+x
+1
+2
+NULL
+3
+NULL
+# MDEV-14792 INSERT without column list into table with explicit versioning columns produces bad data
+create or replace table t1 (
+i int,
+s timestamp(6) as row start,
+e timestamp(6) as row end,
+c varchar(8),
+period for system_time(s, e))
+with system versioning;
+insert into t1 values (1, null, null, 'foo');
+select i, c, e>TIMESTAMP'2038-01-01 00:00:00' AS current_row from t1;
+i c current_row
+1 foo 1
+drop table t1;
+drop table t2;
+#
+# MDEV-14871 Server crashes in fill_record / fill_record_n_invoke_before_triggers upon inserting into versioned table with trigger
+#
+create or replace table t1 (pk int primary key) with system versioning;
+create trigger tr before insert on t1 for each row select 1 into @a;
+insert into t1 values (1),(2);
+drop table t1;
+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;
+pk i row_end > '2038-01-01'
+1 1000 1
+drop table t1;
diff --git a/mysql-test/suite/versioning/r/load_data.result b/mysql-test/suite/versioning/r/load_data.result
new file mode 100644
index 00000000..1fcde73e
--- /dev/null
+++ b/mysql-test/suite/versioning/r/load_data.result
@@ -0,0 +1,10 @@
+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);
+SELECT a, b, c FROM t1 INTO OUTFILE '15330.data';
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+LOAD DATA INFILE '15330.data' IGNORE INTO TABLE t1 (a,b,c);
+Warnings:
+Warning 1062 Duplicate entry '1' for key 'a'
+LOAD DATA INFILE '15330.data' REPLACE INTO TABLE t1 (a,b,c);
+DROP TABLE t1;
diff --git a/mysql-test/suite/versioning/r/misc.result b/mysql-test/suite/versioning/r/misc.result
new file mode 100644
index 00000000..fadc896d
--- /dev/null
+++ b/mysql-test/suite/versioning/r/misc.result
@@ -0,0 +1,62 @@
+set time_zone='+00:00';
+#
+# MDEV-29750 triggers can modify history
+#
+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');
+Warnings:
+Warning 1906 The value specified for generated column 'b' in table 't' has been ignored
+Warning 1906 The value specified for generated column 's' in table 't' has been ignored
+Warning 1906 The value specified for generated column 'e' in table 't' has been ignored
+Warning 1906 The value specified for generated column 'b' in table 't' has been ignored
+Warning 1906 The value specified for generated column 's' in table 't' has been ignored
+Warning 1906 The value specified for generated column 'e' in table 't' has been ignored
+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;
+a b s e
+1 2 2010-10-10 10:10:10.000000 2038-01-19 03:14:07.999999
+2 3 2010-10-10 10:10:10.000000 2038-01-19 03:14:07.999999
+3 4 2010-10-10 10:10:10.000000 2038-01-19 03:14:07.999999
+4 5 2010-10-10 10:10:10.000000 2038-01-19 03:14:07.999999
+drop table t;
+set sql_mode=default, timestamp=default;
+#
+# End of 10.3 tests
+#
+set time_zone='+00:00';
+#
+# MDEV-29721 Inconsistency upon inserting history with visible system versioning columns
+#
+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;
+a s e
+1 2020-01-01 00:00:00.000000 2038-01-19 03:14:07.999999
+2 2020-02-02 00:00:00.000000 2038-01-19 03:14:07.999999
+3 2010-10-10 10:10:10.000000 2020-03-03 00:00:00.000000
+4 2010-10-10 10:10:10.000000 2020-04-04 00:00:00.000000
+5 2020-01-01 00:00:00.000000 2038-01-19 03:14:07.999999
+6 2020-02-02 00:00:00.000000 2038-01-19 03:14:07.999999
+7 2010-11-11 11:11:11.000000 2020-03-03 00:00:00.000000
+8 2010-11-11 11:11:11.000000 2020-04-04 00:00:00.000000
+drop table t1;
+#
+# MDEV-29830 Assertion `table->versioned()' in THD::vers_insert_history_fast
+#
+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);
+a
+drop table t1, t2;
+#
+# End of 10.11 tests
+#
diff --git a/mysql-test/suite/versioning/r/not_embedded.result b/mysql-test/suite/versioning/r/not_embedded.result
new file mode 100644
index 00000000..5d8380e0
--- /dev/null
+++ b/mysql-test/suite/versioning/r/not_embedded.result
@@ -0,0 +1,95 @@
+#
+# SYSTEM_VERSIONING_ASOF sysvar
+#
+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;
+a
+1
+connect subcon,127.0.0.1,root,,,$SERVER_MYPORT_1;
+connection subcon;
+select * from t as nonempty;
+a
+1
+disconnect subcon;
+connection default;
+set global system_versioning_asof= FROM_UNIXTIME(@before);
+select * from t as nonempty;
+a
+1
+connect subcon,127.0.0.1,root,,,$SERVER_MYPORT_1;
+connection subcon;
+select * from t as empty;
+a
+disconnect subcon;
+connection default;
+drop table t;
+set global system_versioning_asof= DEFAULT;
+set system_versioning_asof= DEFAULT;
+#
+# DELETE HISTORY and privileges
+#
+connect root,localhost,root,,test;
+connection root;
+create database mysqltest;
+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;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO `mysqltest_1`@`localhost`
+delete history from mysqltest.t before system_time now();
+ERROR 42000: DELETE HISTORY command denied to user 'mysqltest_1'@'localhost' for table `mysqltest`.`t`
+connection root;
+grant delete history on mysqltest.* to mysqltest_1@localhost;
+grant delete history on mysqltest.t to mysqltest_1@localhost;
+connection user1;
+show grants;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO `mysqltest_1`@`localhost`
+GRANT DELETE HISTORY ON `mysqltest`.* TO `mysqltest_1`@`localhost`
+GRANT DELETE HISTORY ON `mysqltest`.`t` TO `mysqltest_1`@`localhost`
+delete history from mysqltest.t before system_time now();
+connection root;
+grant all on *.* to mysqltest_1@localhost;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT ALL PRIVILEGES ON *.* TO `mysqltest_1`@`localhost`
+GRANT DELETE HISTORY ON `mysqltest`.* TO `mysqltest_1`@`localhost`
+GRANT DELETE HISTORY ON `mysqltest`.`t` TO `mysqltest_1`@`localhost`
+drop user mysqltest_1@localhost;
+drop database mysqltest;
+disconnect user1;
+disconnect root;
+connection default;
+#
+# MDEV-25559 Auto-create: infinite loop after interrupted lock wait
+#
+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');
+update t set a= a + 2;
+connection default;
+set timestamp= unix_timestamp('2000-01-01 01:00:00');
+update t set a= a + 3;
+connection con1;
+ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
+disconnect con1;
+connection default;
+commit;
+drop table t;
+set timestamp= default;
diff --git a/mysql-test/suite/versioning/r/online.result b/mysql-test/suite/versioning/r/online.result
new file mode 100644
index 00000000..b247ce49
--- /dev/null
+++ b/mysql-test/suite/versioning/r/online.result
@@ -0,0 +1,159 @@
+set system_versioning_alter_history=keep;
+create or replace table t (a int);
+alter table t add system versioning, lock=none;
+ERROR 0A000: LOCK=NONE is not supported. Reason: Not implemented for system-versioned timestamp tables. Try LOCK=SHARED
+alter table t add system versioning, algorithm=inplace;
+ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Not implemented for system-versioned timestamp tables. Try ALGORITHM=COPY
+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;
+alter table t drop system versioning, lock=none;
+ERROR 0A000: LOCK=NONE is not supported. Reason: Not implemented for system-versioned operations. Try LOCK=SHARED
+alter table t drop system versioning, algorithm=inplace;
+create or replace table t (
+a int, b int,
+row_start SYS_DATATYPE as row start invisible,
+row_end SYS_DATATYPE 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;
+a check_row(row_start, row_end)
+1 CURRENT ROW
+2 HISTORICAL ROW
+# MDEV-17038 ALTER TABLE CHANGE COLUMN c1 c1 bigint NOT NULL -
+# 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;
+# MDEV-16330 Allow instant change of WITH SYSTEM VERSIONING column attribute
+create or replace table t1 (
+a int,
+b int,
+row_start SYS_DATATYPE as row start invisible,
+row_end SYS_DATATYPE as row end invisible,
+period for system_time(row_start, row_end)
+) with system versioning;
+create or replace table t2 (
+a int without system versioning,
+b int,
+row_start SYS_DATATYPE as row start invisible,
+row_end SYS_DATATYPE 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;
+# without rebuild
+alter table t1
+change a a int without system versioning,
+algorithm=instant;
+affected rows: 0
+info: Records: 0 Duplicates: 0 Warnings: 0
+alter table t2
+change a a int with system versioning,
+add primary key pk (a),
+algorithm=instant;
+ERROR 0A000: ALGORITHM=INSTANT is not supported for this operation. Try ALGORITHM=INPLACE
+# with rebuild
+alter table t2
+change a a int with system versioning,
+add primary key pk (a);
+affected rows: 0
+info: Records: 0 Duplicates: 0 Warnings: 1
+Warnings:
+Warning 1280 Name 'pk' ignored for PRIMARY key.
+# restart
+update t1 set a=2;
+select count(*) from t1 for system_time all;
+count(*)
+1
+update t2 set a=2;
+select count(*) from t2 for system_time all;
+count(*)
+2
+drop table t1, t2;
+# rollback ALTER TABLE: nothing should change
+create or replace table t (
+a int,
+b int,
+row_start SYS_DATATYPE as row start invisible,
+row_end SYS_DATATYPE 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';
+prtype
+50179
+set @@system_versioning_alter_history=keep;
+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';
+prtype
+50179
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `row_start` SYS_DATATYPE GENERATED ALWAYS AS ROW START INVISIBLE,
+ `row_end` SYS_DATATYPE GENERATED ALWAYS AS ROW END INVISIBLE,
+ PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+select count(*) from t for system_time all;
+count(*)
+1
+update t set b=11;
+select count(*) from t for system_time all;
+count(*)
+2
+drop table t;
+# 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;
+alter table t drop system versioning, lock=none;
+ERROR 0A000: LOCK=NONE is not supported. Reason: Not implemented for system-versioned operations. Try LOCK=SHARED
+#
+# MDEV-17697 Broken versioning info after instant drop column
+#
+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);
+alter table t1 drop system versioning;
+#
+# MDEV-18173 Assertion `o->ind == vers_end' or `o->ind == vers_start' failed in dict_table_t::instant_column
+#
+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;
+#
+# MDEV-18122 Assertion `table->versioned() == m_prebuilt->table->versioned()' failed in ha_innobase::open
+#
+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;
diff --git a/mysql-test/suite/versioning/r/optimized.result b/mysql-test/suite/versioning/r/optimized.result
new file mode 100644
index 00000000..b14d8a04
--- /dev/null
+++ b/mysql-test/suite/versioning/r/optimized.result
@@ -0,0 +1,75 @@
+create table t (
+a int,
+b int without system versioning
+) with system versioning;
+insert into t values(1, 2);
+insert into t values(3, 4);
+select * from t;
+a b
+1 2
+3 4
+select a from t for system_time as of timestamp now(6);
+a
+1
+3
+select a, b, b+0 from t for system_time as of timestamp now(6);
+a b b+0
+1 2 2
+3 4 4
+select * from t for system_time as of timestamp now(6);
+a b
+1 2
+3 4
+select count(*) from t for system_time as of timestamp now(6) group by b;
+count(*)
+1
+1
+select * from t for system_time as of timestamp now(6) order by b asc;
+a b
+1 2
+3 4
+select * from t for system_time as of timestamp now(6) order by b desc;
+a b
+3 4
+1 2
+select * from t for system_time as of timestamp now(6) group by a having a=2;
+a b
+select * from t for system_time as of timestamp now(6) group by b having b=2;
+a b
+1 2
+select a from t for system_time as of timestamp now(6) where b=2;
+a
+1
+select a from t for system_time as of timestamp now(6) where b=NULL;
+a
+select a from t for system_time as of timestamp now(6) where b is NULL;
+a
+select count(*), b from t for system_time as of timestamp now(6) group by b having b=NULL;
+count(*) b
+select a, b from t;
+a b
+1 2
+3 4
+create or replace table t (
+a int,
+b int not null without system versioning
+) with system versioning;
+insert into t values (1, 2), (3, 4);
+select * from t for system_time as of timestamp now(6);
+a b
+1 2
+3 4
+select * from t for system_time as of timestamp now(6) where b is NULL;
+a b
+create or replace table t (x int with system versioning, y int);
+select column_name, extra from information_schema.columns where table_name='t';
+column_name extra
+x
+y WITHOUT SYSTEM VERSIONING
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `x` int(11) DEFAULT NULL,
+ `y` int(11) DEFAULT NULL WITHOUT SYSTEM VERSIONING
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+drop table t;
diff --git a/mysql-test/suite/versioning/r/partition,heap.rdiff b/mysql-test/suite/versioning/r/partition,heap.rdiff
new file mode 100644
index 00000000..d6c8363f
--- /dev/null
+++ b/mysql-test/suite/versioning/r/partition,heap.rdiff
@@ -0,0 +1,221 @@
+@@ -2132,85 +2132,6 @@
+ (PARTITION `p0` HISTORY ENGINE = X,
+ PARTITION `pn` CURRENT ENGINE = X)
+ drop tables t1, tp1;
+-# 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;
+-show create table tp1;
+-Table Create Table
+-tp1 CREATE TABLE `tp1` (
+- `x` int(11) NOT NULL AUTO_INCREMENT,
+- `t` timestamp(6) NULL DEFAULT '2001-11-11 11:11:11.000000',
+- `b` blob /*!100301 COMPRESSED*/ DEFAULT NULL,
+- `c` varchar(1033) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
+- `u` int(11) DEFAULT NULL,
+- `m` enum('a','b','c') NOT NULL DEFAULT 'a' COMMENT 'absolute',
+- `i1` tinyint(4) DEFAULT NULL,
+- `i2` smallint(6) DEFAULT NULL,
+- `i3` bigint(20) DEFAULT NULL,
+- `v1` timestamp(6) GENERATED ALWAYS AS (`t` + interval 1 day) VIRTUAL,
+- `v2` timestamp(6) GENERATED ALWAYS AS (`t` + interval 1 month) STORED,
+- `s` timestamp(6) GENERATED ALWAYS AS ROW START,
+- `e` timestamp(6) GENERATED ALWAYS AS ROW END,
+- `ps` date NOT NULL,
+- `pe` date NOT NULL,
+- PERIOD FOR `app_time` (`ps`, `pe`),
+- PRIMARY KEY (`x`,`e`),
+- UNIQUE KEY `x` (`x`,`u`,`e`),
+- KEY `three` (`i1`,`i2`,`i3`),
+- PERIOD FOR SYSTEM_TIME (`s`, `e`),
+- CONSTRAINT `check_constr` CHECK (`u` > -1)
+-) ENGINE=X DEFAULT CHARSET=ucs2 COLLATE=ucs2_general_ci WITH SYSTEM VERSIONING
+-show create table t1;
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `x` int(11) NOT NULL AUTO_INCREMENT,
+- `t` timestamp(6) NULL DEFAULT '2001-11-11 11:11:11.000000',
+- `b` blob /*!100301 COMPRESSED*/ DEFAULT NULL,
+- `c` varchar(1033) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
+- `u` int(11) DEFAULT NULL,
+- `m` enum('a','b','c') NOT NULL DEFAULT 'a' COMMENT 'absolute',
+- `i1` tinyint(4) DEFAULT NULL,
+- `i2` smallint(6) DEFAULT NULL,
+- `i3` bigint(20) DEFAULT NULL,
+- `v1` timestamp(6) GENERATED ALWAYS AS (`t` + interval 1 day) VIRTUAL,
+- `v2` timestamp(6) GENERATED ALWAYS AS (`t` + interval 1 month) STORED,
+- `s` timestamp(6) GENERATED ALWAYS AS ROW START,
+- `e` timestamp(6) GENERATED ALWAYS AS ROW END,
+- `ps` date NOT NULL,
+- `pe` date NOT NULL,
+- PERIOD FOR `app_time` (`ps`, `pe`),
+- PRIMARY KEY (`x`,`e`),
+- UNIQUE KEY `x` (`x`,`u`,`e`),
+- KEY `three` (`i1`,`i2`,`i3`),
+- PERIOD FOR SYSTEM_TIME (`s`, `e`),
+- CONSTRAINT `check_constr` CHECK (`u` > -1)
+-) ENGINE=X DEFAULT CHARSET=ucs2 COLLATE=ucs2_general_ci WITH SYSTEM VERSIONING
+- PARTITION BY RANGE (`x`)
+-(PARTITION `p0` VALUES LESS THAN (10) ENGINE = X,
+- PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = X)
+-drop tables t1, tp1;
+ #
+ # End of 10.7 tests
+ #
+@@ -2765,134 +2686,6 @@
+ Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p0`) is out of INTERVAL, need more HISTORY partitions
+ drop prepare s;
+ affected rows: 0
+-# Complex table
+-set timestamp= unix_timestamp('2000-01-01 00:00:00');
+-affected rows: 0
+-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);
+-affected rows: 0
+-show create table t1;
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `x` int(11) NOT NULL AUTO_INCREMENT,
+- `t` timestamp(6) NULL DEFAULT '2001-11-11 11:11:11.000000',
+- `b` blob /*!100301 COMPRESSED*/ DEFAULT NULL,
+- `c` varchar(1033) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
+- `u` int(11) DEFAULT NULL,
+- `m` enum('a','b','c') NOT NULL DEFAULT 'a' COMMENT 'absolute',
+- `i1` tinyint(4) DEFAULT NULL,
+- `i2` smallint(6) DEFAULT NULL,
+- `i3` bigint(20) DEFAULT NULL,
+- `v1` timestamp(6) GENERATED ALWAYS AS (`t` + interval 1 day) VIRTUAL,
+- `v2` timestamp(6) GENERATED ALWAYS AS (`t` + interval 1 month) STORED,
+- `s` timestamp(6) GENERATED ALWAYS AS ROW START,
+- `e` timestamp(6) GENERATED ALWAYS AS ROW END,
+- `ps` date NOT NULL,
+- `pe` date NOT NULL,
+- PERIOD FOR `app_time` (`ps`, `pe`),
+- PRIMARY KEY (`x`,`e`),
+- UNIQUE KEY `u` (`u`,`e`),
+- KEY `three` (`i1`,`i2`,`i3`),
+- PERIOD FOR SYSTEM_TIME (`s`, `e`),
+- CONSTRAINT `check_constr` CHECK (`u` > -1)
+-) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=ucs2 COLLATE=ucs2_general_ci WITH SYSTEM VERSIONING
+- PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+-(PARTITION `p2` HISTORY ENGINE = DEFAULT_ENGINE,
+- PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE)
+-affected rows: 1
+-insert into t1 (x, c, u, i1, i2, i3, ps, pe)
+-values (1, 'cc', 0, 1, 2, 3, '1999-01-01', '2000-01-01');
+-affected rows: 1
+-set timestamp= unix_timestamp('2000-01-01 01:00:00');
+-affected rows: 0
+-update t1 set x= x + 8;
+-affected rows: 1
+-info: Rows matched: 1 Changed: 1 Inserted: 1 Warnings: 0
+-show create table t1;
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `x` int(11) NOT NULL AUTO_INCREMENT,
+- `t` timestamp(6) NULL DEFAULT '2001-11-11 11:11:11.000000',
+- `b` blob /*!100301 COMPRESSED*/ DEFAULT NULL,
+- `c` varchar(1033) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
+- `u` int(11) DEFAULT NULL,
+- `m` enum('a','b','c') NOT NULL DEFAULT 'a' COMMENT 'absolute',
+- `i1` tinyint(4) DEFAULT NULL,
+- `i2` smallint(6) DEFAULT NULL,
+- `i3` bigint(20) DEFAULT NULL,
+- `v1` timestamp(6) GENERATED ALWAYS AS (`t` + interval 1 day) VIRTUAL,
+- `v2` timestamp(6) GENERATED ALWAYS AS (`t` + interval 1 month) STORED,
+- `s` timestamp(6) GENERATED ALWAYS AS ROW START,
+- `e` timestamp(6) GENERATED ALWAYS AS ROW END,
+- `ps` date NOT NULL,
+- `pe` date NOT NULL,
+- PERIOD FOR `app_time` (`ps`, `pe`),
+- PRIMARY KEY (`x`,`e`),
+- UNIQUE KEY `u` (`u`,`e`),
+- KEY `three` (`i1`,`i2`,`i3`),
+- PERIOD FOR SYSTEM_TIME (`s`, `e`),
+- CONSTRAINT `check_constr` CHECK (`u` > -1)
+-) ENGINE=DEFAULT_ENGINE AUTO_INCREMENT=10 DEFAULT CHARSET=ucs2 COLLATE=ucs2_general_ci WITH SYSTEM VERSIONING
+- PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+-(PARTITION `p2` HISTORY ENGINE = DEFAULT_ENGINE,
+- PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE,
+- PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE)
+-affected rows: 1
+-set timestamp= unix_timestamp('2000-01-01 02:00:00');
+-affected rows: 0
+-update t1 set x= x - 8;
+-affected rows: 1
+-info: Rows matched: 1 Changed: 1 Inserted: 1 Warnings: 0
+-show create table t1;
+-Table Create Table
+-t1 CREATE TABLE `t1` (
+- `x` int(11) NOT NULL AUTO_INCREMENT,
+- `t` timestamp(6) NULL DEFAULT '2001-11-11 11:11:11.000000',
+- `b` blob /*!100301 COMPRESSED*/ DEFAULT NULL,
+- `c` varchar(1033) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
+- `u` int(11) DEFAULT NULL,
+- `m` enum('a','b','c') NOT NULL DEFAULT 'a' COMMENT 'absolute',
+- `i1` tinyint(4) DEFAULT NULL,
+- `i2` smallint(6) DEFAULT NULL,
+- `i3` bigint(20) DEFAULT NULL,
+- `v1` timestamp(6) GENERATED ALWAYS AS (`t` + interval 1 day) VIRTUAL,
+- `v2` timestamp(6) GENERATED ALWAYS AS (`t` + interval 1 month) STORED,
+- `s` timestamp(6) GENERATED ALWAYS AS ROW START,
+- `e` timestamp(6) GENERATED ALWAYS AS ROW END,
+- `ps` date NOT NULL,
+- `pe` date NOT NULL,
+- PERIOD FOR `app_time` (`ps`, `pe`),
+- PRIMARY KEY (`x`,`e`),
+- UNIQUE KEY `u` (`u`,`e`),
+- KEY `three` (`i1`,`i2`,`i3`),
+- PERIOD FOR SYSTEM_TIME (`s`, `e`),
+- CONSTRAINT `check_constr` CHECK (`u` > -1)
+-) ENGINE=DEFAULT_ENGINE AUTO_INCREMENT=10 DEFAULT CHARSET=ucs2 COLLATE=ucs2_general_ci WITH SYSTEM VERSIONING
+- PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+-(PARTITION `p2` HISTORY ENGINE = DEFAULT_ENGINE,
+- PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE,
+- PARTITION `p3` HISTORY ENGINE = DEFAULT_ENGINE,
+- PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE)
+-affected rows: 1
+ # 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
diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result
new file mode 100644
index 00000000..4c1486d0
--- /dev/null
+++ b/mysql-test/suite/versioning/r/partition.result
@@ -0,0 +1,3450 @@
+set @save_persistent=@@global.innodb_stats_persistent;
+set global innodb_stats_persistent= 0;
+call mtr.add_suppression("need more HISTORY partitions");
+set system_versioning_alter_history=keep;
+# Check conventional partitioning on temporal tables
+create or replace table t1 (
+x int,
+row_start SYS_DATATYPE as row start invisible,
+row_end SYS_DATATYPE 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;
+x
+3
+300
+select * from t1 partition (p0);
+x
+3
+select * from t1 partition (p1);
+x
+300
+delete from t1;
+select * from t1;
+x
+select * from t1 partition (p0);
+x
+select * from t1 partition (p1);
+x
+select * from t1 for system_time all;
+x
+3
+300
+select * from t1 partition (p0) for system_time all;
+x
+3
+select * from t1 partition (p1) for system_time all;
+x
+300
+# Engine change native <-> non-native versioning prohibited
+create or replace table t1 (
+i int,
+row_start SYS_DATATYPE as row start invisible,
+row_end SYS_DATATYPE as row end invisible,
+period for system_time(row_start, row_end))
+engine=DEFAULT_ENGINE
+with system versioning partition by hash(i);
+alter table t1 engine=NON_DEFAULT_ENGINE;
+ERROR HY000: Not allowed for system-versioned `test`.`t1`. Change to/from native system versioning engine is not supported.
+## CREATE TABLE
+create or replace table t1 (x int)
+partition by system_time (
+partition p0 history,
+partition pn current);
+ERROR HY000: Table `t1` is not system-versioned
+create or replace table t1 (x int);
+alter table t1
+partition by system_time (
+partition p0 history,
+partition pn current);
+ERROR HY000: Table `t1` is not system-versioned
+create or replace table t1 (x int)
+with system versioning
+partition by system_time (
+partition p0 current);
+ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT
+create or replace table t1 (x int)
+with system versioning
+partition by system_time (
+partition p0 current,
+partition p1 current);
+ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT
+create or replace table t1 (x int)
+with system versioning
+partition by system_time (
+partition p0 history,
+partition p1 history);
+ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT
+create or replace table t1 (x int)
+with system versioning
+partition by system_time (
+partition pn current,
+partition p0 history);
+ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT
+create or replace table t1 (x int)
+with system versioning
+partition by system_time (
+partition p0,
+partition pn current);
+ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT
+create or replace table t1 (x int)
+with system versioning
+partition by system_time (
+partition p0 history,
+partition pn current);
+create or replace table t1 (a int)
+partition by range (a) (
+partition p0 history,
+partition p1 current);
+ERROR HY000: Wrong partition type `SYSTEM_TIME` for partitioning by `RANGE`
+create or replace table t1 (b int)
+partition by range (a) (
+partition p0 current,
+partition p1 history);
+ERROR HY000: Wrong partition type `SYSTEM_TIME` for partitioning by `RANGE`
+## ALTER TABLE
+alter table t1 add partition (
+partition p1 current);
+ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT
+alter table t1 add partition (
+partition p1 history);
+Warnings:
+Warning 4115 Maybe missing parameters: no rotation condition for multiple HISTORY partitions.
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME
+(PARTITION `p0` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE)
+insert into t1 values (1), (2);
+alter table t1 drop partition pn;
+ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT
+alter table t1 drop partition p1;
+alter table t1 drop partition p0;
+ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT
+select x from t1;
+x
+1
+2
+# 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);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME
+(PARTITION `custom_name` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE)
+# 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;
+alter table t1 reorganize partition p0, p1 into (partition p00 history);
+ERROR HY000: REORGANIZE PARTITION can only be used to reorganize partitions not to change their numbers
+alter table t1 reorganize partition p1 into (partition p1 history, partition p2 history);
+ERROR HY000: REORGANIZE PARTITION can only be used to reorganize partitions not to change their numbers
+# 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;
+alter table t1 add partition (partition px history);
+ERROR HY000: Wrong partition type `SYSTEM_TIME` for partitioning by `HASH`
+## 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;
+x A B
+execute select_pn;
+x C D
+1 1 1
+set @str= concat('select row_start from t1 partition (pn) into @ts0');
+prepare stmt from @str;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+execute stmt;
+drop prepare stmt;
+set @now= now(6);
+delete from t1;
+execute select_p0;
+x A B
+1 1 1
+execute select_pn;
+x C D
+set @str= concat('select row_start from t1 partition (p0) into @ts1');
+prepare stmt from @str;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+execute stmt;
+drop prepare stmt;
+select @ts0 = @ts1;
+@ts0 = @ts1
+1
+set @now= now(6);
+insert into t1 values (2);
+execute select_p0;
+x A B
+1 1 0
+execute select_pn;
+x C D
+2 1 1
+set @str= concat('select row_start from t1 partition (pn) into @ts0');
+prepare stmt from @str;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+execute stmt;
+drop prepare stmt;
+set @now= now(6);
+update t1 set x = x + 1;
+execute select_p0;
+x A B
+1 1 0
+2 1 1
+execute select_pn;
+x C D
+3 1 1
+drop prepare select_p0;
+drop prepare select_pn;
+set @str= concat('select row_start from t1 partition (p0) where x = 2 into @ts1');
+prepare stmt from @str;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+execute stmt;
+drop prepare stmt;
+set @str= concat('select row_end from t1 partition (p0) where x = 2 into @ts2');
+prepare stmt from @str;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+execute stmt;
+drop prepare stmt;
+set @str= concat('select row_start from t1 partition (pn) into @ts3');
+prepare stmt from @str;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+execute stmt;
+drop prepare stmt;
+select @ts0 = @ts1;
+@ts0 = @ts1
+1
+select @ts2 = @ts3;
+@ts2 = @ts3
+1
+#
+# Rotation by LIMIT
+#
+create or replace table t1 (x int)
+with system versioning
+partition by system_time limit 0 partitions 3;
+ERROR HY000: Wrong parameters for partitioned `t1`: wrong value for 'LIMIT'
+create or replace table t1 (x int)
+with system versioning
+partition by system_time limit 2 partitions 3;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME LIMIT 2
+PARTITIONS 3
+alter table t1 drop partition non_existent;
+ERROR HY000: Wrong partition name or partition list
+insert into t1 values (1), (2), (3), (4), (5), (6);
+select * from t1 partition (pn);
+x
+1
+2
+3
+4
+5
+6
+delete from t1 where x < 4;
+delete from t1;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p1`) is out of LIMIT, need more HISTORY partitions
+# You see warning above ^
+select * from t1 partition (p0);
+x
+1
+2
+3
+select * from t1 partition (p1);
+x
+4
+5
+6
+insert into t1 values (7), (8);
+### warn about full partition
+delete from t1;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p1`) is out of LIMIT, need more HISTORY partitions
+# You see warning above ^
+select * from t1 partition (p1) order by x;
+x
+4
+5
+6
+7
+8
+#
+# Rotation by INTERVAL
+#
+create or replace table t1 (x int)
+with system versioning
+partition by system_time interval 0 second partitions 3;
+ERROR HY000: Wrong parameters for partitioned `t1`: wrong value for 'INTERVAL'
+create table t1 (i int) with system versioning
+partition by system_time interval 6 day limit 98;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'limit 98' at line 2
+create or replace table t1 (pk int) with system versioning
+partition by system_time interval 10 year partitions 3;
+ERROR 22003: TIMESTAMP value is out of range in 'INTERVAL'
+# 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';
+partition_name partition_ordinal_position partition_method timediff(partition_description, @ts)
+p0 1 SYSTEM_TIME 00:00:00.000000
+pn 2 SYSTEM_TIME NULL
+Warnings:
+Warning 1292 Incorrect time value: 'CURRENT'
+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';
+partition_name partition_ordinal_position partition_method timediff(partition_description, @ts)
+p0 1 SYSTEM_TIME 00:00:00.000000
+p1 2 SYSTEM_TIME 01:00:00.000000
+p2 3 SYSTEM_TIME 02:00:00.000000
+pn 4 SYSTEM_TIME NULL
+Warnings:
+Warning 1292 Incorrect time value: 'CURRENT'
+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';
+partition_name partition_ordinal_position partition_method timediff(partition_description, @ts)
+p1 1 SYSTEM_TIME 01:00:00.000000
+p2 2 SYSTEM_TIME 02:00:00.000000
+pn 3 SYSTEM_TIME NULL
+Warnings:
+Warning 1292 Incorrect time value: 'CURRENT'
+alter table t1 drop partition p2;
+ERROR HY000: Can only drop oldest partitions when rotating by INTERVAL
+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_name partition_ordinal_position partition_method timediff(partition_description, @ts)
+p1 1 SYSTEM_TIME 01:00:00.000000
+p2 2 SYSTEM_TIME 02:00:00.000000
+pn 3 SYSTEM_TIME NULL
+Warnings:
+Warning 1292 Incorrect time value: 'CURRENT'
+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;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p1`) is out of INTERVAL, need more HISTORY partitions
+select subpartition_name, partition_description, table_rows from information_schema.partitions where table_schema='test' and table_name='t1';
+subpartition_name partition_description table_rows
+p1sp0 2001-02-04 00:00:00 1
+p1sp1 2001-02-04 00:00:00 1
+pnsp0 CURRENT 0
+pnsp1 CURRENT 0
+select * from t1 partition (p1);
+i
+1
+2
+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';
+subpartition_name partition_description table_rows
+p1sp0 2001-02-04 00:00:00 1
+p1sp1 2001-02-04 00:00:00 0
+p0sp0 2001-02-05 00:00:00 1
+p0sp1 2001-02-05 00:00:00 1
+p2sp0 2001-02-06 00:00:00 0
+p2sp1 2001-02-06 00:00:00 0
+pnsp0 CURRENT 0
+pnsp1 CURRENT 2
+select * from t1 partition (p1);
+i
+1
+select * from t1 partition (p0);
+i
+5
+2
+select * from t1 partition (p2);
+i
+alter table t1 rebuild partition p0, p1, p2;
+select * from t1 partition (p1);
+i
+1
+select * from t1 partition (p0);
+i
+5
+2
+select * from t1 partition (p2);
+i
+## 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);
+select * from t1;
+i
+4
+6
+explain partitions select * from t1;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 pn_pnsp0,pn_pnsp1 ALL NULL NULL NULL NULL # Using where
+explain partitions select * from t1 for system_time as of '2001-02-04 10:20:30';
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0_p0sp0,p0_p0sp1,p2_p2sp0,p2_p2sp1,pn_pnsp0,pn_pnsp1 ALL NULL NULL NULL NULL # Using where
+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;
+i
+1
+explain partitions select * from t1 for system_time all where row_end = @ts;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p1_p1sp0,p1_p1sp1 # NULL NULL NULL NULL # #
+#
+# MDEV-16023 Unfortunate error message WARN_VERS_PART_FULL
+#
+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;
+Level Code Message
+# Cleanup
+set timestamp= default;
+## INTERVAL ... STARTS
+create or replace table t1 (i int) with system versioning
+partition by system_time interval 1 day starts 'a';
+ERROR HY000: Wrong parameters for partitioned `t1`: wrong value for 'STARTS'
+create or replace table t1 (i int) with system versioning
+partition by system_time interval 1 day starts '00:00:00';
+ERROR HY000: Wrong parameters for partitioned `t1`: wrong value for 'STARTS'
+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 HY000: Wrong parameters for partitioned `t1`: wrong value for 'STARTS'
+create or replace table t1 (i int) with system versioning
+partition by system_time interval 1 day starts 946684800;
+ERROR HY000: Wrong parameters for partitioned `t1`: wrong value for 'STARTS'
+create or replace table t1 (i int) with system versioning
+partition by system_time interval 1 day starts '2000-01-01 00:00:00';
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 DAY STARTS TIMESTAMP'2000-01-01 00:00:00'
+PARTITIONS 2
+# 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;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 DAY STARTS TIMESTAMP'2000-01-01 00:00:00'
+PARTITIONS 2
+create or replace table t1 (i int) with system versioning
+partition by system_time interval 1 day starts '2000-01-01 00:00:01';
+Warnings:
+Warning 4164 `t1`: STARTS is later than query time, first history partition may exceed INTERVAL value
+# 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;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 SECOND STARTS TIMESTAMP'1999-12-15 13:33:33'
+PARTITIONS 2
+create or replace table t1 (i int) with system versioning
+partition by system_time interval 1 minute;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 MINUTE STARTS TIMESTAMP'1999-12-15 13:33:00'
+PARTITIONS 2
+create or replace table t1 (i int) with system versioning
+partition by system_time interval 1 hour;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'1999-12-15 13:00:00'
+PARTITIONS 2
+create or replace table t1 (i int) with system versioning
+partition by system_time interval 1 day;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 DAY STARTS TIMESTAMP'1999-12-15 00:00:00'
+PARTITIONS 2
+create or replace table t1 (i int) with system versioning
+partition by system_time interval 1 month;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 MONTH STARTS TIMESTAMP'1999-12-15 00:00:00'
+PARTITIONS 2
+create or replace table t1 (i int) with system versioning
+partition by system_time interval 1 year;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 YEAR STARTS TIMESTAMP'1999-12-15 00:00:00'
+PARTITIONS 2
+# 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;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 86400 SECOND STARTS TIMESTAMP'1999-12-15 13:33:33'
+PARTITIONS 2
+# 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';
+Warnings:
+Warning 4164 `t1`: STARTS is later than query time, first history partition may exceed INTERVAL value
+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;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 DAY STARTS TIMESTAMP'2000-01-01 00:00:00'
+PARTITIONS 2
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `i` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 DAY STARTS TIMESTAMP'2000-01-01 00:00:00'
+PARTITIONS 2
+set time_zone="+00:00";
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 DAY STARTS TIMESTAMP'1999-12-31 21:00:00'
+PARTITIONS 2
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `i` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 DAY STARTS TIMESTAMP'1999-12-31 21:00:00'
+PARTITIONS 2
+# Test rotation
+set timestamp= unix_timestamp('2001-01-01 00:00:00');
+# 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;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p1`) is out of INTERVAL, need more HISTORY partitions
+set timestamp= unix_timestamp('2001-01-01 00:00:02');
+update t1 set i= i + 1;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p1`) is out of INTERVAL, need more HISTORY partitions
+select *, row_end from t1 partition (p0);
+i row_end
+select *, row_end from t1 partition (p1);
+i row_end
+0 2001-01-01 00:00:01.000000
+1 2001-01-01 00:00:02.000000
+set timestamp= unix_timestamp('2000-01-01 00:00:00');
+# 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;
+Warnings:
+Warning 4164 `t1`: STARTS is later than query time, first history partition may exceed INTERVAL value
+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);
+i row_end
+0 2000-01-01 00:00:01.000000
+1 2000-01-02 00:00:01.000000
+2 2000-01-03 00:00:01.000000
+select *, row_end from t1 partition (p1);
+i row_end
+3 2000-01-04 00:00:01.000000
+# 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;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p1`) is out of INTERVAL, need more HISTORY partitions
+set timestamp= unix_timestamp('2000-01-04 00:00:01');
+update t1 set i= i + 1;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p1`) is out of INTERVAL, need more HISTORY partitions
+alter table t1 add partition (partition p2 history, partition p3 history);
+select *, row_end from t1 partition (p0);
+i row_end
+0 2000-01-01 00:00:01.000000
+select *, row_end from t1 partition (p1);
+i row_end
+1 2000-01-02 00:00:01.000000
+select *, row_end from t1 partition (p2);
+i row_end
+2 2000-01-03 00:00:01.000000
+select *, row_end from t1 partition (p3);
+i row_end
+3 2000-01-04 00:00:01.000000
+drop tables t1, t2;
+## 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);
+x
+1
+3
+5
+select * from t1 partition (pnsp1);
+x
+2
+4
+delete from t1 where x < 3;
+delete from t1;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p1`) is out of LIMIT, need more HISTORY partitions
+# You see warning above ^
+delete from t1;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p1`) is out of LIMIT, need more HISTORY partitions
+# You see warning above ^ (no matter if nothing was deleted)
+select * from t1 partition (p0sp0);
+x
+1
+select * from t1 partition (p0sp1);
+x
+2
+select * from t1 partition (p1sp0);
+x
+3
+5
+select * from t1 partition (p1sp1);
+x
+4
+# 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);
+a
+1
+# 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);
+f_int1
+1
+#
+# TRX_ID versioning (moved from partition_innodb.test)
+#
+# MDEV-15951 system versioning by trx id doesn't work with partitioning
+# currently trx_id does not support partitioning by system_time
+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
+);
+ERROR HY000: `row_start` must be of type TIMESTAMP(6) for system-versioned table `t1`
+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;
+alter table t1 partition by system_time (
+partition p0 history,
+partition pn current
+);
+ERROR HY000: `row_start` must be of type TIMESTAMP(6) for system-versioned table `t1`
+drop table t1;
+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 HY000: Transaction-precise system-versioned tables do not support partitioning by ROW START or ROW END
+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 HY000: Transaction-precise system-versioned tables do not support partitioning by ROW START or ROW END
+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 HY000: Transaction-precise system-versioned tables do not support partitioning by ROW START or ROW END
+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)
+);
+ERROR HY000: Transaction-precise system-versioned tables do not support partitioning by ROW START or ROW END
+#
+# Assertion in ALTER on warning from partitioning LIMIT [#446]
+#
+create or replace table t1 (x int) with system versioning;
+insert into t1 values (1), (2);
+delete from t1;
+alter table t1 partition by system_time limit 1 (
+partition p1 history,
+partition pn current);
+#
+# MDEV-14649 Assertion `t->mysql_col_len == 8' failed in row_insert_for_mysql
+#
+create or replace table t1 (i int) engine=innodb partition by key(i);
+alter table t1 add system versioning;
+insert into t1 values();
+#
+# MDEV-14722 Assertion in ha_commit_trans for sub-statement
+#
+create or replace table t1 (i int) with system versioning
+partition by system_time interval 1 day;
+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;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+insert into t2 values (1);
+#
+# MDEV-14740 Locking assertion for system_time partitioning
+#
+create or replace table t1 (i int) with system versioning
+partition by system_time interval 1 week;
+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;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+insert into t2 values (1);
+#
+# MDEV-14747 ALTER PARTITION BY SYSTEM_TIME after LOCK TABLES
+#
+create or replace table t1 (x int) with system versioning;
+lock table t1 write;
+alter table t1 partition by system_time interval 1 week (
+partition p1 history,
+partition pn current);
+unlock tables;
+#
+# MDEV-14748 Assertion in ha_myisammrg::attach_children()
+#
+create or replace table t1 (x int) engine=myisam with system versioning
+partition by system_time interval 1 month (partition p1 history, partition pn current);
+create or replace table t2 (x int) engine=myisam;
+create or replace table t3 (x int) engine=merge union=(t2);
+create or replace table t4 (x int) engine=myisam;
+create or replace trigger tr after insert on t4 for each row insert into t2
+( select x from t3 ) union ( select x from t1 );
+insert into t4 values (1);
+#
+# MDEV-14821 Assertion failure
+#
+create or replace table t1 (x int) with system versioning;
+insert into t1 values (0), (1);
+update t1 set x= x + 1;
+alter table t1 partition by system_time limit 1 (
+partition p1 history,
+partition p2 history,
+partition pn current);
+delete from t1 where x = 1;
+# You see warning above ^
+delete from t1 where x = 2;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p2`) is out of LIMIT, need more HISTORY partitions
+# You see warning above ^
+#
+# MDEV-14923 Assertion upon INSERT into locked versioned partitioned table
+#
+create or replace table t1 (x int) with system versioning
+partition by system_time;
+lock table t1 write;
+alter table t1 add partition (partition p0 history);
+ERROR HY000: Duplicate partition name p0
+insert into t1 values (1);
+unlock tables;
+#
+# MDEV-15103 Assertion in ha_partition::part_records() for updating VIEW
+#
+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;
+#
+# MDEV-15168 Unexpected ER_VERS_ENGINE_UNSUPPORTED upon dropping versioning on a partitioned table
+#
+create or replace table t (a int) with system versioning
+partition by system_time;
+alter table t drop system versioning;
+ERROR HY000: Can not DROP SYSTEM VERSIONING for table `t` partitioned BY SYSTEM_TIME
+#
+# MDEV-15191 Assertion `bit < (map)->n_bits' failed in bitmap_is_set upon INSERT
+#
+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;
+#
+# 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
+#
+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;
+#
+# MDEV-14823 Wrong error message upon selecting from a system_time partition
+#
+create or replace table t1 (i int) with system versioning partition by system_time limit 10;
+select * from t1 partition (p0) for system_time all;
+ERROR HY000: SYSTEM_TIME partitions in table `t1` does not support historical query
+# 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;
+call sp;
+ERROR HY000: SYSTEM_TIME partitions in table `t1` does not support historical query
+call sp;
+ERROR HY000: SYSTEM_TIME partitions in table `t1` does not support historical query
+drop procedure sp;
+#
+# MDEV-15380 Index for versioned table gets corrupt after partitioning and DELETE
+#
+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);
+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);
+#
+# MDEV-18136 Server crashes in Item_func_dyncol_create::prepare_arguments
+#
+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);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `pk` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 7 SECOND STARTS TIMESTAMP'2018-04-11 17:00:04'
+(PARTITION `ver_p1` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `ver_pn` CURRENT ENGINE = DEFAULT_ENGINE)
+set timestamp= default;
+#
+# MDEV-18794 Assertion `!m_innodb' failed in ha_partition::cmp_ref upon SELECT from partitioned table
+#
+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;
+pk i c
+1 1 a
+drop table t1;
+#
+# MDEV-19175 Server crashes in ha_partition::vers_can_native upon INSERT DELAYED into versioned partitioned table
+#
+create or replace table t1 (f int) with system versioning partition by hash(f);
+insert delayed into t1 values (1);
+#
+# MDEV-20068 History partition rotation is not done under LOCK TABLES
+#
+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;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p1`) is out of LIMIT, need more HISTORY partitions
+# You see warning above ^
+delete from t1;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p1`) is out of LIMIT, need more HISTORY partitions
+# You see warning above ^
+unlock tables;
+#
+# MDEV-20336 Assertion bitmap_is_set(read_partitions) upon SELECT FOR UPDATE from versioned table
+#
+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';
+pk
+#
+# MDEV-19903 Setup default partitions for system versioning
+#
+create or replace table t1 (x int) with system versioning partition by system_time;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME
+PARTITIONS 2
+# 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;
+PARTITION_NAME PARTITION_METHOD PARTITION_DESCRIPTION
+p0 SYSTEM_TIME NULL
+pn SYSTEM_TIME CURRENT
+create or replace table t1 (x int) with system versioning partition by system_time limit 10 partitions 4;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME LIMIT 10
+PARTITIONS 4
+# 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;
+PARTITION_NAME PARTITION_METHOD PARTITION_DESCRIPTION
+p0 SYSTEM_TIME NULL
+p1 SYSTEM_TIME NULL
+p2 SYSTEM_TIME NULL
+pn SYSTEM_TIME CURRENT
+# Test cleanup
+drop view v1;
+drop tables t, t1, t2, t3, t4;
+#
+# MDEV-18957 UPDATE with LIMIT clause is wrong for versioned partitioned tables
+#
+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;
+x a
+1 bar
+2 bar
+3 bar
+4 bar
+drop table t1;
+#
+# MDEV-21011 Table corruption reported for versioned partitioned table after DELETE: "Found a misplaced row"
+#
+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;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+drop table t1;
+#
+# MDEV-21233 Assertion `m_extra_cache' failed in ha_partition::late_extra_cache
+#
+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;
+drop table t1, t2;
+#
+# MDEV-20515 multi-update tries to position updated table by null reference
+#
+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;
+drop table t1, t2;
+#
+# MDEV-17091 Assertion `old_part_id == m_last_part' failed in
+# ha_partition::update_row or `part_id == m_last_part' in
+# ha_partition::delete_row upon UPDATE/DELETE after dropping versioning
+#
+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);
+# expected to hit same partition
+select * from t1 partition (p0);
+pk f
+1 10
+2 20
+alter table t1 drop system versioning;
+# 1 and 2 are expected to be in different partitions
+select * from t1 partition(p0);
+pk f
+1 10
+select * from t1 partition(p1);
+pk f
+2 20
+update t1 set f=pk;
+delete from t1;
+drop table t1;
+#
+# MDEV-22413 Server hangs upon UPDATE/DELETE on a view reading from versioned partitioned table
+#
+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';
+# You see warning above ^
+create or replace view v1 as select * from t1 for system_time all;
+update v1 set f = '';
+ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
+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';
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p2`) is out of LIMIT, need more HISTORY partitions
+create or replace view v1 as select * from t1 for system_time all;
+update v1 set f= '';
+ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
+delete from v1;
+ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
+drop view v1;
+drop table t1;
+#
+# MDEV-22112 Assertion `tab_part_info->part_type == RANGE_PARTITION || tab_part_info->part_type == LIST_PARTITION' failed in prep_alter_part_table
+#
+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);
+alter table t1 add partition (partition p2);
+ERROR HY000: Wrong partition type `HASH` for partitioning by `SYSTEM_TIME`
+# MDEV-17891 Assertion failures in select_insert::abort_result_set and
+# mysql_load upon attempt to replace into a full table
+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);
+# fill the table until full
+insert into t1 () values (),(),(),(),(),(),(),(),(),(),(),(),(),(),(),();
+insert into t1 (f) select f from t1;
+ERROR HY000: The table 't1' is full
+# leave space for exactly one record in current partition
+delete from t1 where pk = 1;
+# copy all data into history partition
+replace into t1 select * from t1;
+replace into t1 select * from t1;
+ERROR HY000: The table 't1' is full
+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 (),(),(),(),(),(),(),(),(),(),(),(),(),(),(),();
+select * into outfile 'MDEV-17891.data' from t1;
+load data infile 'MDEV-17891.data' replace into table t1;
+load data infile 'MDEV-17891.data' replace into table t1;
+ERROR HY000: The table 't1' is full
+load data infile 'MDEV-17891.data' replace into table t1;
+ERROR HY000: The table 't1' is full
+set @@max_heap_table_size= 1048576;
+drop table t1;
+#
+# MDEV-22178 Assertion `info->alias.str' failed in partition_info::check_partition_info instead of ER_VERS_WRONG_PARTS
+#
+create or replace table t1 (a int) with system versioning;
+alter table t1 partition by system_time (partition pn current);
+ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT
+drop table t1;
+#
+# MDEV-22247 History partition overflow leads to wrong SELECT result
+#
+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;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p1`) is out of INTERVAL, need more HISTORY partitions
+select *, row_start, row_end from t1 for system_time as of '2000-01-01 02:00:00';
+x row_start row_end
+1 2000-01-01 00:00:00.000000 2000-01-01 02:00:01.000000
+explain partitions select * from t1 for system_time as of '2000-01-01 02:00:00';
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p1,pn ALL NULL NULL NULL NULL # Using where
+explain partitions select * from t1;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 pn # NULL NULL NULL NULL # #
+drop table t1;
+#
+# MDEV-27244 Table corruption upon adding serial data type
+#
+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;
+#
+# MDEV-27217 DELETE partition selection doesn't work for history partitions
+#
+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);
+delete from t1 partition (p1);
+ERROR HY000: Not allowed for system-versioned table `test`.`t1`
+delete from t1 partition (p0, pn);
+ERROR HY000: Not allowed for system-versioned table `test`.`t1`
+delete from t1 partition (p0, p1);
+ERROR HY000: Not allowed for system-versioned table `test`.`t1`
+delete from t1 partition (p0, p1, pn);
+ERROR HY000: Not allowed for system-versioned table `test`.`t1`
+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);
+delete from t1 partition (p0, pn);
+ERROR HY000: Not allowed for system-versioned table `test`.`t1`
+delete from t1 partition (p0, p1, pn);
+ERROR HY000: Not allowed for system-versioned table `test`.`t1`
+lock tables t1 write;
+delete from t1 partition (p0, pn);
+ERROR HY000: Not allowed for system-versioned table `test`.`t1`
+delete from t1;
+unlock tables;
+drop table t1;
+set timestamp= default;
+#
+# MDEV-25546 LIMIT partitioning does not respect ROLLBACK
+#
+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;
+replace into t1 select seq from seq_1_to_80;
+replace into t1 select seq from seq_1_to_70;
+replace into t1 select seq from seq_1_to_60;
+select partition_name, table_rows
+from information_schema.partitions
+where table_name = 't1';
+partition_name table_rows
+p0 150
+p1 60
+pn 90
+rollback;
+select partition_name, table_rows
+from information_schema.partitions
+where table_name = 't1';
+partition_name table_rows
+p0 0
+p1 0
+pn 90
+replace into t1 select seq from seq_1_to_10;
+select partition_name, table_rows
+from information_schema.partitions
+where table_name = 't1';
+partition_name table_rows
+p0 10
+p1 0
+pn 90
+drop table t1;
+#
+# MDEV-28271 Assertion on TRUNCATE PARTITION for PARTITION BY SYSTEM_TIME
+#
+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);
+x
+0
+select * from t1 partition (p1);
+x
+1
+select * from t1 partition (pn);
+x
+2
+delete from t1;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p2`) is out of LIMIT, need more HISTORY partitions
+delete history from t1;
+select * from t1 partition (p0);
+x
+select * from t1 partition (p1);
+x
+select * from t1 partition (pn);
+x
+insert into t1 values (0);
+update t1 set x= x + 1;
+update t1 set x= x + 1;
+# TRUNCATE PARTITION ALL does the same
+alter table t1 truncate partition all;
+select * from t1 partition (p0);
+x
+select * from t1 partition (p1);
+x
+select * from t1 partition (pn);
+x
+insert into t1 values (0);
+update t1 set x= x + 1;
+update t1 set x= x + 1;
+# TRUNCATE PARTITION deletes data from HISTORY partition
+alter table t1 truncate partition p1;
+select * from t1 partition (p0);
+x
+0
+select * from t1 partition (p1);
+x
+select * from t1 partition (pn);
+x
+2
+# or from CURRENT partition
+alter table t1 truncate partition pn;
+select * from t1 partition (p0);
+x
+0
+select * from t1 partition (p1);
+x
+select * from t1 partition (pn);
+x
+drop table t1;
+#
+# MDEV-20077 Warning on full history partition is delayed until next DML statement
+#
+# 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;
+# p0 is filled with 100 records (no warnings):
+delete from t1 where x <= 99;
+# p1 is filled with 1 + 100 records (warning is printed):
+delete from t1 where x <= 100;
+delete from t1;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p1`) is out of LIMIT, need more HISTORY partitions
+# You see warning above ^
+select count(*) from t1 partition (p0);
+count(*)
+100
+select count(*) from t1 partition (p1);
+count(*)
+101
+drop table t1;
+# 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;
+# (LOCK TABLES) p0 is filled with 100 records (no warnings):
+delete from t1 where x <= 99;
+# (LOCK TABLES) p1 is filled with 1 + 100 records (warning is printed):
+delete from t1 where x <= 100;
+delete from t1;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p1`) is out of LIMIT, need more HISTORY partitions
+# You see warning above ^
+unlock tables;
+select count(*) from t1 partition (p0);
+count(*)
+100
+select count(*) from t1 partition (p1);
+count(*)
+101
+drop table t1;
+# 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;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p1`) is out of LIMIT, need more HISTORY partitions
+# You see warning above ^
+select count(*) from t1 partition (p0);
+count(*)
+100
+select count(*) from t1 partition (p1);
+count(*)
+101
+drop table t1;
+# 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;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p1`) is out of LIMIT, need more HISTORY partitions
+# You see warning above ^
+select count(*) from t1 partition (p0);
+count(*)
+100
+select count(*) from t1 partition (p1);
+count(*)
+100
+drop tables t1, t2;
+# 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;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p1`) is out of LIMIT, need more HISTORY partitions
+# You see warning above ^
+select count(*) from t1 partition (p0);
+count(*)
+100
+select count(*) from t1 partition (p1);
+count(*)
+100
+drop tables t1, t2;
+# 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);
+count(*)
+100
+select count(*) from t1 partition (p1);
+count(*)
+1
+drop table t1;
+# 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);
+count(*)
+100
+select count(*) from t1 partition (p1);
+count(*)
+1
+drop tables t1, t2;
+# 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);
+count(*)
+100
+select count(*) from t1 partition (p1);
+count(*)
+1
+drop table t1;
+# 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;
+select x into outfile 'MDEV-20077.data' from t1;
+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);
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p1`) is out of LIMIT, need more HISTORY partitions
+# You see warning above ^
+select count(*) from t1 partition (p0);
+count(*)
+100
+select count(*) from t1 partition (p1);
+count(*)
+100
+drop table t1;
+# 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;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p1`) is out of LIMIT, need more HISTORY partitions
+# You see warning above ^
+select count(*) from t1 partition (p0);
+count(*)
+100
+select count(*) from t1 partition (p1);
+count(*)
+100
+drop table t1;
+#
+# MDEV-28552 Assertion `inited==RND' failed in handler::ha_rnd_end
+#
+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;
+drop table tcount, t;
+#
+# 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
+#
+set timestamp=unix_timestamp('2000-01-01 00:00:00');
+create table t1 (i int);
+create table t2 (i int);
+alter table t1 partition by system_time
+interval (select i from t2) day (partition p1 history, partition pn current);
+ERROR 42000: INTERVAL does not support subqueries or stored functions
+drop table t1;
+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 42000: INTERVAL does not support subqueries or stored functions
+create table t1 (id int) with system versioning
+partition by system_time
+interval "hello" day (partition p1 history, partition pn current);
+ERROR HY000: Wrong parameters for partitioned `t1`: wrong value for 'INTERVAL'
+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);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL '3-11' YEAR_MONTH STARTS TIMESTAMP'2000-01-01 00:00:00'
+(PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE)
+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);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL '3 11' DAY_HOUR STARTS TIMESTAMP'2000-01-01 00:00:00'
+(PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE)
+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);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL '3 11:12' DAY_MINUTE STARTS TIMESTAMP'2000-01-01 00:00:00'
+(PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE)
+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);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL '3 11:12:13' DAY_SECOND STARTS TIMESTAMP'2000-01-01 00:00:00'
+(PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE)
+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);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL '11:12' HOUR_MINUTE STARTS TIMESTAMP'2000-01-01 00:00:00'
+(PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE)
+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);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL '11:12:13' HOUR_SECOND STARTS TIMESTAMP'2000-01-01 00:00:00'
+(PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE)
+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);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL '12:13' MINUTE_SECOND STARTS TIMESTAMP'2000-01-01 00:00:00'
+(PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE)
+drop table t1;
+create table t1 (id int) with system versioning
+partition by system_time interval "12:13.123" minute_microsecond (partition p1 history, partition pn current);
+ERROR HY000: Wrong parameters for partitioned `t1`: wrong value for 'INTERVAL'
+#
+# End of 10.3 tests
+#
+#
+# MDEV-22283 Server crashes in key_copy or unexpected error 156: The table already existed in the storage engine
+#
+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);
+Warnings:
+Warning 4115 Maybe missing parameters: no rotation condition for multiple HISTORY partitions.
+show table status;
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+t1 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL Got error 174 "Fatal error during initialization of handler" from storage engine Aria NULL NULL
+Warnings:
+Warning 1030 Got error 174 "Fatal error during initialization of handler" from storage engine Aria
+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);
+drop table t1;
+#
+# MDEV-18794 Assertion `!m_innodb' failed in ha_partition::cmp_ref upon SELECT from partitioned table
+#
+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;
+pk i c
+1 1 a
+drop table t1;
+#
+# End of 10.4 tests
+#
+#
+# MDEV-22153 ALTER add default history partitions makes table inaccessible
+#
+create or replace table t1 (x int) with system versioning partition by system_time;
+alter table t1 add partition partitions 1;
+Warnings:
+Warning 4115 Maybe missing parameters: no rotation condition for multiple HISTORY partitions.
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME
+PARTITIONS 3
+alter table t1 add partition partitions 2;
+Warnings:
+Warning 4115 Maybe missing parameters: no rotation condition for multiple HISTORY partitions.
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME
+PARTITIONS 5
+alter table t1 add partition partitions 3;
+Warnings:
+Warning 4115 Maybe missing parameters: no rotation condition for multiple HISTORY partitions.
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME
+PARTITIONS 8
+drop tables t1;
+#
+# MDEV-22207 Drop default history partitions renders table inaccessible
+#
+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;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME LIMIT 1
+(PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p3` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE)
+alter table t1 add partition partitions 1;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME LIMIT 1
+(PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p3` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p2` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE)
+drop tables t1;
+#
+# MDEV-22155 ALTER add default history partitions name clash on non-default partitions
+#
+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;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME LIMIT 1
+(PARTITION `p2` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p8` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p3` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p4` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p5` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE)
+alter table t1 add partition partitions 8;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME LIMIT 1
+(PARTITION `p2` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p8` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p3` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p4` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p5` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p9` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p10` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p11` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p12` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p13` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p14` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p15` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p16` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE)
+drop tables t1;
+#
+# MDEV-27328 Change of SYSTEM_TIME partitioning options is not possible without data copy
+#
+create or replace table t1 (f int) with system versioning
+partition by hash(f);
+alter table t1 partition by system_time;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `f` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME
+PARTITIONS 2
+create or replace table t1 (f int) with system versioning
+partition by system_time;
+alter table t1 partition by hash(f);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `f` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY HASH (`f`)
+create or replace table t1 (x int) with system versioning;
+alter table t1 partition by system_time;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME
+PARTITIONS 2
+create or replace table t1 (x int) with system versioning
+partition by system_time limit 100 partitions 4;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME LIMIT 100
+PARTITIONS 4
+alter table t1 add partition partitions 2;
+alter table t1 partition by system_time;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME
+PARTITIONS 6
+alter table t1 partition by system_time limit 33;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME LIMIT 33
+PARTITIONS 6
+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;
+alter table t1 partition by system_time interval 1 hour
+starts '2000-01-01 00:00:00';
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00'
+PARTITIONS 6
+select * from t1 partition (p0);
+x
+0
+select * from t1 partition (p1);
+x
+1
+2
+select * from t1 partition (p2);
+x
+3
+select * from t1 partition (pn);
+x
+4
+set timestamp= default;
+alter table t1 partition by system_time limit 1;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME LIMIT 1
+PARTITIONS 6
+update t1 set x= x + 1;
+update t1 set x= x + 1;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p4`) is out of LIMIT, need more HISTORY partitions
+# You see warning above ^
+select * from t1 partition (p0);
+x
+0
+select * from t1 partition (p1);
+x
+1
+2
+select * from t1 partition (p2);
+x
+3
+select * from t1 partition (p3);
+x
+4
+select * from t1 partition (p4);
+x
+5
+select * from t1 partition (pn);
+x
+6
+drop table t1;
+# End of 10.6 tests
+#
+# MDEV-22166 MIGRATE PARTITION: move out partition into a table
+#
+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;
+show create table tp2;
+Table Create Table
+tp2 CREATE TABLE `tp2` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=X DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+select * from tp2;
+x
+13
+select * from tp2 for system_time all order by x;
+x
+12
+13
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=X DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY RANGE (`x`)
+(PARTITION `p1` VALUES LESS THAN (10) ENGINE = X,
+ PARTITION `p3` VALUES LESS THAN (30) ENGINE = X,
+ PARTITION `p4` VALUES LESS THAN (40) ENGINE = X,
+ PARTITION `p5` VALUES LESS THAN (50) ENGINE = X,
+ PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = X)
+select * from t1 order by x;
+x
+3
+23
+33
+43
+53
+select * from t1 for system_time all order by x;
+x
+2
+3
+22
+23
+32
+33
+42
+43
+52
+53
+# SP
+create or replace procedure sp()
+alter table t1 convert partition p3 to table tp3;
+call sp;
+show create table tp3;
+Table Create Table
+tp3 CREATE TABLE `tp3` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=X DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+select * from tp3;
+x
+23
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=X DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY RANGE (`x`)
+(PARTITION `p1` VALUES LESS THAN (10) ENGINE = X,
+ PARTITION `p4` VALUES LESS THAN (40) ENGINE = X,
+ PARTITION `p5` VALUES LESS THAN (50) ENGINE = X,
+ PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = X)
+select * from t1 order by x;
+x
+3
+33
+43
+53
+drop table tp3;
+call sp;
+ERROR HY000: Wrong partition name or partition list
+call sp;
+ERROR HY000: Wrong partition name or partition list
+drop procedure sp;
+# 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;
+unlock tables;
+show create table tp4;
+Table Create Table
+tp4 CREATE TABLE `tp4` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=X DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+select * from tp4;
+x
+33
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=X DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY RANGE (`x`)
+(PARTITION `p1` VALUES LESS THAN (10) ENGINE = X,
+ PARTITION `p5` VALUES LESS THAN (50) ENGINE = X,
+ PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = X)
+select * from t1 order by x;
+x
+3
+43
+53
+drop table tp4;
+lock tables t1 write;
+execute stmt;
+ERROR HY000: Wrong partition name or partition list
+call sp;
+ERROR HY000: Wrong partition name or partition list
+drop prepare stmt;
+unlock tables;
+drop procedure sp;
+unlock tables;
+drop tables t1, tp2;
+# 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;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p2`) is out of LIMIT, need more HISTORY partitions
+select * from t1 partition (p1);
+x
+12
+alter table t1 convert partition pn to table tp1;
+ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT
+alter table t1 convert partition p1 to table tp1;
+show create table tp1;
+Table Create Table
+tp1 CREATE TABLE `tp1` (
+ `x` int(11) DEFAULT NULL,
+ `row_start` timestamp(6) GENERATED ALWAYS AS ROW START INVISIBLE,
+ `row_end` timestamp(6) GENERATED ALWAYS AS ROW END INVISIBLE,
+ PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`)
+) ENGINE=X DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+select * from tp1;
+x
+select * from tp1 for system_time all;
+x
+12
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL,
+ `row_start` timestamp(6) GENERATED ALWAYS AS ROW START INVISIBLE,
+ `row_end` timestamp(6) GENERATED ALWAYS AS ROW END INVISIBLE,
+ PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`)
+) ENGINE=X DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME LIMIT 1
+(PARTITION `p0` HISTORY ENGINE = X,
+ PARTITION `p2` HISTORY ENGINE = X,
+ PARTITION `pn` CURRENT ENGINE = X)
+select * from t1 order by x;
+x
+3
+13
+23
+select * from t1 for system_time all order by x;
+x
+2
+3
+13
+22
+23
+drop tables t1, tp1;
+# 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);
+x
+2
+select * from t1 partition (p1);
+x
+12
+select * from t1 partition (p2);
+x
+22
+alter table t1 convert partition p1 to table tp1;
+ERROR HY000: Can only drop oldest partitions when rotating by INTERVAL
+alter table t1 convert partition p0 to table tp0;
+alter table t1 convert partition p1 to table tp1;
+alter table t1 convert partition p2 to table tp2;
+ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT
+show create table tp0;
+Table Create Table
+tp0 CREATE TABLE `tp0` (
+ `x` int(11) DEFAULT NULL,
+ `row_start` timestamp(6) GENERATED ALWAYS AS ROW START INVISIBLE,
+ `row_end` timestamp(6) GENERATED ALWAYS AS ROW END INVISIBLE,
+ PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`)
+) ENGINE=X DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+show create table tp1;
+Table Create Table
+tp1 CREATE TABLE `tp1` (
+ `x` int(11) DEFAULT NULL,
+ `row_start` timestamp(6) GENERATED ALWAYS AS ROW START INVISIBLE,
+ `row_end` timestamp(6) GENERATED ALWAYS AS ROW END INVISIBLE,
+ PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`)
+) ENGINE=X DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+select * from tp0;
+x
+select * from tp1;
+x
+select * from tp0 for system_time all;
+x
+2
+select * from tp1 for system_time all;
+x
+12
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL,
+ `row_start` timestamp(6) GENERATED ALWAYS AS ROW START INVISIBLE,
+ `row_end` timestamp(6) GENERATED ALWAYS AS ROW END INVISIBLE,
+ PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`)
+) ENGINE=X DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 02:00:00'
+(PARTITION `p2` HISTORY ENGINE = X,
+ PARTITION `pn` CURRENT ENGINE = X)
+select * from t1;
+x
+3
+13
+23
+select * from t1 for system_time all order by x;
+x
+3
+13
+22
+23
+drop tables t1, tp0, tp1;
+# 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;
+show create table tp1;
+Table Create Table
+tp1 CREATE TABLE `tp1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=X DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=X DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME LIMIT 1
+(PARTITION `p0` HISTORY ENGINE = X,
+ PARTITION `pn` CURRENT ENGINE = X)
+drop tables t1, tp1;
+# 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;
+show create table tp1;
+Table Create Table
+tp1 CREATE TABLE `tp1` (
+ `x` int(11) NOT NULL AUTO_INCREMENT,
+ `t` timestamp(6) NULL DEFAULT '2001-11-11 11:11:11.000000',
+ `b` blob /*!100301 COMPRESSED*/ DEFAULT NULL,
+ `c` varchar(1033) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
+ `u` int(11) DEFAULT NULL,
+ `m` enum('a','b','c') NOT NULL DEFAULT 'a' COMMENT 'absolute',
+ `i1` tinyint(4) DEFAULT NULL,
+ `i2` smallint(6) DEFAULT NULL,
+ `i3` bigint(20) DEFAULT NULL,
+ `v1` timestamp(6) GENERATED ALWAYS AS (`t` + interval 1 day) VIRTUAL,
+ `v2` timestamp(6) GENERATED ALWAYS AS (`t` + interval 1 month) STORED,
+ `s` timestamp(6) GENERATED ALWAYS AS ROW START,
+ `e` timestamp(6) GENERATED ALWAYS AS ROW END,
+ `ps` date NOT NULL,
+ `pe` date NOT NULL,
+ PERIOD FOR `app_time` (`ps`, `pe`),
+ PRIMARY KEY (`x`,`e`),
+ UNIQUE KEY `x` (`x`,`u`,`e`),
+ KEY `three` (`i1`,`i2`,`i3`),
+ PERIOD FOR SYSTEM_TIME (`s`, `e`),
+ CONSTRAINT `check_constr` CHECK (`u` > -1)
+) ENGINE=X DEFAULT CHARSET=ucs2 COLLATE=ucs2_general_ci WITH SYSTEM VERSIONING
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) NOT NULL AUTO_INCREMENT,
+ `t` timestamp(6) NULL DEFAULT '2001-11-11 11:11:11.000000',
+ `b` blob /*!100301 COMPRESSED*/ DEFAULT NULL,
+ `c` varchar(1033) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
+ `u` int(11) DEFAULT NULL,
+ `m` enum('a','b','c') NOT NULL DEFAULT 'a' COMMENT 'absolute',
+ `i1` tinyint(4) DEFAULT NULL,
+ `i2` smallint(6) DEFAULT NULL,
+ `i3` bigint(20) DEFAULT NULL,
+ `v1` timestamp(6) GENERATED ALWAYS AS (`t` + interval 1 day) VIRTUAL,
+ `v2` timestamp(6) GENERATED ALWAYS AS (`t` + interval 1 month) STORED,
+ `s` timestamp(6) GENERATED ALWAYS AS ROW START,
+ `e` timestamp(6) GENERATED ALWAYS AS ROW END,
+ `ps` date NOT NULL,
+ `pe` date NOT NULL,
+ PERIOD FOR `app_time` (`ps`, `pe`),
+ PRIMARY KEY (`x`,`e`),
+ UNIQUE KEY `x` (`x`,`u`,`e`),
+ KEY `three` (`i1`,`i2`,`i3`),
+ PERIOD FOR SYSTEM_TIME (`s`, `e`),
+ CONSTRAINT `check_constr` CHECK (`u` > -1)
+) ENGINE=X DEFAULT CHARSET=ucs2 COLLATE=ucs2_general_ci WITH SYSTEM VERSIONING
+ PARTITION BY RANGE (`x`)
+(PARTITION `p0` VALUES LESS THAN (10) ENGINE = X,
+ PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = X)
+drop tables t1, tp1;
+#
+# MDEV-29841 Partition by system_time can be converted into table but not back
+#
+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;
+alter table t convert table tp to partition p0;
+ERROR HY000: CONVERT TABLE TO PARTITION can only be used on RANGE/LIST partitions
+drop tables t, tp;
+#
+# End of 10.7 tests
+#
+#
+# MDEV-17554 Auto-create new partition for system versioned tables
+# with history partitioned by INTERVAL/LIMIT
+#
+create or replace table t1 (x int) with system versioning
+partition by system_time limit 1 auto;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME LIMIT 1 AUTO
+PARTITIONS 2
+# Turn off AUTO
+alter table t1 partition by system_time limit 1;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME LIMIT 1
+PARTITIONS 2
+# Get AUTO back
+alter table t1 partition by system_time limit 1 auto;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME LIMIT 1 AUTO
+PARTITIONS 2
+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;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME LIMIT 1 AUTO
+PARTITIONS 2
+# 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');
+update t1 set x= x + 1;
+ERROR HY000: Versioned table `test`.`t1`: adding HISTORY partition(s) failed
+show warnings;
+Level Code Message
+Warning 1499 Too many partitions (including subpartitions) were defined
+Error 4189 Versioned table `test`.`t1`: adding HISTORY partition(s) failed
+# 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");
+set timestamp= unix_timestamp('2000-01-01 01:00:00');
+update t1 set x= x + 2;
+ERROR HY000: Got error 184 "Tablespace already exists" from storage engine InnoDB
+show warnings;
+Level Code Message
+Error 1030 Got error 184 "Tablespace already exists" from storage engine InnoDB
+Warning 4189 Versioned table `test`.`t1`: adding HISTORY partition(s) failed
+# 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;
+# Check how pruning boundaries work
+explain partitions select * from t1 for system_time as of '2000-01-01 00:59:58';
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0,pn # NULL NULL NULL NULL # #
+explain partitions select * from t1 for system_time as of '2000-01-01 00:59:59';
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0,pn # NULL NULL NULL NULL # #
+explain partitions select * from t1 for system_time as of '2000-01-01 01:00:00';
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0,pn # NULL NULL NULL NULL # #
+select * from t1 for system_time as of '2000-01-01 00:09:59';
+x
+440
+set timestamp= unix_timestamp('2000-01-01 02:00:00');
+update t1 set x= x + 1;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p0`) is out of INTERVAL, need more HISTORY partitions
+select * from t1 for system_time as of '2000-01-01 01:00:00';
+x
+441
+select * from t1 partition (p0) order by x;
+x
+440
+441
+# 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';
+x
+441
+select * from t1 partition (p0) order by x;
+x
+440
+# Check pruning after ALTER
+explain partitions select * from t1 for system_time as of '2000-01-01 00:59:58';
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p0,p1,p2,p3,pn # NULL NULL NULL NULL # #
+explain partitions select * from t1 for system_time as of '2000-01-01 00:59:59';
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p1,p2,p3,pn # NULL NULL NULL NULL # #
+explain partitions select * from t1 for system_time as of '2000-01-01 01:00:00';
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p1,p2,p3,pn # NULL NULL NULL NULL # #
+drop table t1;
+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;
+affected rows: 0
+insert into t1 values (1);
+affected rows: 1
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 3600 SECOND STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 3
+affected rows: 1
+set timestamp= unix_timestamp('2000-01-01 02:00:00');
+affected rows: 0
+update t1 set x= x + 1;
+affected rows: 1
+info: Rows matched: 1 Changed: 1 Inserted: 1 Warnings: 0
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 3600 SECOND STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 4
+affected rows: 1
+set timestamp= unix_timestamp('2000-01-01 03:00:00');
+affected rows: 0
+update t1 set x= x + 2;
+affected rows: 1
+info: Rows matched: 1 Changed: 1 Inserted: 1 Warnings: 0
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 3600 SECOND STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 5
+affected rows: 1
+set timestamp= unix_timestamp('2000-01-01 00:00:00');
+affected rows: 0
+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);
+affected rows: 0
+insert into t1 values (1);
+affected rows: 1
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+(PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p3` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE)
+affected rows: 1
+set timestamp= unix_timestamp('2000-01-01 02:00:00');
+affected rows: 0
+update t1 set x= x + 3;
+affected rows: 1
+info: Rows matched: 1 Changed: 1 Inserted: 1 Warnings: 0
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+(PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p3` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p2` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE)
+affected rows: 1
+set timestamp= unix_timestamp('2000-01-01 03:00:00');
+affected rows: 0
+update t1 set x= x + 4;
+affected rows: 1
+info: Rows matched: 1 Changed: 1 Inserted: 1 Warnings: 0
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+(PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p3` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p2` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p4` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE)
+affected rows: 1
+set timestamp= unix_timestamp('2000-01-01 04:00:00');
+affected rows: 0
+lock tables t1 write;
+affected rows: 0
+update t1 set x= x + 5;
+affected rows: 1
+info: Rows matched: 1 Changed: 1 Inserted: 1 Warnings: 0
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+(PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p3` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p2` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p4` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p5` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE)
+affected rows: 1
+unlock tables;
+affected rows: 0
+set timestamp= default;
+affected rows: 0
+# Couple of more LOCK TABLES cases
+create or replace table t1 (x int) with system versioning
+partition by system_time limit 1 auto;
+affected rows: 0
+lock tables t1 write;
+affected rows: 0
+insert into t1 values (1);
+affected rows: 1
+update t1 set x= x + 1;
+affected rows: 1
+info: Rows matched: 1 Changed: 1 Inserted: 1 Warnings: 0
+update t1 set x= x + 2;
+affected rows: 1
+info: Rows matched: 1 Changed: 1 Inserted: 1 Warnings: 0
+update t1 set x= x + 3;
+affected rows: 1
+info: Rows matched: 1 Changed: 1 Inserted: 1 Warnings: 0
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME LIMIT 1 AUTO
+PARTITIONS 4
+affected rows: 1
+unlock tables;
+affected rows: 0
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME LIMIT 1 AUTO
+PARTITIONS 4
+affected rows: 1
+# Overflow prevention under LOCK TABLES
+create or replace table t1 (x int)
+with system versioning partition by system_time
+limit 10 auto;
+affected rows: 0
+insert into t1 values (1), (2), (3), (4), (5), (6), (7), (8), (9);
+affected rows: 9
+info: Records: 9 Duplicates: 0 Warnings: 0
+update t1 set x= x + 10;
+affected rows: 9
+info: Rows matched: 9 Changed: 9 Inserted: 9 Warnings: 0
+lock tables t1 write;
+affected rows: 0
+update t1 set x= 1 where x = 11;
+affected rows: 1
+info: Rows matched: 1 Changed: 1 Inserted: 1 Warnings: 0
+update t1 set x= 2 where x = 12;
+affected rows: 1
+info: Rows matched: 1 Changed: 1 Inserted: 1 Warnings: 0
+update t1 set x= 3 where x = 13;
+affected rows: 1
+info: Rows matched: 1 Changed: 1 Inserted: 1 Warnings: 0
+unlock tables;
+affected rows: 0
+select count(x) from t1 partition (p0);
+count(x)
+10
+affected rows: 1
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME LIMIT 10 AUTO
+PARTITIONS 3
+affected rows: 1
+drop tables t1;
+affected rows: 0
+# Test VIEW, LOCK TABLES
+set timestamp= unix_timestamp('2000-01-01 00:00:00');
+affected rows: 0
+create or replace table t1 (x int) with system versioning
+partition by system_time interval 1 hour auto;
+affected rows: 0
+create or replace view v1 as select * from t1;
+affected rows: 0
+insert into t1 values (1);
+affected rows: 1
+set timestamp= unix_timestamp('2000-01-01 01:00:00');
+affected rows: 0
+update v1 set x= x + 2;
+affected rows: 1
+info: Rows matched: 1 Changed: 1 Inserted: 1 Warnings: 0
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 3
+affected rows: 1
+set timestamp= unix_timestamp('2000-01-01 02:00:00');
+affected rows: 0
+lock tables v1 write;
+affected rows: 0
+update v1 set x= x + 3;
+affected rows: 1
+info: Rows matched: 1 Changed: 1 Inserted: 1 Warnings: 0
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 4
+affected rows: 1
+unlock tables;
+affected rows: 0
+drop view v1;
+affected rows: 0
+drop tables t1;
+affected rows: 0
+set timestamp= unix_timestamp('2000-01-01 00:00:00');
+affected rows: 0
+create or replace table t1 (x int) with system versioning
+partition by system_time interval 1 hour auto partitions 3;
+affected rows: 0
+create or replace table t2 (y int) with system versioning
+partition by system_time interval 1 hour auto;
+affected rows: 0
+insert into t1 values (1);
+affected rows: 1
+insert into t2 values (2);
+affected rows: 1
+set timestamp= unix_timestamp('2000-01-01 01:00:00');
+affected rows: 0
+update t1, t2 set x= x + 1, y= y + 1;
+affected rows: 2
+info: Rows matched: 2 Changed: 2 Warnings: 0
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 3
+affected rows: 1
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `y` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 3
+affected rows: 1
+set timestamp= unix_timestamp('2000-01-01 02:00:00');
+affected rows: 0
+update t1, t2 set x= x + 1, y= y + 1;
+affected rows: 2
+info: Rows matched: 2 Changed: 2 Warnings: 0
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 4
+affected rows: 1
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `y` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 4
+affected rows: 1
+set timestamp= unix_timestamp('2000-01-01 03:00:00');
+affected rows: 0
+update t1, t2 set t1.x= 0 where t1.x< t2.y;
+affected rows: 1
+info: Rows matched: 1 Changed: 1 Warnings: 0
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 5
+affected rows: 1
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `y` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS ok
+affected rows: 1
+drop tables t1, t2;
+affected rows: 0
+# PS, SP, LOCK TABLES
+set timestamp= unix_timestamp('2000-01-01 00:00:00');
+affected rows: 0
+create or replace table t1 (x int) with system versioning
+partition by system_time interval 1 hour auto;
+affected rows: 0
+insert into t1 values (1);
+affected rows: 1
+set timestamp= unix_timestamp('2000-01-01 01:00:00');
+affected rows: 0
+execute immediate 'update t1 set x= x + 5';
+affected rows: 1
+info: Rows matched: 1 Changed: 1 Inserted: 1 Warnings: 0
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 3
+affected rows: 1
+prepare s from 'update t1 set x= x + 6';
+affected rows: 0
+info: Statement prepared
+set timestamp= unix_timestamp('2000-01-01 02:00:00');
+affected rows: 0
+execute s;
+affected rows: 1
+info: Rows matched: 1 Changed: 1 Inserted: 1 Warnings: 0
+execute s;
+affected rows: 1
+info: Rows matched: 1 Changed: 1 Inserted: 1 Warnings: 0
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 4
+affected rows: 1
+set timestamp= unix_timestamp('2000-01-01 03:00:00');
+affected rows: 0
+lock tables t1 write;
+affected rows: 0
+execute s;
+affected rows: 1
+info: Rows matched: 1 Changed: 1 Inserted: 1 Warnings: 0
+execute s;
+affected rows: 1
+info: Rows matched: 1 Changed: 1 Inserted: 1 Warnings: 0
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 5
+affected rows: 1
+unlock tables;
+affected rows: 0
+drop prepare s;
+affected rows: 0
+create procedure sp() update t1 set x= x + 7;
+affected rows: 0
+set timestamp= unix_timestamp('2000-01-01 04:00:00');
+affected rows: 0
+call sp;
+affected rows: 1
+call sp;
+affected rows: 1
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 6
+affected rows: 1
+set timestamp= unix_timestamp('2000-01-01 05:00:00');
+affected rows: 0
+lock tables t1 write;
+affected rows: 0
+call sp;
+affected rows: 1
+call sp;
+affected rows: 1
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 7
+affected rows: 1
+unlock tables;
+affected rows: 0
+drop procedure sp;
+affected rows: 0
+set timestamp= unix_timestamp('2001-01-01 00:00:00');
+affected rows: 0
+create or replace table t1 (i int) with system versioning
+partition by system_time interval 1 day starts '2001-01-01 00:00:00';
+affected rows: 0
+insert into t1 values (0);
+affected rows: 1
+set timestamp= unix_timestamp('2001-01-01 00:00:01');
+affected rows: 0
+prepare s from 'update t1 set i= i + 1';
+affected rows: 0
+info: Statement prepared
+execute s;
+affected rows: 1
+info: Rows matched: 1 Changed: 1 Inserted: 1 Warnings: 0
+set timestamp= unix_timestamp('2001-01-02 00:00:01');
+affected rows: 0
+execute s;
+affected rows: 1
+info: Rows matched: 1 Changed: 1 Inserted: 1 Warnings: 1
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p0`) is out of INTERVAL, need more HISTORY partitions
+drop prepare s;
+affected rows: 0
+# Complex table
+set timestamp= unix_timestamp('2000-01-01 00:00:00');
+affected rows: 0
+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);
+affected rows: 0
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) NOT NULL AUTO_INCREMENT,
+ `t` timestamp(6) NULL DEFAULT '2001-11-11 11:11:11.000000',
+ `b` blob /*!100301 COMPRESSED*/ DEFAULT NULL,
+ `c` varchar(1033) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
+ `u` int(11) DEFAULT NULL,
+ `m` enum('a','b','c') NOT NULL DEFAULT 'a' COMMENT 'absolute',
+ `i1` tinyint(4) DEFAULT NULL,
+ `i2` smallint(6) DEFAULT NULL,
+ `i3` bigint(20) DEFAULT NULL,
+ `v1` timestamp(6) GENERATED ALWAYS AS (`t` + interval 1 day) VIRTUAL,
+ `v2` timestamp(6) GENERATED ALWAYS AS (`t` + interval 1 month) STORED,
+ `s` timestamp(6) GENERATED ALWAYS AS ROW START,
+ `e` timestamp(6) GENERATED ALWAYS AS ROW END,
+ `ps` date NOT NULL,
+ `pe` date NOT NULL,
+ PERIOD FOR `app_time` (`ps`, `pe`),
+ PRIMARY KEY (`x`,`e`),
+ UNIQUE KEY `u` (`u`,`e`),
+ KEY `three` (`i1`,`i2`,`i3`),
+ PERIOD FOR SYSTEM_TIME (`s`, `e`),
+ CONSTRAINT `check_constr` CHECK (`u` > -1)
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=ucs2 COLLATE=ucs2_general_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+(PARTITION `p2` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE)
+affected rows: 1
+insert into t1 (x, c, u, i1, i2, i3, ps, pe)
+values (1, 'cc', 0, 1, 2, 3, '1999-01-01', '2000-01-01');
+affected rows: 1
+set timestamp= unix_timestamp('2000-01-01 01:00:00');
+affected rows: 0
+update t1 set x= x + 8;
+affected rows: 1
+info: Rows matched: 1 Changed: 1 Inserted: 1 Warnings: 0
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) NOT NULL AUTO_INCREMENT,
+ `t` timestamp(6) NULL DEFAULT '2001-11-11 11:11:11.000000',
+ `b` blob /*!100301 COMPRESSED*/ DEFAULT NULL,
+ `c` varchar(1033) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
+ `u` int(11) DEFAULT NULL,
+ `m` enum('a','b','c') NOT NULL DEFAULT 'a' COMMENT 'absolute',
+ `i1` tinyint(4) DEFAULT NULL,
+ `i2` smallint(6) DEFAULT NULL,
+ `i3` bigint(20) DEFAULT NULL,
+ `v1` timestamp(6) GENERATED ALWAYS AS (`t` + interval 1 day) VIRTUAL,
+ `v2` timestamp(6) GENERATED ALWAYS AS (`t` + interval 1 month) STORED,
+ `s` timestamp(6) GENERATED ALWAYS AS ROW START,
+ `e` timestamp(6) GENERATED ALWAYS AS ROW END,
+ `ps` date NOT NULL,
+ `pe` date NOT NULL,
+ PERIOD FOR `app_time` (`ps`, `pe`),
+ PRIMARY KEY (`x`,`e`),
+ UNIQUE KEY `u` (`u`,`e`),
+ KEY `three` (`i1`,`i2`,`i3`),
+ PERIOD FOR SYSTEM_TIME (`s`, `e`),
+ CONSTRAINT `check_constr` CHECK (`u` > -1)
+) ENGINE=DEFAULT_ENGINE AUTO_INCREMENT=10 DEFAULT CHARSET=ucs2 COLLATE=ucs2_general_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+(PARTITION `p2` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE)
+affected rows: 1
+set timestamp= unix_timestamp('2000-01-01 02:00:00');
+affected rows: 0
+update t1 set x= x - 8;
+affected rows: 1
+info: Rows matched: 1 Changed: 1 Inserted: 1 Warnings: 0
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) NOT NULL AUTO_INCREMENT,
+ `t` timestamp(6) NULL DEFAULT '2001-11-11 11:11:11.000000',
+ `b` blob /*!100301 COMPRESSED*/ DEFAULT NULL,
+ `c` varchar(1033) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
+ `u` int(11) DEFAULT NULL,
+ `m` enum('a','b','c') NOT NULL DEFAULT 'a' COMMENT 'absolute',
+ `i1` tinyint(4) DEFAULT NULL,
+ `i2` smallint(6) DEFAULT NULL,
+ `i3` bigint(20) DEFAULT NULL,
+ `v1` timestamp(6) GENERATED ALWAYS AS (`t` + interval 1 day) VIRTUAL,
+ `v2` timestamp(6) GENERATED ALWAYS AS (`t` + interval 1 month) STORED,
+ `s` timestamp(6) GENERATED ALWAYS AS ROW START,
+ `e` timestamp(6) GENERATED ALWAYS AS ROW END,
+ `ps` date NOT NULL,
+ `pe` date NOT NULL,
+ PERIOD FOR `app_time` (`ps`, `pe`),
+ PRIMARY KEY (`x`,`e`),
+ UNIQUE KEY `u` (`u`,`e`),
+ KEY `three` (`i1`,`i2`,`i3`),
+ PERIOD FOR SYSTEM_TIME (`s`, `e`),
+ CONSTRAINT `check_constr` CHECK (`u` > -1)
+) ENGINE=DEFAULT_ENGINE AUTO_INCREMENT=10 DEFAULT CHARSET=ucs2 COLLATE=ucs2_general_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+(PARTITION `p2` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `p3` HISTORY ENGINE = DEFAULT_ENGINE,
+ PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE)
+affected rows: 1
+# 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;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) NOT NULL,
+ PRIMARY KEY (`x`)
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 3
+# 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);
+select x into outfile 'MDEV-17554.data' from t1;
+set timestamp= unix_timestamp('2000-01-01 01:00:00');
+load data infile 'MDEV-17554.data' replace into table t1 (x);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) NOT NULL,
+ PRIMARY KEY (`x`)
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 3
+# 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);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 3
+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');
+update t1 set x= x + 10;
+connection con2;
+set timestamp= unix_timestamp('2000-01-01 02:00:00');
+update t1 set x= x + 20;
+connection con3;
+set timestamp= unix_timestamp('2000-01-01 02:00:00');
+update t1 set x= x + 30;
+connection con4;
+set timestamp= unix_timestamp('2000-01-01 02:00:00');
+update t1 set x= x + 40;
+connection con5;
+set timestamp= unix_timestamp('2000-01-01 02:00:00');
+update t1 set x= x + 50;
+connection con6;
+set timestamp= unix_timestamp('2000-01-01 02:00:00');
+update t1 set x= x + 60;
+connection con7;
+set timestamp= unix_timestamp('2000-01-01 02:00:00');
+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;
+disconnect con1;
+connection con2;
+disconnect con2;
+connection con3;
+disconnect con3;
+connection con4;
+disconnect con4;
+connection con5;
+disconnect con5;
+connection con6;
+disconnect con6;
+connection con7;
+disconnect con7;
+disconnect con8;
+connection default;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 4
+drop tables t1;
+set timestamp= default;
+# 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);
+update t1 set x= x + N; # (running multithreaded for 3 times)
+drop tables t1;
+# 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;
+x
+1
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 3
+connection default;
+commit;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 3
+set timestamp= unix_timestamp('2000-01-01 02:00:00');
+start transaction;
+update t1 set x= 1;
+connection con1;
+select * from t1;
+x
+0
+connection default;
+rollback;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 4
+disconnect con1;
+connection default;
+drop table t1;
+#
+# MDEV-25479 Auto-create: 2nd and further executions of PS or SP fail to create partition
+#
+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;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 02:00:00' AUTO
+PARTITIONS 4
+create procedure sp() update t set a= a + 1;
+set @@timestamp= @@timestamp + 3601;
+call sp();
+set @@timestamp= @@timestamp + 3601;
+call sp();
+drop procedure sp;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 02:00:00' AUTO
+PARTITIONS 6
+drop table t;
+#
+# MDEV-23639 Auto-create does not work under LOCK TABLES or inside triggers
+#
+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');
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 3
+insert into t2 values (2);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 4
+set timestamp= unix_timestamp('2000-01-01 03:00:00');
+call sp;
+call sp;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 5
+set timestamp= unix_timestamp('2000-01-01 04:00:00');
+call sp2;
+call sp2;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 6
+set timestamp= unix_timestamp('2000-01-01 05:00:00');
+execute ps;
+execute ps;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 7
+set timestamp= unix_timestamp('2000-01-01 06:00:00');
+execute ps2;
+execute ps2;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 8
+set timestamp= unix_timestamp('2000-01-01 08:00:00');
+lock tables t1 write, t2 write;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 10
+set timestamp= unix_timestamp('2000-01-01 09:00:00');
+update t1 set x= x + 1;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 11
+set timestamp= unix_timestamp('2000-01-01 10:00:00');
+update t1 set x= x + 2;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 12
+update t2 set x= x + 1;
+set timestamp= unix_timestamp('2000-01-01 11:00:00');
+insert into t2 values (4);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 13
+update t3 set x= x + 1;
+ERROR HY000: Table 't3' was not locked with LOCK TABLES
+set timestamp= unix_timestamp('2000-01-01 12:00:00');
+call sp;
+call sp;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 14
+set timestamp= unix_timestamp('2000-01-01 13:00:00');
+call sp2;
+call sp2;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 15
+set timestamp= unix_timestamp('2000-01-01 14:00:00');
+execute ps;
+execute ps;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 16
+set timestamp= unix_timestamp('2000-01-01 15:00:00');
+execute ps2;
+execute ps2;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 17
+unlock tables;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 17
+drop tables t1, t2, t3;
+drop procedure sp;
+drop procedure sp2;
+drop prepare ps;
+drop prepare ps2;
+#
+# MDEV-27456 Assertion `!thd->is_error()' fails in vers_create_partitions upon DML with ER_UNKNOWN_PARTITION
+#
+create table t (a int) with system versioning
+partition by system_time interval 1 minute auto;
+set @@timestamp= @@timestamp + 61;
+select * from t;
+a
+delete from t partition (px);
+ERROR HY000: Unknown partition 'px' in table 't'
+lock tables t write;
+delete from t partition (px);
+ERROR HY000: Unknown partition 'px' in table 't'
+unlock tables;
+drop table t;
+set timestamp= default;
+#
+# MDEV-28978 Assertion failure in THD::binlog_query or unexpected
+# ER_ERROR_ON_WRITE with auto-partitioning
+#
+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;
+drop table t;
+#
+# MDEV-31244 Assertion "not SELECT" in vers_set_hist_part()
+#
+create table t (a int) with system versioning partition by system_time;
+create function f() returns int
+begin
+update t set a = 1;
+return 1;
+end $
+create procedure p() select f();
+call p();
+f()
+1
+call p();
+f()
+1
+drop procedure p;
+drop function f;
+drop table t;
+#
+# MDEV-29873 MSAN uninitialized value errors in bcmp /
+# prep_alter_part_table upon re-partitioning by system time
+#
+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;
+drop table t;
+#
+# MDEV-16546 System versioning setting to allow history modification
+#
+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';
+table_name partition_name partition_ordinal_position partition_method partition_description table_rows
+t1 p0 1 SYSTEM_TIME 2021-10-01 00:00:00 1
+t1 p1 2 SYSTEM_TIME 2021-10-02 00:00:00 2
+t1 pn 3 SYSTEM_TIME CURRENT 1
+drop table t1;
+set system_versioning_insert_history=0;
+#
+# MDEV-29727 ALTER and CREATE with default partitioning
+# differently react to SQL_MODE => unusable SHOW CREATE
+#
+create table t (a int) with system versioning;
+alter table t partition by system_time partitions 3;
+ERROR HY000: Maybe missing parameters: no rotation condition for multiple HISTORY partitions.
+drop table t;
+create table t (a int) with system versioning partition by system_time partitions 3;
+ERROR HY000: Maybe missing parameters: no rotation condition for multiple HISTORY partitions.
+#
+# End of 10.5 tests
+#
+set global innodb_stats_persistent= @save_persistent;
diff --git a/mysql-test/suite/versioning/r/replace.result b/mysql-test/suite/versioning/r/replace.result
new file mode 100644
index 00000000..57a992cc
--- /dev/null
+++ b/mysql-test/suite/versioning/r/replace.result
@@ -0,0 +1,63 @@
+create or replace table t(
+id int,
+KEY_TYPE(id),
+x int,
+row_start SYS_DATATYPE as row start invisible,
+row_end SYS_DATATYPE 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;
+id x current
+1 2 0
+1 3 1
+drop table t;
+create table t (
+id int unique,
+x int,
+row_start SYS_DATATYPE as row start invisible,
+row_end SYS_DATATYPE 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;
+id x current
+1 2 0
+1 3 1
+drop table t;
+# 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;
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT,
+f INT,
+row_start SYS_DATATYPE AS ROW START INVISIBLE,
+row_end SYS_DATATYPE 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;
+# 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;
+replace into t1 values (1),(2);
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+drop table t1;
diff --git a/mysql-test/suite/versioning/r/rpl.result b/mysql-test/suite/versioning/r/rpl.result
new file mode 100644
index 00000000..62dd9798
--- /dev/null
+++ b/mysql-test/suite/versioning/r/rpl.result
@@ -0,0 +1,531 @@
+include/master-slave.inc
+[connection master]
+connection slave;
+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;
+x
+1
+delete from t1;
+select * from t1 order by x;
+x
+select * from t1 for system_time all order by row_end, x;
+x
+1
+connection slave;
+select * from t1 order by x;
+x
+select * from t1 for system_time all order by row_end, x;
+x
+1
+connection master;
+insert into t1 values (2);
+connection slave;
+select * from t1 order by x;
+x
+2
+connection master;
+update t1 set x = 3;
+connection slave;
+select * from t1 order by x;
+x
+3
+select * from t1 for system_time all order by row_end, x;
+x
+1
+2
+3
+# check unversioned -> versioned replication
+connection master;
+create or replace table t1 (x int primary key);
+connection slave;
+alter table t1 with system versioning;
+connection master;
+insert into t1 values (1);
+connection slave;
+select * from t1 order by x;
+x
+1
+select * from t1 for system_time all order by row_end, x;
+x
+1
+connection master;
+update t1 set x= 2 where x = 1;
+connection slave;
+select * from t1 order by x;
+x
+2
+select * from t1 for system_time all order by row_end, x;
+x
+1
+2
+connection master;
+delete from t1;
+connection slave;
+select * from t1 order by x;
+x
+select * from t1 for system_time all order by row_end, x;
+x
+1
+2
+# same thing (UPDATE, DELETE), but without PK
+connection master;
+create or replace table t1 (x int);
+connection slave;
+alter table t1 with system versioning;
+connection master;
+insert into t1 values (1);
+update t1 set x= 2 where x = 1;
+connection slave;
+select * from t1 order by x;
+x
+2
+select * from t1 for system_time all order by row_end, x;
+x
+1
+2
+connection master;
+delete from t1;
+connection slave;
+select * from t1 order by x;
+x
+select * from t1 for system_time all order by row_end, x;
+x
+1
+2
+# 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;
+connection slave;
+select * from t1 order by x;
+x
+11
+select * from t2 order by x;
+x
+22
+select * from t1 for system_time all order by row_end, x;
+x
+1
+11
+select * from t2 for system_time all order by row_end, x;
+x
+2
+22
+# MDEV-14767 system_versioning_alter_history breaks ALTER replication
+## 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;
+connection slave;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+## 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;
+alter table t1 drop column b;
+ERROR HY000: Not allowed for system-versioned `test`.`t1`. Change @@system_versioning_alter_history to proceed with ALTER.
+connection slave;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+## Case 3: table is not versioned on the master, ALTER will work on the slave
+connection master;
+create or replace table t1 (a int);
+connection slave;
+create or replace table t1 (a int) with system versioning;
+connection master;
+alter table t1 add column b int;
+connection slave;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+connection master;
+drop table t1, t2;
+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;
+connection slave;
+connection master;
+drop table t1;
+# 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;
+connection slave;
+include/diff_tables.inc [master:test.t1,slave:test.t1]
+connection master;
+drop table t1;
+connection slave;
+# 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;
+connection slave;
+include/diff_tables.inc [master:test.t1,slave:test.t1]
+connection master;
+drop table t1;
+#
+# MDEV-31313 SYSTEM VERSIONING and FOREIGN KEY CASCADE create orphan rows on replica
+#
+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;
+check_row(row_start, row_end)
+HISTORICAL ROW
+select check_row(row_start, row_end) from child for system_time all;
+check_row(row_start, row_end)
+HISTORICAL ROW
+select * from child;
+id ch_name andreid
+select * from parent;
+id processdate
+connection slave;
+select check_row_slave(row_start, row_end) from parent for system_time all;
+check_row_slave(row_start, row_end)
+HISTORICAL ROW
+select check_row_slave(row_start, row_end) from child for system_time all;
+check_row_slave(row_start, row_end)
+HISTORICAL ROW
+select * from child;
+id ch_name andreid
+select * from parent;
+id processdate
+connection master;
+set timestamp= default;
+drop table child;
+drop table parent;
+connection slave;
+connection master;
+#
+# MDEV-17554 Auto-create new partition for system versioned tables
+# with history partitioned by INTERVAL/LIMIT
+#
+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;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 3
+connection slave;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL
+) ENGINE=ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' AUTO
+PARTITIONS 3
+connection master;
+drop table t1;
+set timestamp= default;
+#
+# MDEV-25477 Auto-create breaks replication when triggering event was not replicated
+#
+set timestamp= unix_timestamp('2001-01-01 01:00:00');
+# 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;
+rollback;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2001-01-01 01:00:00' AUTO
+PARTITIONS 3
+connection slave;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2001-01-01 01:00:00' AUTO
+PARTITIONS 3
+connection master;
+alter table t drop partition p0;
+connection slave;
+# 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;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) NOT NULL,
+ PRIMARY KEY (`a`)
+) ENGINE=ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2001-01-01 02:00:00' AUTO
+PARTITIONS 3
+connection slave;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) NOT NULL,
+ PRIMARY KEY (`a`)
+) ENGINE=ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2001-01-01 02:00:00' AUTO
+PARTITIONS 3
+connection master;
+alter table t drop partition p0;
+connection slave;
+# 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;
+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;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) NOT NULL,
+ PRIMARY KEY (`a`)
+) ENGINE=ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2001-01-01 03:00:00' AUTO
+PARTITIONS 3
+connection slave;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) NOT NULL,
+ PRIMARY KEY (`a`)
+) ENGINE=ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2001-01-01 03:00:00' AUTO
+PARTITIONS 3
+connection master;
+alter table t drop partition p0;
+connection slave;
+# 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;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2001-01-01 04:00:00' AUTO
+PARTITIONS 3
+connection slave;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2001-01-01 04:00:00' AUTO
+PARTITIONS 3
+connection master;
+alter table t drop partition p0;
+connection slave;
+# 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;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2001-01-01 05:00:00' AUTO
+PARTITIONS 3
+connection slave;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2001-01-01 05:00:00' AUTO
+PARTITIONS 3
+connection master;
+alter table t drop partition p0;
+connection slave;
+# 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;
+update t left join t2 on a > b set a= 4;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2001-01-01 06:00:00' AUTO
+PARTITIONS 3
+connection slave;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2001-01-01 06:00:00' AUTO
+PARTITIONS 3
+connection master;
+alter table t drop partition p0;
+connection slave;
+# 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;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2001-01-01 07:00:00' AUTO
+PARTITIONS 3
+connection slave;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2001-01-01 07:00:00' AUTO
+PARTITIONS 3
+connection master;
+alter table t drop partition p0;
+connection slave;
+connection master;
+drop tables t, t2;
+set timestamp= default;
+#
+# MDEV-16546 System versioning setting to allow history modification
+#
+create table t1(x int) with system versioning;
+insert into t1(x) values (1);
+insert into t1(x, row_start, row_end) values (2, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
+ERROR 42S22: Unknown column 'row_start' in 'field list'
+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;
+connection slave;
+set @@session.time_zone='+00:00';
+select x, check_row_ts(row_start, row_end) from t1 for system_time all order by x;
+x check_row_ts(row_start, row_end)
+1 HISTORICAL ROW
+2 CURRENT ROW
+3 HISTORICAL ROW
+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;
+row_start = '1980-01-01 00:00:00' row_end = '1980-01-01 00:00:01'
+1 1
+## 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;
+connection slave;
+select x, check_row_ts(row_start, row_end) from t2 for system_time all order by x;
+x check_row_ts(row_start, row_end)
+1 HISTORICAL ROW
+2 CURRENT ROW
+3 HISTORICAL ROW
+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;
+row_start = '1980-01-01 00:00:00' row_end = '1980-01-01 00:00:01'
+1 1
+# LOAD DATA
+connection master;
+select x, row_start, row_end into outfile 'DATAFILE' from t1 for system_time all;
+create or replace table t3 like t1;
+set @@system_versioning_insert_history= 1;
+load data infile 'DATAFILE' into table t3 (x, row_start, row_end);
+connection slave;
+select x, check_row_ts(row_start, row_end) from t3 for system_time all order by x;
+x check_row_ts(row_start, row_end)
+1 HISTORICAL ROW
+2 CURRENT ROW
+3 HISTORICAL ROW
+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;
+row_start = '1980-01-01 00:00:00' row_end = '1980-01-01 00:00:01'
+1 1
+# 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');
+Warnings:
+Warning 1906 The value specified for generated column 'rs' in table 't1' has been ignored
+Warning 1906 The value specified for generated column 're' in table 't1' has been ignored
+select a,check_row_ts(rs,re) from t1 for system_time all;
+a check_row_ts(rs,re)
+1 CURRENT ROW
+connection slave;
+select a,check_row_ts(rs,re) from t1 for system_time all;
+a check_row_ts(rs,re)
+1 CURRENT ROW
+set sql_mode=default;
+connection master;
+drop tables t1, t2, t3;
+include/rpl_end.inc
diff --git a/mysql-test/suite/versioning/r/rpl_mix.result b/mysql-test/suite/versioning/r/rpl_mix.result
new file mode 100644
index 00000000..856678ae
--- /dev/null
+++ b/mysql-test/suite/versioning/r/rpl_mix.result
@@ -0,0 +1,66 @@
+include/master-slave.inc
+[connection master]
+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;
+SET BINLOG_FORMAT= ROW;
+DELETE HISTORY FROM t1;
+connection slave;
+connection master;
+drop table t1;
+#
+# MDEV-25347 DML events for auto-partitioned tables are written into binary log twice
+#
+flush binary logs;
+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;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME LIMIT 1 AUTO
+PARTITIONS 3
+select * from t1;
+a
+4
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000002 # Binlog_checkpoint # # master-bin.000002
+master-bin.000002 # Gtid # # GTID #-#-#
+master-bin.000002 # Query # # use `test`; create table t1 (a int) with system versioning
+partition by system_time limit 1 auto
+master-bin.000002 # Gtid # # BEGIN GTID #-#-#
+master-bin.000002 # Annotate_rows # # insert into t1 values (1)
+master-bin.000002 # Table_map # # table_id: # (test.t1)
+master-bin.000002 # Write_rows_v1 # # table_id: # flags: STMT_END_F
+master-bin.000002 # Query # # COMMIT
+master-bin.000002 # Gtid # # BEGIN GTID #-#-#
+master-bin.000002 # Annotate_rows # # update t1 set a= a + 1
+master-bin.000002 # Table_map # # table_id: # (test.t1)
+master-bin.000002 # Update_rows_v1 # # table_id: #
+master-bin.000002 # Write_rows_v1 # # table_id: # flags: STMT_END_F
+master-bin.000002 # Query # # COMMIT
+master-bin.000002 # Gtid # # BEGIN GTID #-#-#
+master-bin.000002 # Annotate_rows # # update t1 set a= a + 2
+master-bin.000002 # Table_map # # table_id: # (test.t1)
+master-bin.000002 # Update_rows_v1 # # table_id: #
+master-bin.000002 # Write_rows_v1 # # table_id: # flags: STMT_END_F
+master-bin.000002 # Query # # COMMIT
+connection slave;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME LIMIT 1 AUTO
+PARTITIONS 3
+select * from t1;
+a
+4
+connection master;
+drop table t1;
+include/rpl_end.inc
diff --git a/mysql-test/suite/versioning/r/rpl_row.result b/mysql-test/suite/versioning/r/rpl_row.result
new file mode 100644
index 00000000..c161f68d
--- /dev/null
+++ b/mysql-test/suite/versioning/r/rpl_row.result
@@ -0,0 +1,107 @@
+include/master-slave.inc
+[connection master]
+# 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;
+connection slave;
+connection master;
+drop table t1;
+set binlog_row_image= @old_row_image;
+#
+# MDEV-28254 Wrong position for row_start, row_end after adding column
+# to implicit versioned table
+#
+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;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+connection slave;
+drop table t1;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `x` int(11) DEFAULT NULL,
+ `y` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+connection master;
+set timestamp= 12345;
+insert t1 values (1, 1);
+select *, unix_timestamp(row_start) as row_start, unix_timestamp(row_end) as row_end from t1;
+x y row_start row_end
+1 1 12345.000000 2147483647.999999
+set timestamp= default;
+### INSERT INTO `test`.`t1`
+### SET
+### @1=1
+### @2=1
+### @3=12345.000000
+### @4=2147483647.999999
+connection slave;
+select * from t1;
+x y
+1 1
+connection master;
+drop table t1;
+#
+# MDEV-25347 DML events for auto-partitioned tables are written into binary log twice
+#
+flush binary logs;
+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;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME LIMIT 1 AUTO
+PARTITIONS 3
+select * from t1;
+a
+4
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000002 # Binlog_checkpoint # # master-bin.000002
+master-bin.000002 # Gtid # # GTID #-#-#
+master-bin.000002 # Query # # use `test`; create table t1 (a int) with system versioning
+partition by system_time limit 1 auto
+master-bin.000002 # Gtid # # BEGIN GTID #-#-#
+master-bin.000002 # Annotate_rows # # insert into t1 values (1)
+master-bin.000002 # Table_map # # table_id: # (test.t1)
+master-bin.000002 # Write_rows_v1 # # table_id: # flags: STMT_END_F
+master-bin.000002 # Query # # COMMIT
+master-bin.000002 # Gtid # # BEGIN GTID #-#-#
+master-bin.000002 # Annotate_rows # # update t1 set a= a + 1
+master-bin.000002 # Table_map # # table_id: # (test.t1)
+master-bin.000002 # Update_rows_v1 # # table_id: #
+master-bin.000002 # Write_rows_v1 # # table_id: # flags: STMT_END_F
+master-bin.000002 # Query # # COMMIT
+master-bin.000002 # Gtid # # BEGIN GTID #-#-#
+master-bin.000002 # Annotate_rows # # update t1 set a= a + 2
+master-bin.000002 # Table_map # # table_id: # (test.t1)
+master-bin.000002 # Update_rows_v1 # # table_id: #
+master-bin.000002 # Write_rows_v1 # # table_id: # flags: STMT_END_F
+master-bin.000002 # Query # # COMMIT
+connection slave;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME LIMIT 1 AUTO
+PARTITIONS 3
+select * from t1;
+a
+4
+connection master;
+drop table t1;
+include/rpl_end.inc
diff --git a/mysql-test/suite/versioning/r/rpl_stmt.result b/mysql-test/suite/versioning/r/rpl_stmt.result
new file mode 100644
index 00000000..97ce2265
--- /dev/null
+++ b/mysql-test/suite/versioning/r/rpl_stmt.result
@@ -0,0 +1,50 @@
+include/master-slave.inc
+[connection master]
+#
+# MDEV-25347 DML events for auto-partitioned tables are written into binary log twice
+#
+flush binary logs;
+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;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME LIMIT 1 AUTO
+PARTITIONS 3
+select * from t1;
+a
+4
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000002 # Binlog_checkpoint # # master-bin.000002
+master-bin.000002 # Gtid # # GTID #-#-#
+master-bin.000002 # Query # # use `test`; create table t1 (a int) with system versioning
+partition by system_time limit 1 auto
+master-bin.000002 # Gtid # # BEGIN GTID #-#-#
+master-bin.000002 # Query # # use `test`; insert into t1 values (1)
+master-bin.000002 # Query # # COMMIT
+master-bin.000002 # Gtid # # BEGIN GTID #-#-#
+master-bin.000002 # Query # # use `test`; update t1 set a= a + 1
+master-bin.000002 # Query # # COMMIT
+master-bin.000002 # Gtid # # BEGIN GTID #-#-#
+master-bin.000002 # Query # # use `test`; update t1 set a= a + 2
+master-bin.000002 # Query # # COMMIT
+connection slave;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME LIMIT 1 AUTO
+PARTITIONS 3
+select * from t1;
+a
+4
+connection master;
+drop table t1;
+include/rpl_end.inc
diff --git a/mysql-test/suite/versioning/r/select,trx_id.rdiff b/mysql-test/suite/versioning/r/select,trx_id.rdiff
new file mode 100644
index 00000000..8906007a
--- /dev/null
+++ b/mysql-test/suite/versioning/r/select,trx_id.rdiff
@@ -0,0 +1,11 @@
+--- select.result 2018-06-29 18:09:17.962447067 +0200
++++ select.reject 2018-06-29 18:10:04.618808616 +0200
+@@ -17,6 +17,8 @@
+ (8, 108),
+ (9, 109);
+ set @t0= now(6);
++Warnings:
++Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+ delete from t1 where x = 3;
+ delete from t1 where x > 7;
+ insert into t1(x, y) values(3, 33);
diff --git a/mysql-test/suite/versioning/r/select.result b/mysql-test/suite/versioning/r/select.result
new file mode 100644
index 00000000..90c99d1b
--- /dev/null
+++ b/mysql-test/suite/versioning/r/select.result
@@ -0,0 +1,710 @@
+SET @saved_stats_persistent = @@GLOBAL.innodb_stats_persistent;
+SET GLOBAL innodb_stats_persistent = OFF;
+create or replace table t1 (
+x int unsigned,
+y int unsigned,
+sys_trx_start SYS_DATATYPE as row start invisible,
+sys_trx_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_trx_start, sys_trx_end)
+) with system versioning;
+insert into t1 (x, y) values
+(0, 100),
+(1, 101),
+(2, 102),
+(3, 103),
+(4, 104),
+(5, 105),
+(6, 106),
+(7, 107),
+(8, 108),
+(9, 109);
+set @t0= now(6);
+delete from t1 where x = 3;
+delete from t1 where x > 7;
+insert into t1(x, y) values(3, 33);
+select sys_trx_start from t1 where x = 3 and y = 33 into @t1;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+select x, y from t1;
+x y
+0 100
+1 101
+2 102
+4 104
+5 105
+6 106
+7 107
+3 33
+select x as ASOF_x, y from t1 for system_time as of timestamp @t0;
+ASOF_x y
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
+8 108
+9 109
+select x as FROMTO_x, y from t1 for system_time from timestamp '1970-01-01 00:00:00' to timestamp @t1;
+FROMTO_x y
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
+8 108
+9 109
+select x as BETWAND_x, y from t1 for system_time between timestamp '1970-01-01 00:00:00' and timestamp @t1;
+BETWAND_x y
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
+8 108
+9 109
+3 33
+select x as ALL_x, y from t1 for system_time all;
+ALL_x y
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
+8 108
+9 109
+3 33
+ASOF2_x y
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
+8 108
+9 109
+FROMTO2_x y
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
+8 108
+9 109
+BETWAND2_x y
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
+8 108
+9 109
+3 33
+create or replace table t1 (
+x int unsigned,
+y int unsigned
+) with system versioning;
+create or replace table t2 (
+x int unsigned,
+y int unsigned
+) with system versioning;
+insert into t1 values (1, 1), (1, 2), (1, 3), (4, 4), (5, 5);
+insert into t2 values (1, 2), (2, 1), (3, 1);
+set @t0= now(6);
+select t1.x as IJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 inner join t2 on t1.x = t2.x;
+IJ1_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+select t1.x as LJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 left join t2 on t1.x = t2.x;
+LJ1_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+4 4 NULL NULL
+5 5 NULL NULL
+select t1.x as RJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 right join t2 on t1.x = t2.x;
+RJ1_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+NULL NULL 2 1
+NULL NULL 3 1
+delete from t1;
+delete from t2;
+explain extended select * from (select t1.x as IJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 inner join t2 on t1.x = t2.x)
+for system_time as of timestamp @t0 as t;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`x` AS `IJ2_x1`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t1` FOR SYSTEM_TIME AS OF TIMESTAMP @`t0` join `test`.`t2` FOR SYSTEM_TIME AS OF TIMESTAMP @`t0` where `test`.`t1`.`x` = `test`.`t2`.`x` and `test`.`t2`.`row_end` > @`t0` and `test`.`t2`.`row_start` <= @`t0` and `test`.`t1`.`row_end` > @`t0` and `test`.`t1`.`row_start` <= @`t0`
+explain extended select * from (select t1.x as LJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 left join t2 on t1.x = t2.x)
+for system_time as of timestamp @t0 as t;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`x` AS `LJ2_x1`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t1` FOR SYSTEM_TIME AS OF TIMESTAMP @`t0` left join `test`.`t2` FOR SYSTEM_TIME AS OF TIMESTAMP @`t0` on(`test`.`t2`.`x` = `test`.`t1`.`x` and `test`.`t2`.`row_end` > @`t0` and `test`.`t2`.`row_start` <= @`t0`) where `test`.`t1`.`row_end` > @`t0` and `test`.`t1`.`row_start` <= @`t0`
+explain extended select * from (select t1.x as RJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 right join t2 on t1.x = t2.x)
+for system_time as of timestamp @t0 as t;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`x` AS `RJ2_x1`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t2` FOR SYSTEM_TIME AS OF TIMESTAMP @`t0` left join `test`.`t1` FOR SYSTEM_TIME AS OF TIMESTAMP @`t0` on(`test`.`t1`.`x` = `test`.`t2`.`x` and `test`.`t1`.`row_end` > @`t0` and `test`.`t1`.`row_start` <= @`t0`) where `test`.`t2`.`row_end` > @`t0` and `test`.`t2`.`row_start` <= @`t0`
+select * from (select t1.x as IJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 inner join t2 on t1.x = t2.x)
+for system_time as of timestamp @t0 as t;
+IJ2_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+select * from (select t1.x as LJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 left join t2 on t1.x = t2.x)
+for system_time as of timestamp @t0 as t;
+LJ2_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+4 4 NULL NULL
+5 5 NULL NULL
+select * from (select t1.x as RJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 right join t2 on t1.x = t2.x)
+for system_time as of timestamp @t0 as t;
+RJ2_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+NULL NULL 2 1
+NULL NULL 3 1
+drop table t1;
+drop table t2;
+create 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;
+ASOF_x
+2
+select x as ASOF_x from t1 for system_time as of @end2;
+ASOF_x
+select x as FROMTO_x from t1 for system_time from @start1 to @end3;
+FROMTO_x
+1
+2
+3
+select x as FROMTO_x from t1 for system_time from @end1 to @start2;
+FROMTO_x
+select x as BETWAND_x from t1 for system_time between @start1 and @end3;
+BETWAND_x
+1
+2
+3
+select x as BETWAND_x from t1 for system_time between @end1 and @start2;
+BETWAND_x
+2
+drop table t1;
+create table t1(
+A int
+) with system versioning;
+insert into t1 values(1);
+select * from t1;
+A
+1
+create or replace table t1 (x int);
+insert into t1 values (1);
+select * from t1 for system_time all;
+ERROR HY000: Table `t1` is not system-versioned
+create or replace table t1 (x int) with system versioning;
+insert into t1 values (1);
+select * from t1 for system_time all for update;
+ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
+create or replace table t1 (a int not null auto_increment primary key) with system versioning;
+select * from (t1 as t2 left join t1 as t3 using (a)) natural left join t1;
+a
+create or replace table t1 (a int) with system versioning;
+create or replace table t2 (a int) with system versioning;
+insert into t1 values(1);
+insert into t2 values(1);
+create view v1 as select * from t2 inner join t1 using (a);
+select * from v1;
+a
+1
+drop view v1;
+create or replace table t1 (a int) with system versioning;
+insert into t1 values (1);
+create view vt1 as select a from t1;
+select * from t1 natural join vt1;
+a
+1
+drop view vt1;
+create or replace table t1(x int) with system versioning;
+select * from (t1 as r left join t1 as u using (x)), t1;
+x x
+create or replace table t1 (a int) with system versioning;
+insert into t1 values (1);
+create trigger read_end after update on t1
+for each row set @end = old.row_end;
+update t1 set a=2;
+select @end;
+@end
+MAX_RESULT
+create or replace table t1 (a int) with system versioning;
+create or replace table t2 (b int) with system versioning;
+insert into t1 values (1);
+insert into t2 values (2);
+select * from (select * from t1 cross join t2) as tmp;
+a b
+1 2
+select * from (select * from (select * from t1 cross join t2) as tmp1) as tmp2;
+a b
+1 2
+select * from (select * from t1 cross join t2 for system_time as of timestamp ('1970-01-01 00:00:00')) as tmp;
+a b
+create or replace table t1(a1 int) with system versioning;
+create or replace table t2(a2 int) with system versioning;
+insert into t1 values(1),(2);
+insert into t2 values(1),(2);
+select * from t1 for system_time all natural left join t2 for system_time all;
+a1 a2
+1 1
+2 1
+1 2
+2 2
+create or replace table t1(a1 int) with system versioning;
+create or replace table t2(a2 int) with system versioning;
+insert into t1 values(1),(2);
+insert into t2 values(1),(2);
+create or replace view v1 as select a1 from t1;
+select * from v1 natural join t2;
+a1 a2
+1 1
+2 1
+1 2
+2 2
+select * from v1 natural left join t2;
+a1 a2
+1 1
+2 1
+1 2
+2 2
+select * from v1 natural right join t2;
+a2 a1
+1 1
+2 1
+1 2
+2 2
+create or replace table t1 (a int) with system versioning;
+insert into t1 values (1);
+insert into t1 values (2);
+insert into t1 values (3);
+explain extended
+select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `a` from `test`.`t1` left join (`test`.`t1` `t2` left join `test`.`t1` `t3` on(`test`.`t3`.`a` = `test`.`t2`.`a` and `test`.`t3`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999')) on(`test`.`t2`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999' and `test`.`t1`.`a` > 1) where `test`.`t1`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999'
+select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
+a a
+2 1
+3 1
+2 2
+3 2
+2 3
+3 3
+1 NULL
+create or replace table t1 (x int) with system versioning;
+create or replace table t2 (y int) with system versioning;
+insert into t1 values (1), (2), (3);
+delete from t1 where x = 3;
+insert into t2 values (1);
+select * from t1, t2 for system_time all;
+x y
+1 1
+2 1
+select * from (select * from t1 for system_time all, t2 for system_time all)
+for system_time all as t;
+ERROR HY000: Table `t` is not system-versioned
+# TRANSACTION/TIMESTAMP specifier in SYSTEM_TIME [MDEV-14645, Issue #396]
+create or replace table t1 (x int) with system versioning engine myisam;
+select * from t1 for system_time as of transaction 1;
+ERROR HY000: Transaction-precise system versioning for `t1` is not supported
+# 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;
+call sp;
+ERROR HY000: Transaction-precise system versioning for `t1` is not supported
+call sp;
+ERROR HY000: Transaction-precise system versioning for `t1` is not supported
+create or replace table t1 (a int);
+create or replace procedure sp()
+select * from t1 for system_time all;
+call sp;
+ERROR HY000: Table `t1` is not system-versioned
+call sp;
+ERROR HY000: Table `t1` is not system-versioned
+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;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+## ensure @trx_start is much lower than unix timestamp
+select @trx_start < unix_timestamp(@ts) - 100 as trx_start_good;
+trx_start_good
+1
+## TIMESTAMP specifier
+select x from t1 for system_time as of timestamp @ts;
+x
+1
+set @ts= timestamp'1-1-1 0:0:0';
+select x from t1 for system_time as of timestamp @ts;
+x
+## TRANSACTION specifier
+select x from t1 for system_time as of transaction @trx_start;
+x
+1
+## no specifier (defaults to timestamp)
+select x from t1 for system_time as of @ts;
+x
+### Issue #365, bug 4 (related to #226, optimized fields)
+create or replace table t1 (i int, b int) with system versioning;
+insert into t1 values (0, 0), (0, 0);
+select min(i) over (partition by b) as f
+from (select i + 0 as i, b from t1) as tt
+order by i;
+f
+0
+0
+### Issue #365, bug 5 (dangling AND)
+create or replace table t1 (a int);
+create or replace table t2 (b int) with system versioning;
+select * from t1
+where exists (select 1 from t2 where t2.b = t1.a and t2.b = t1.a);
+a
+### Issue #365, bug 9 (not a derived subquery)
+create or replace table t1 (x int) with system versioning;
+select t1.x in (select x from t1) a from t1, (select x from t1) b;
+a
+### Issue #365, bug 10 (WHERE cond freed prematurely for PS)
+create or replace table t1 (x int) with system versioning;
+insert into t1 values (1);
+create or replace view v1 as select x from t1 where x = 1;
+prepare stmt from "
+select x from t1 where x in (select x from v1);";
+execute stmt;
+x
+1
+execute stmt;
+x
+1
+### Issue #365, bug 11 (WHERE cond not top level item)
+create or replace table t1 (a int, b int, key idx(a)) with system versioning;
+insert into t1 values (1, 1), (2, 2);
+select * from t1 where (a, 2) in ((1, 1), (2, 2)) and b = 1;
+a b
+### Issue #398, NOW is now non-magic
+create or replace table t1 (x int) with system versioning;
+select * from t1 for system_time as of current_timestamp;
+x
+select * from t1 for system_time as of now;
+ERROR 42S22: Unknown column 'now' in 'FOR SYSTEM_TIME'
+### Issue #405, NATURAL JOIN failure
+create or replace table t1 (a int) with system versioning;
+create or replace table t2 (b int);
+create or replace view v1 as select a, row_start, row_end from t1 where a > round(rand()*1000);
+select * from v1 natural join t2;
+a row_start row_end b
+#
+# Issue #406, MDEV-14633 Assertion on TRT read
+#
+create or replace table t1 (pk int primary key, i int, t time, key (i)) with system versioning;
+insert into t1 values (1, 10, '15:01:53'), (2, 20, '00:00:00');
+delete from t1;
+select * from t1 where t = '00:00:00' and i > 0 and row_end <> '2012-12-12 00:00:00';
+pk i t
+#
+# MDEV-14816 Assertion `join->best_read < double(1.797...e+308L)' failed in bool greedy_search
+#
+create or replace table t1 (f1 int) with system versioning;
+create or replace table t2 (f2 int) with system versioning;
+create or replace table t3 (f3 int);
+create or replace table t4 (f4 int);
+insert into t1 values (1), (2), (3), (4);
+insert into t2 values (1), (2), (3);
+insert into t3 values (1), (2);
+insert into t4 values (1);
+select * from
+t1 as t1a
+left join t2 as t2a left join (t3 as t3a inner join t1) on t2a.f2 = t3a.f3 on t1a.f1 = t2a.f2
+left join (t2 join t3 inner join t4) on t2a.f2 = t1a.f1;
+f1 f2 f3 f1 f2 f3 f4
+1 1 1 1 1 1 1
+2 2 2 1 1 1 1
+1 1 1 2 1 1 1
+2 2 2 2 1 1 1
+1 1 1 3 1 1 1
+2 2 2 3 1 1 1
+1 1 1 4 1 1 1
+2 2 2 4 1 1 1
+1 1 1 1 1 2 1
+2 2 2 1 1 2 1
+1 1 1 2 1 2 1
+2 2 2 2 1 2 1
+1 1 1 3 1 2 1
+2 2 2 3 1 2 1
+1 1 1 4 1 2 1
+2 2 2 4 1 2 1
+1 1 1 1 2 1 1
+2 2 2 1 2 1 1
+1 1 1 2 2 1 1
+2 2 2 2 2 1 1
+1 1 1 3 2 1 1
+2 2 2 3 2 1 1
+1 1 1 4 2 1 1
+2 2 2 4 2 1 1
+1 1 1 1 2 2 1
+2 2 2 1 2 2 1
+1 1 1 2 2 2 1
+2 2 2 2 2 2 1
+1 1 1 3 2 2 1
+2 2 2 3 2 2 1
+1 1 1 4 2 2 1
+2 2 2 4 2 2 1
+1 1 1 1 3 1 1
+2 2 2 1 3 1 1
+1 1 1 2 3 1 1
+2 2 2 2 3 1 1
+1 1 1 3 3 1 1
+2 2 2 3 3 1 1
+1 1 1 4 3 1 1
+2 2 2 4 3 1 1
+1 1 1 1 3 2 1
+2 2 2 1 3 2 1
+1 1 1 2 3 2 1
+2 2 2 2 3 2 1
+1 1 1 3 3 2 1
+2 2 2 3 3 2 1
+1 1 1 4 3 2 1
+2 2 2 4 3 2 1
+3 3 NULL NULL 1 1 1
+3 3 NULL NULL 1 2 1
+3 3 NULL NULL 2 1 1
+3 3 NULL NULL 2 2 1
+3 3 NULL NULL 3 1 1
+3 3 NULL NULL 3 2 1
+4 NULL NULL NULL NULL NULL NULL
+#
+# MDEV-15004 parser greedily parses AS OF TIMESTAMP
+#
+select timestamp'2016-02-30 08:07:06';
+ERROR HY000: Incorrect DATETIME value: '2016-02-30 08:07:06'
+select * from t1 for system_time as of timestamp'2016-02-30 08:07:06';
+ERROR HY000: Incorrect DATETIME value: '2016-02-30 08:07:06'
+select timestamp('2003-12-31 12:00:00','12:00:00');
+timestamp('2003-12-31 12:00:00','12:00:00')
+2004-01-01 00:00:00
+select * from t1 for system_time as of timestamp('2003-12-31 12:00:00','12:00:00');
+f1
+#
+# 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]
+#
+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;
+f1
+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;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`f1` AS `f1` from `test`.`t1` join `test`.`t2` left join (`test`.`t3` left join `test`.`t4` on(`test`.`t4`.`f4` = `test`.`t2`.`f2` and `test`.`t4`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999')) on(`test`.`t3`.`f3` = `test`.`t2`.`f2`) where `test`.`t1`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999'
+drop view v1;
+drop table t1, t2, t3, t4;
+#
+# MDEV-15980 FOR SYSTEM_TIME BETWEEN and FROM .. TO work with negative intervals
+#
+create or replace table t1 (
+a int,
+row_start SYS_DATATYPE as row start invisible,
+row_end SYS_DATATYPE 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;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+select row_end from t1 for system_time all into @t2;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+select * from t1 for system_time between @t1 and @t2;
+a
+1
+select * from t1 for system_time between @t2 and @t1;
+a
+select * from t1 for system_time from @t1 to @t2;
+a
+1
+select * from t1 for system_time from @t2 to @t1;
+a
+drop table t1;
+#
+# MDEV-15991 Server crashes in setup_on_expr upon calling SP or function executing DML on versioned tables
+#
+create or replace table t1 (i int);
+insert into t1 values (1);
+create or replace procedure p(n int)
+begin
+select * from t1;
+end $
+call p(1);
+i
+1
+alter table t1 add system versioning;
+call p(2);
+i
+1
+call p(3);
+i
+1
+#
+# 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
+#
+create or replace table t1 (i int) with system versioning;
+create or replace procedure p() select * from t1;
+call p;
+i
+flush tables;
+call p;
+i
+call p;
+i
+drop procedure p;
+drop table t1;
+#
+# MDEV-21234 Server crashes in in setup_on_expr upon 3rd execution of SP
+#
+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;
+call pr;
+ERROR 22007: Incorrect date value: 'foo' for column `test`.`t2`.`b` at row 1
+prepare stmt from 'insert into t2 select * from t1';
+execute stmt;
+ERROR 22007: Incorrect date value: 'foo' for column `test`.`t2`.`b` at row 1
+alter table t1 add system versioning;
+call pr;
+ERROR 22007: Incorrect date value: 'foo' for column `test`.`t2`.`b` at row 1
+call pr;
+ERROR 22007: Incorrect date value: 'foo' for column `test`.`t2`.`b` at row 1
+execute stmt;
+ERROR 22007: Incorrect date value: 'foo' for column `test`.`t2`.`b` at row 1
+execute stmt;
+ERROR 22007: Incorrect date value: 'foo' for column `test`.`t2`.`b` at row 1
+drop prepare stmt;
+drop procedure pr;
+drop table t1, t2;
+#
+# MDEV-23799 CREATE .. SELECT wrong result on join versioned table
+#
+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;
+gender title
+male NULL
+female NULL
+male NULL
+drop table tmp1;
+drop tables x, x_p;
+call verify_trt_dummy(34);
+No A B C D
+1 1 1 1 1
+2 1 1 1 1
+3 1 1 1 1
+4 1 1 1 1
+5 1 1 1 1
+6 1 1 1 1
+7 1 1 1 1
+8 1 1 1 1
+9 1 1 1 1
+10 1 1 1 1
+11 1 1 1 1
+12 1 1 1 1
+13 1 1 1 1
+14 1 1 1 1
+15 1 1 1 1
+16 1 1 1 1
+17 1 1 1 1
+18 1 1 1 1
+19 1 1 1 1
+20 1 1 1 1
+21 1 1 1 1
+22 1 1 1 1
+23 1 1 1 1
+24 1 1 1 1
+25 1 1 1 1
+26 1 1 1 1
+27 1 1 1 1
+28 1 1 1 1
+29 1 1 1 1
+30 1 1 1 1
+31 1 1 1 1
+32 1 1 1 1
+33 1 1 1 1
+34 1 1 1 1
+SET GLOBAL innodb_stats_persistent = @saved_stats_persistent;
diff --git a/mysql-test/suite/versioning/r/select2,trx_id.rdiff b/mysql-test/suite/versioning/r/select2,trx_id.rdiff
new file mode 100644
index 00000000..bdc20d1d
--- /dev/null
+++ b/mysql-test/suite/versioning/r/select2,trx_id.rdiff
@@ -0,0 +1,38 @@
+--- select2.result 2018-06-29 17:51:17.142172085 +0200
++++ select2,trx_id.reject 2018-06-29 18:03:49.034273090 +0200
+@@ -26,6 +26,8 @@
+ select sys_start from t1 where x = 3 and y = 33 into @t1;
+ Warnings:
+ Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
++set @x1= @t1;
++select trt_commit_ts(@x1) into @t1;
+ select x, y from t1;
+ x y
+ 0 100
+@@ -86,7 +88,7 @@
+ 8 108
+ 9 109
+ 3 33
+-select x as ASOF2_x, y from t1 for system_time as of @t0;
++select x as ASOF2_x, y from t1 for system_time as of transaction @x0;
+ ASOF2_x y
+ 0 100
+ 1 101
+@@ -98,7 +100,7 @@
+ 7 107
+ 8 108
+ 9 109
+-select x as FROMTO2_x, y from t1 for system_time from '1970-01-01 00:00' to @t1;
++select x as FROMTO2_x, y from t1 for system_time from transaction @x0 to transaction @x1;
+ FROMTO2_x y
+ 0 100
+ 1 101
+@@ -110,7 +112,7 @@
+ 7 107
+ 8 108
+ 9 109
+-select x as BETWAND2_x, y from t1 for system_time between '1970-01-01 00:00' and timestamp @t1;
++select x as BETWAND2_x, y from t1 for system_time between transaction @x0 and transaction @x1;
+ BETWAND2_x y
+ 0 100
+ 1 101
diff --git a/mysql-test/suite/versioning/r/select2.result b/mysql-test/suite/versioning/r/select2.result
new file mode 100644
index 00000000..353bdf8e
--- /dev/null
+++ b/mysql-test/suite/versioning/r/select2.result
@@ -0,0 +1,347 @@
+create table t1(
+x int unsigned,
+y int unsigned,
+sys_start SYS_TYPE as row start invisible,
+sys_end SYS_TYPE as row end invisible,
+period for system_time (sys_start, sys_end))
+with system versioning engine=ENGINE;
+insert into t1 (x, y) values
+(0, 100),
+(1, 101),
+(2, 102),
+(3, 103),
+(4, 104),
+(5, 105),
+(6, 106),
+(7, 107),
+(8, 108),
+(9, 109);
+set @t0= now(6);
+select sys_start from t1 limit 1 into @x0;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+delete from t1 where x = 3;
+delete from t1 where x > 7;
+insert into t1(x, y) values(3, 33);
+select sys_start from t1 where x = 3 and y = 33 into @t1;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+select x, y from t1;
+x y
+0 100
+1 101
+2 102
+4 104
+5 105
+6 106
+7 107
+3 33
+select x as ASOF_x, y from t1 for system_time as of timestamp @t0;
+ASOF_x y
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
+8 108
+9 109
+select x as FROMTO_x, y from t1 for system_time from '1970-01-01 00:00' to timestamp @t1;
+FROMTO_x y
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
+8 108
+9 109
+select x as BETWAND_x, y from t1 for system_time between '1970-01-01 00:00' and timestamp @t1;
+BETWAND_x y
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
+8 108
+9 109
+3 33
+select x as ALL_x, y from t1 for system_time all;
+ALL_x y
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
+8 108
+9 109
+3 33
+select x as ASOF2_x, y from t1 for system_time as of @t0;
+ASOF2_x y
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
+8 108
+9 109
+select x as FROMTO2_x, y from t1 for system_time from '1970-01-01 00:00' to @t1;
+FROMTO2_x y
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
+8 108
+9 109
+select x as BETWAND2_x, y from t1 for system_time between '1970-01-01 00:00' and timestamp @t1;
+BETWAND2_x y
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
+8 108
+9 109
+3 33
+drop table t1;
+create table t1(
+x int,
+y int,
+sys_start SYS_TYPE as row start invisible,
+sys_end SYS_TYPE as row end invisible,
+period for system_time (sys_start, sys_end))
+with system versioning engine=ENGINE;
+create table t2 like t1;
+insert into t1 values (1, 1), (1, 2), (1, 3), (4, 4), (5, 5);
+insert into t2 values (1, 2), (2, 1), (3, 1);
+set @t0= now(6);
+select t1.x as IJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 inner join t2 on t1.x = t2.x;
+IJ1_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+select t1.x as LJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 left join t2 on t1.x = t2.x;
+LJ1_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+4 4 NULL NULL
+5 5 NULL NULL
+select t1.x as RJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 right join t2 on t1.x = t2.x;
+RJ1_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+NULL NULL 2 1
+NULL NULL 3 1
+delete from t1;
+delete from t2;
+select IJ2_x1,y1,x2,y2 from (select t1.x as IJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 inner join t2 on t1.x = t2.x)
+for system_time as of timestamp @t0 as t;
+IJ2_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+select LJ2_x1,y1,x2,y2 from (select t1.x as LJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 left join t2 on t1.x = t2.x)
+for system_time as of timestamp @t0 as t;
+LJ2_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+4 4 NULL NULL
+5 5 NULL NULL
+select RJ2_x1,y1,x2,y2 from (select t1.x as RJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 right join t2 on t1.x = t2.x)
+for system_time as of timestamp @t0 as t;
+RJ2_x1 y1 x2 y2
+1 1 1 2
+1 2 1 2
+1 3 1 2
+NULL NULL 2 1
+NULL NULL 3 1
+drop table t1;
+drop table t2;
+# MDEV-14686 Server crashes in Item_field::used_tables on 2nd call of SP [#422]
+create or replace table t1 (called int, bad int) with system versioning;
+create or replace procedure bad() select * from t1 where bad in (select called from t1);
+called bad
+called bad
+called bad
+called bad
+called bad
+called bad
+called bad
+called bad
+# bad() is good.
+# MDEV-14751 Server crashes in TABLE::versioned on 2nd execution of SP [#431]
+create or replace table t1 (called_bad int);
+create or replace table t2 (b int);
+create or replace procedure bad() select * from t1 where ( 5, 6 ) in ( select b, b from t2 ) and called_bad in ( select max(b) from t2 );
+called_bad
+called_bad
+called_bad
+called_bad
+called_bad
+called_bad
+called_bad
+called_bad
+# bad() is good.
+# MDEV-14786 Server crashes in Item_cond::transform on 2nd execution of SP querying from a view [#436]
+create or replace table t1 (called_bad int) with system versioning;
+create or replace view v1 as select called_bad from t1 where called_bad < 5;
+create or replace procedure bad() select called_bad from v1;
+called_bad
+called_bad
+called_bad
+called_bad
+called_bad
+called_bad
+called_bad
+called_bad
+# bad() is good.
+# wildcard expansion on hidden fields.
+create or replace table t1(
+A int
+) with system versioning;
+insert into t1 values(1);
+select * from t1;
+A
+1
+create or replace table t1 (x int);
+insert into t1 values (1);
+select * from t1 for system_time all;
+ERROR HY000: Table `t1` is not system-versioned
+create or replace table t1 (x int) with system versioning;
+insert into t1 values (1);
+select * from t1 for system_time as of now() for update;
+ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
+create or replace table t1 (a int not null auto_increment primary key) with system versioning;
+select * from (t1 as t2 left join t1 as t3 using (a)) natural left join t1;
+a
+create or replace table t1 (a int) with system versioning;
+create or replace table t2 (a int) with system versioning;
+insert into t1 values(1);
+insert into t2 values(1);
+create or replace view v1 as select * from t2 inner join t1 using (a);
+select * from v1;
+a
+1
+drop view v1;
+create or replace table t1 (a int) with system versioning;
+insert into t1 values (1);
+create view vt1 as select a from t1;
+select * from t1 natural join vt1;
+a
+1
+drop view vt1;
+create or replace table t1(x int) with system versioning;
+select * from (t1 as r left join t1 as u using (x)), t1;
+x x
+create or replace table t1 (a int) with system versioning;
+insert into t1 values (1);
+create trigger read_end after update on t1
+for each row set @end = old.row_end;
+update t1 set a=2;
+select @end;
+@end
+MAX_RESULT
+create or replace table t1 (a int) with system versioning;
+create or replace table t2 (b int) with system versioning;
+insert into t1 values (1);
+insert into t2 values (2);
+select * from (select * from t1 cross join t2) as tmp;
+a b
+1 2
+select * from (select * from (select * from t1 cross join t2) as tmp1) as tmp2;
+a b
+1 2
+select * from (select * from t1 cross join t2 for system_time as of timestamp ('1970-01-01 00:00')) as tmp;
+a b
+create or replace table t1(a1 int) with system versioning;
+create or replace table t2(a2 int) with system versioning;
+insert into t1 values(1),(2);
+insert into t2 values(1),(2);
+select * from t1 for system_time all natural left join t2 for system_time all;
+a1 a2
+1 1
+2 1
+1 2
+2 2
+create or replace table t1(a1 int) with system versioning;
+create or replace table t2(a2 int) with system versioning;
+insert into t1 values(1),(2);
+insert into t2 values(1),(2);
+create or replace view v1 as select a1 from t1;
+select * from v1 natural join t2;
+a1 a2
+1 1
+2 1
+1 2
+2 2
+select * from v1 natural left join t2;
+a1 a2
+1 1
+2 1
+1 2
+2 2
+select * from v1 natural right join t2;
+a2 a1
+1 1
+2 1
+1 2
+2 2
+create or replace table t1 (a int) with system versioning;
+insert into t1 values (1);
+insert into t1 values (2);
+insert into t1 values (3);
+select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
+a a
+2 1
+3 1
+2 2
+3 2
+2 3
+3 3
+1 NULL
+create or replace table t1 (x int) with system versioning;
+create or replace table t2 (y int) with system versioning;
+insert into t1 values (1), (2), (3);
+delete from t1 where x = 3;
+insert into t2 values (1);
+select * from t1, t2 for system_time all;
+x y
+1 1
+2 1
+select * from (select * from t1 for system_time all, t2 for system_time all) for system_time all as t;
+ERROR HY000: Table `t` is not system-versioned
+select * from (t1 for system_time all join t2 for system_time all) for system_time all;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'system_time all' at line 1
+# 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' )";
+execute stmt;
+ERROR 22003: DOUBLE value is out of range in 'exp('20010609211642053929')'
+select a from v1;
+a
+drop view v1;
+drop table t1, t2;
diff --git a/mysql-test/suite/versioning/r/simple.result b/mysql-test/suite/versioning/r/simple.result
new file mode 100644
index 00000000..39ced386
--- /dev/null
+++ b/mysql-test/suite/versioning/r/simple.result
@@ -0,0 +1,200 @@
+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;
+emp_id dept_id name salary
+1 10 bill 1000
+update emp set salary=2000 where name="bill";
+commit;
+select row_start into @ts_3 from emp where name="bill";
+select * from emp;
+emp_id dept_id name salary
+1 10 bill 2000
+select * from emp for system_time as of timestamp @ts_2;
+emp_id dept_id name salary
+1 10 bill 1000
+select * from emp for system_time as of timestamp @ts_3;
+emp_id dept_id name salary
+1 10 bill 2000
+select * from emp e, dept d
+where d.dept_id = 10
+and d.dept_id = e.dept_id;
+emp_id dept_id name salary dept_id name
+1 10 bill 2000 10 accounting
+select * from
+emp for system_time from timestamp @ts_1 to timestamp @ts_2 e,
+dept for system_time from timestamp @ts_1 to timestamp @ts_2 d
+where d.dept_id = 10
+and d.dept_id = e.dept_id;
+emp_id dept_id name salary dept_id name
+set statement system_versioning_asof=@ts_0 for
+select * from emp e, dept d
+where d.dept_id = 10
+and d.dept_id = e.dept_id;
+emp_id dept_id name salary dept_id name
+set statement system_versioning_asof=@ts_1 for
+select * from emp e, dept d
+where d.dept_id = 10
+and d.dept_id = e.dept_id;
+emp_id dept_id name salary dept_id name
+set statement system_versioning_asof=@ts_2 for
+select * from emp e, dept d
+where d.dept_id = 10
+and d.dept_id = e.dept_id;
+emp_id dept_id name salary dept_id name
+1 10 bill 1000 10 accounting
+set statement system_versioning_asof=@ts_3 for
+select * from emp e, dept d
+where d.dept_id = 10
+and d.dept_id = e.dept_id;
+emp_id dept_id name salary dept_id name
+1 10 bill 2000 10 accounting
+drop table emp, dept;
+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;
+Field Type Null Key Default Extra
+a timestamp(6) YES NULL
+b timestamp(6) YES NULL VIRTUAL GENERATED
+c timestamp(6) YES NULL STORED GENERATED
+d timestamp(6) NO NULL STORED GENERATED
+e timestamp(6) NO NULL STORED GENERATED
+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';
+table_catalog def
+table_schema test
+table_name t1
+column_name a
+ordinal_position 1
+column_default NULL
+is_nullable YES
+data_type timestamp
+character_maximum_length NULL
+character_octet_length NULL
+numeric_precision NULL
+numeric_scale NULL
+datetime_precision 6
+character_set_name NULL
+collation_name NULL
+column_type timestamp(6)
+column_key
+extra
+column_comment
+is_generated NEVER
+generation_expression NULL
+--- ---
+table_catalog def
+table_schema test
+table_name t1
+column_name b
+ordinal_position 2
+column_default NULL
+is_nullable YES
+data_type timestamp
+character_maximum_length NULL
+character_octet_length NULL
+numeric_precision NULL
+numeric_scale NULL
+datetime_precision 6
+character_set_name NULL
+collation_name NULL
+column_type timestamp(6)
+column_key
+extra VIRTUAL GENERATED
+column_comment
+is_generated ALWAYS
+generation_expression `a` + interval 1 day
+--- ---
+table_catalog def
+table_schema test
+table_name t1
+column_name c
+ordinal_position 3
+column_default NULL
+is_nullable YES
+data_type timestamp
+character_maximum_length NULL
+character_octet_length NULL
+numeric_precision NULL
+numeric_scale NULL
+datetime_precision 6
+character_set_name NULL
+collation_name NULL
+column_type timestamp(6)
+column_key
+extra STORED GENERATED
+column_comment
+is_generated ALWAYS
+generation_expression `a` + interval 1 month
+--- ---
+table_catalog def
+table_schema test
+table_name t1
+column_name d
+ordinal_position 4
+column_default NULL
+is_nullable NO
+data_type timestamp
+character_maximum_length NULL
+character_octet_length NULL
+numeric_precision NULL
+numeric_scale NULL
+datetime_precision 6
+character_set_name NULL
+collation_name NULL
+column_type timestamp(6)
+column_key
+extra STORED GENERATED
+column_comment
+is_generated ALWAYS
+generation_expression ROW START
+--- ---
+table_catalog def
+table_schema test
+table_name t1
+column_name e
+ordinal_position 5
+column_default NULL
+is_nullable NO
+data_type timestamp
+character_maximum_length NULL
+character_octet_length NULL
+numeric_precision NULL
+numeric_scale NULL
+datetime_precision 6
+character_set_name NULL
+collation_name NULL
+column_type timestamp(6)
+column_key
+extra STORED GENERATED
+column_comment
+is_generated ALWAYS
+generation_expression ROW END
+--- ---
+drop table t1;
diff --git a/mysql-test/suite/versioning/r/sysvars.result b/mysql-test/suite/versioning/r/sysvars.result
new file mode 100644
index 00000000..a5a3f799
--- /dev/null
+++ b/mysql-test/suite/versioning/r/sysvars.result
@@ -0,0 +1,256 @@
+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';
+Variable_name Value
+system_versioning_asof DEFAULT
+show variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof DEFAULT
+select * from t;
+a
+2
+set system_versioning_asof= '2031-1-1 0:0:0';
+show variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof 2031-01-01 00:00:00.000000
+select * from t;
+a
+2
+set system_versioning_asof= '2011-1-1 0:0:0';
+show variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof 2011-01-01 00:00:00.000000
+select * from t;
+a
+set global system_versioning_asof= 'alley';
+ERROR 42000: Variable 'system_versioning_asof' can't be set to the value of 'alley'
+set global system_versioning_asof= null;
+ERROR 42000: Variable 'system_versioning_asof' can't be set to the value of 'NULL'
+set global system_versioning_asof= 1;
+ERROR 42000: Incorrect argument type to variable 'system_versioning_asof'
+set global system_versioning_asof= 1.1;
+ERROR 42000: Incorrect argument type to variable 'system_versioning_asof'
+set global system_versioning_asof= '2011-02-29 00:00';
+ERROR 42000: Variable 'system_versioning_asof' can't be set to the value of '2011-02-29 00:00'
+set global system_versioning_asof= '2011-02-28 24:00';
+ERROR 42000: Variable 'system_versioning_asof' can't be set to the value of '2011-02-28 24:00'
+set global system_versioning_asof= '2011-00-28 00:00';
+ERROR 42000: Variable 'system_versioning_asof' can't be set to the value of '2011-00-28 00:00'
+set global system_versioning_asof= '0000-00-00 00:00';
+ERROR 42000: Variable 'system_versioning_asof' can't be set to the value of '0000-00-00 00:00'
+set system_versioning_asof= 'alley';
+ERROR 42000: Variable 'system_versioning_asof' can't be set to the value of 'alley'
+set system_versioning_asof= null;
+ERROR 42000: Variable 'system_versioning_asof' can't be set to the value of 'NULL'
+set system_versioning_asof= 1;
+ERROR 42000: Incorrect argument type to variable 'system_versioning_asof'
+set system_versioning_asof= 1.1;
+ERROR 42000: Incorrect argument type to variable 'system_versioning_asof'
+set system_versioning_asof= '2011-02-29 00:00';
+ERROR 42000: Variable 'system_versioning_asof' can't be set to the value of '2011-02-29 00:00'
+set system_versioning_asof= '2011-02-28 24:00';
+ERROR 42000: Variable 'system_versioning_asof' can't be set to the value of '2011-02-28 24:00'
+set system_versioning_asof= '2011-00-28 00:00';
+ERROR 42000: Variable 'system_versioning_asof' can't be set to the value of '2011-00-28 00:00'
+set system_versioning_asof= '0000-00-00 00:00';
+ERROR 42000: Variable 'system_versioning_asof' can't be set to the value of '0000-00-00 00:00'
+# GLOBAL @@system_versioning_asof
+set global system_versioning_asof= '1991-11-11 11:11:11.1111119';
+Warnings:
+Note 1292 Truncated incorrect datetime value: '1991-11-11 11:11:11.1111119'
+show global variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof 1991-11-11 11:11:11.111111
+set global system_versioning_asof= '1990-01-01 00:00:00';
+show global variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof 1990-01-01 00:00:00.000000
+set global system_versioning_asof= timestamp'1991-11-11 11:11:11.1111119';
+Warnings:
+Note 1292 Truncated incorrect DATETIME value: '1991-11-11 11:11:11.1111119'
+show global variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof 1991-11-11 11:11:11.111111
+set @ts= timestamp'1990-01-01 00:00:00';
+set global system_versioning_asof= @ts;
+show global variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof 1990-01-01 00:00:00.000000
+set global system_versioning_asof= default;
+select @@global.system_versioning_asof;
+@@global.system_versioning_asof
+DEFAULT
+# SESSION @@system_versioning_asof
+set system_versioning_asof= '1991-11-11 11:11:11.1111119';
+Warnings:
+Note 1292 Truncated incorrect datetime value: '1991-11-11 11:11:11.1111119'
+show variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof 1991-11-11 11:11:11.111111
+set system_versioning_asof= '1990-01-01 00:00:00';
+show variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof 1990-01-01 00:00:00.000000
+set system_versioning_asof= timestamp'1991-11-11 11:11:11.1111119';
+Warnings:
+Note 1292 Truncated incorrect DATETIME value: '1991-11-11 11:11:11.1111119'
+show variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof 1991-11-11 11:11:11.111111
+set @ts= timestamp'1990-01-01 00:00:00';
+set system_versioning_asof= @ts;
+show variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof 1990-01-01 00:00:00.000000
+# 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;
+different
+1
+set system_versioning_asof= default;
+select @@global.system_versioning_asof != @@system_versioning_asof as different;
+different
+1
+set global system_versioning_asof= default;
+select @@global.system_versioning_asof = @@system_versioning_asof as equal;
+equal
+1
+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;
+@@global.system_versioning_asof @@system_versioning_asof
+DEFAULT DEFAULT
+select * from t for system_time all;
+a
+2
+1
+select * from t;
+a
+2
+select * from t for system_time as of timestamp current_timestamp(6);
+a
+2
+select * from t for system_time all;
+a
+2
+1
+select * from t for system_time from '1970-01-01 00:00' to current_timestamp(6);
+a
+2
+1
+select * from t for system_time between '1970-01-01 00:00' and current_timestamp(6);
+a
+2
+1
+# MDEV-16026: Global system_versioning_asof must not be used if client sessions can have non-default time zone
+# 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';
+Variable_name Value
+system_versioning_asof 1999-09-08 00:00:00.000000
+set session time_zone = '+03:00';
+show global variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof 1999-09-07 17:00:00.000000
+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';
+Variable_name Value
+system_versioning_asof 2000-09-08 00:00:00.000000
+set session time_zone = '+10:00';
+show session variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof 2000-09-08 07:00:00.000000
+# global and local time zones should not interfere
+show global variables like 'system_versioning_asof';
+Variable_name Value
+system_versioning_asof 1999-09-08 00:00:00.000000
+set time_zone= "+10:00";
+set system_versioning_asof= FROM_UNIXTIME(@before);
+select * from t as empty;
+a
+set system_versioning_asof= FROM_UNIXTIME(@after);
+select * from t as nonempty;
+a
+1
+set time_zone= "+03:00";
+set system_versioning_asof= FROM_UNIXTIME(@before);
+select * from t as empty;
+a
+set system_versioning_asof= FROM_UNIXTIME(@after);
+select * from t as nonempty;
+a
+1
+# MDEV-16481: set global system_versioning_asof=sf() crashes in specific case
+# 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";
+Variable_name Value
+Feature_system_versioning 2
+drop table t;
+#
+# MDEV-22906 Disallow system_versioning_asof in DML
+#
+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);
+x
+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);
+x
+2
+replace t2 select x + 1 from t1;
+select * from t2;
+y
+2
+3
+insert t2 select x + 2 from t1;
+select * from t2;
+y
+2
+3
+4
+drop tables t1, t2;
+#
+# MDEV-16991 Rounding vs truncation for TIME, DATETIME, TIMESTAMP
+#
+SET sql_mode=TIME_ROUND_FRACTIONAL;
+SET @@global.system_versioning_asof= timestamp'2001-12-31 23:59:59.9999999';
+Warnings:
+Note 1292 Truncated incorrect DATETIME value: '2001-12-31 23:59:59.9999999'
+SELECT @@global.system_versioning_asof;
+@@global.system_versioning_asof
+2002-01-01 00:00:00.000000
+SET @@global.system_versioning_asof= DEFAULT;
+#
+# MDEV-23562 Assertion `time_type == MYSQL_TIMESTAMP_DATETIME' failed upon SELECT from versioned table
+#
+CREATE TABLE t1 (a INT) WITH SYSTEM VERSIONING;
+SET system_versioning_asof= DATE(NOW());
+SELECT * FROM t1;
+a
+DROP TABLE t1;
+SET system_versioning_asof= DEFAULT;
+# End of 10.4 tests
diff --git a/mysql-test/suite/versioning/r/trx_id.result b/mysql-test/suite/versioning/r/trx_id.result
new file mode 100644
index 00000000..9beec414
--- /dev/null
+++ b/mysql-test/suite/versioning/r/trx_id.result
@@ -0,0 +1,613 @@
+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;
+# 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;
+x sys_trx_start > 1 sys_trx_end
+3 1 18446744073709551615
+# 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;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+select count(*) = 1 from mysql.transaction_registry where transaction_id = @trx_start;
+count(*) = 1
+1
+create or replace table t1 (x int);
+select count(*) from mysql.transaction_registry into @tmp;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+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;
+count(*) = @tmp
+1
+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;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+select count(*) = 1 from mysql.transaction_registry where transaction_id = @trx_start;
+count(*) = 1
+1
+create or replace table t1 (x int);
+select count(*) from mysql.transaction_registry into @tmp;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+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 count(*) = @tmp + 1 from mysql.transaction_registry;
+count(*) = @tmp + 1
+1
+# 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;
+transaction_based
+1
+# 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;
+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;
+set @ts1= sysdate(6);
+connection con1;
+commit;
+disconnect con1;
+connection default;
+set @ts2= sysdate(6);
+commit;
+set @ts3= sysdate(6);
+select sys_start from t1 where x = 1 into @trx_id1;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+select sys_start from t1 where x = 2 into @trx_id2;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+select sys_start from t1 where x = 3 into @trx_id3;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+select @trx_id1 < @trx_id2, @trx_id2 < @trx_id3;
+@trx_id1 < @trx_id2 @trx_id2 < @trx_id3
+1 1
+select @ts1 < @ts2, @ts2 < @ts3;
+@ts1 < @ts2 @ts2 < @ts3
+1 1
+# MVCC is resolved
+select * from t1 for system_time as of transaction @trx_id1;
+x
+100
+1
+2
+3
+select * from t1 for system_time as of timestamp @ts1;
+x
+100
+3
+select * from t1 for system_time as of transaction @trx_id2;
+x
+100
+2
+3
+select * from t1 for system_time as of timestamp @ts2;
+x
+100
+2
+3
+select * from t1 for system_time as of transaction @trx_id3;
+x
+100
+3
+select * from t1 for system_time as of timestamp @ts3;
+x
+100
+1
+2
+3
+#
+# MDEV-15427 IB: TRX_ID based operations inside transaction generate history
+#
+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;
+x
+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;
+x row_start < row_end
+4 1
+2 1
+#
+# MDEV-15951 system versioning by trx id doesn't work with partitioning
+# currently trx_id does not support partitioning by system_time
+#
+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
+);
+ERROR HY000: `row_start` must be of type TIMESTAMP(6) for system-versioned table `t1`
+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;
+alter table t1 partition by system_time (
+partition p0 history,
+partition pn current
+);
+ERROR HY000: `row_start` must be of type TIMESTAMP(6) for system-versioned table `t1`
+drop table t1;
+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 HY000: Transaction-precise system-versioned tables do not support partitioning by ROW START or ROW END
+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 HY000: Transaction-precise system-versioned tables do not support partitioning by ROW START or ROW END
+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 HY000: Transaction-precise system-versioned tables do not support partitioning by ROW START or ROW END
+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)
+);
+ERROR HY000: Transaction-precise system-versioned tables do not support partitioning by ROW START or ROW END
+#
+# MDEV-16010 Too many rows with AS OF point_in_the_past_or_NULL
+#
+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';
+x
+select * from t1 for system_time as of NULL;
+x
+# 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);
+insert into t1 values (1);
+commit;
+select row_start from t1 into @trx_id;
+Warnings:
+Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
+select trt_begin_ts(@trx_id) <= @ts1 as BEGIN_TS_GOOD;
+BEGIN_TS_GOOD
+1
+drop table t1;
+#
+# MDEV-16100 FOR SYSTEM_TIME erroneously resolves string user variables as transaction IDs
+#
+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;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 1 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`x` AS `x` from `test`.`t1` FOR SYSTEM_TIME AS OF TRANSACTION @`ts` where trt_trx_sees(`test`.`t1`.`sys_trx_end`,@`ts`) and trt_trx_sees_eq(@`ts`,`test`.`t1`.`sys_trx_start`)
+EXPLAIN EXTENDED SELECT x FROM t1 FOR SYSTEM_TIME AS OF TIMESTAMP @ts;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 1 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`x` AS `x` from `test`.`t1` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts` where trt_trx_sees(`test`.`t1`.`sys_trx_end`,<cache>(trt_trx_id(@`ts`))) and trt_trx_sees_eq(<cache>(trt_trx_id(@`ts`)),`test`.`t1`.`sys_trx_start`)
+EXPLAIN EXTENDED SELECT x FROM t1 FOR SYSTEM_TIME AS OF @ts;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 1 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`x` AS `x` from `test`.`t1` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts` where trt_trx_sees(`test`.`t1`.`sys_trx_end`,<cache>(trt_trx_id(@`ts`))) and trt_trx_sees_eq(<cache>(trt_trx_id(@`ts`)),`test`.`t1`.`sys_trx_start`)
+DROP TABLE t1;
+#
+# Testing AS OF with expressions of various kinds and data types
+#
+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);
+#
+# ROW is not supported
+#
+SELECT * FROM t1 FOR SYSTEM_TIME AS OF (1,1);
+ERROR HY000: Illegal parameter data type row for operation 'FOR SYSTEM_TIME'
+SELECT * FROM t2 FOR SYSTEM_TIME AS OF (1,1);
+ERROR HY000: Illegal parameter data type row for operation 'FOR SYSTEM_TIME'
+#
+# DOUBLE is not supported, use explicit CAST
+#
+SELECT * FROM t1 FOR SYSTEM_TIME AS OF TRANSACTION RAND();
+ERROR HY000: Illegal parameter data type double for operation 'FOR SYSTEM_TIME'
+SELECT * FROM t1 FOR SYSTEM_TIME AS OF TRANSACTION (RAND());
+ERROR HY000: Illegal parameter data type double for operation 'FOR SYSTEM_TIME'
+SELECT * FROM t1 FOR SYSTEM_TIME AS OF TRANSACTION COALESCE(RAND());
+ERROR HY000: Illegal parameter data type double for operation 'FOR SYSTEM_TIME'
+SELECT * FROM t2 FOR SYSTEM_TIME AS OF TRANSACTION RAND();
+ERROR HY000: Illegal parameter data type double for operation 'FOR SYSTEM_TIME'
+SELECT * FROM t2 FOR SYSTEM_TIME AS OF TRANSACTION (RAND());
+ERROR HY000: Illegal parameter data type double for operation 'FOR SYSTEM_TIME'
+SELECT * FROM t2 FOR SYSTEM_TIME AS OF TRANSACTION COALESCE(RAND());
+ERROR HY000: Illegal parameter data type double for operation 'FOR SYSTEM_TIME'
+#
+# DECIMAL is not supported, use explicit CAST
+#
+SELECT * FROM t1 FOR SYSTEM_TIME AS OF TRANSACTION 10.1;
+ERROR HY000: Illegal parameter data type decimal for operation 'FOR SYSTEM_TIME'
+SELECT * FROM t1 FOR SYSTEM_TIME AS OF TRANSACTION COALESCE(10.1);
+ERROR HY000: Illegal parameter data type decimal for operation 'FOR SYSTEM_TIME'
+SELECT * FROM t2 FOR SYSTEM_TIME AS OF TRANSACTION 10.1;
+ERROR HY000: Illegal parameter data type decimal for operation 'FOR SYSTEM_TIME'
+SELECT * FROM t2 FOR SYSTEM_TIME AS OF TRANSACTION COALESCE(10.1);
+ERROR HY000: Illegal parameter data type decimal for operation 'FOR SYSTEM_TIME'
+#
+# YEAR is not supported, use explicit CAST
+#
+BEGIN NOT ATOMIC
+DECLARE var YEAR;
+SELECT * FROM t1 FOR SYSTEM_TIME AS OF TRANSACTION var;
+END;
+$$
+ERROR HY000: Illegal parameter data type year for operation 'FOR SYSTEM_TIME'
+BEGIN NOT ATOMIC
+DECLARE var YEAR;
+SELECT * FROM t2 FOR SYSTEM_TIME AS OF TRANSACTION var;
+END;
+$$
+ERROR HY000: Illegal parameter data type year for operation 'FOR SYSTEM_TIME'
+#
+# ENUM is not supported, use explicit CAST
+#
+BEGIN NOT ATOMIC
+DECLARE var ENUM('xxx') DEFAULT 'xxx';
+SELECT * FROM t1 FOR SYSTEM_TIME AS OF TRANSACTION var;
+END;
+$$
+ERROR HY000: Illegal parameter data type enum for operation 'FOR SYSTEM_TIME'
+BEGIN NOT ATOMIC
+DECLARE var ENUM('xxx') DEFAULT 'xxx';
+SELECT * FROM t2 FOR SYSTEM_TIME AS OF TRANSACTION var;
+END;
+$$
+ERROR HY000: Illegal parameter data type enum for operation 'FOR SYSTEM_TIME'
+#
+# SET is not supported, use explicit CAST
+#
+BEGIN NOT ATOMIC
+DECLARE var SET('xxx') DEFAULT 'xxx';
+SELECT * FROM t1 FOR SYSTEM_TIME AS OF TRANSACTION var;
+END;
+$$
+ERROR HY000: Illegal parameter data type set for operation 'FOR SYSTEM_TIME'
+BEGIN NOT ATOMIC
+DECLARE var SET('xxx') DEFAULT 'xxx';
+SELECT * FROM t2 FOR SYSTEM_TIME AS OF TRANSACTION var;
+END;
+$$
+ERROR HY000: Illegal parameter data type set for operation 'FOR SYSTEM_TIME'
+BEGIN NOT ATOMIC
+DECLARE var BIT(10);
+SELECT * FROM t2 FOR SYSTEM_TIME AS OF TRANSACTION var;
+END;
+$$
+ERROR HY000: Transaction-precise system versioning for `t2` is not supported
+#
+# String literals resolve to TIMESTAMP
+#
+SELECT * FROM t1 FOR SYSTEM_TIME AS OF '2038-12-30 00:00:00';
+x
+1
+SELECT * FROM t2 FOR SYSTEM_TIME AS OF '2038-12-30 00:00:00';
+x
+DROP TABLE t1, t2;
+#
+# MDEV-16094 Crash when using AS OF with a stored function
+#
+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();
+x start_timestamp end_timestamp
+SELECT * FROM tts FOR SYSTEM_TIME AS OF TRANSACTION ftx();
+ERROR HY000: Transaction-precise system versioning for `tts` is not supported
+SELECT * FROM ttx FOR SYSTEM_TIME AS OF fts();
+x start_timestamp end_timestamp
+SELECT * FROM ttx FOR SYSTEM_TIME AS OF TRANSACTION ftx();
+x start_timestamp end_timestamp
+DROP TABLE tts;
+DROP TABLE ttx;
+DROP FUNCTION fts;
+DROP FUNCTION ftx;
+#
+# MDEV-16330 Allow instant change of WITH SYSTEM VERSIONING column attribute
+#
+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);
+# 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';
+prtype
+50179
+ALTER TABLE t
+CHANGE a a INT WITHOUT SYSTEM VERSIONING;
+affected rows: 0
+info: Records: 0 Duplicates: 0 Warnings: 0
+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';
+prtype
+1027
+UPDATE t SET a=11;
+SELECT COUNT(*) FROM t FOR SYSTEM_TIME ALL;
+COUNT(*)
+1
+# 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';
+prtype
+1027
+ALTER TABLE t
+CHANGE a a INT WITH SYSTEM VERSIONING,
+ADD PRIMARY KEY pk(a);
+affected rows: 0
+info: Records: 0 Duplicates: 0 Warnings: 1
+Warnings:
+Warning 1280 Name 'pk' ignored for PRIMARY key.
+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';
+prtype
+50435
+UPDATE t SET a=1;
+SELECT COUNT(*) FROM t FOR SYSTEM_TIME ALL;
+COUNT(*)
+2
+SHOW CREATE TABLE t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) NOT NULL,
+ `b` 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,
+ PRIMARY KEY (`a`,`row_end`),
+ PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+# 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';
+prtype
+50179
+ALTER TABLE t
+CHANGE b b INT WITHOUT SYSTEM VERSIONING;
+affected rows: 0
+info: Records: 0 Duplicates: 0 Warnings: 0
+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';
+prtype
+1027
+UPDATE t SET b=11;
+SELECT COUNT(*) FROM t FOR SYSTEM_TIME ALL;
+COUNT(*)
+1
+DROP TABLE t;
+SET @@SYSTEM_VERSIONING_ALTER_HISTORY=ERROR;
+SELECT count(*) from mysql.transaction_registry where begin_timestamp>=commit_timestamp;
+count(*)
+0
+# MDEV-18875 Assertion `thd->transaction.stmt.ha_list == __null ||
+# trans == &thd->transaction.stmt' failed or bogus ER_DUP_ENTRY upon
+# 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;
+# MDEV-18865 Assertion `t->first->versioned_by_id()'
+# 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;
+#
+# MDEV-20842 Crash using versioning plugin functions after plugin was removed from server
+#
+uninstall plugin test_versioning;
+select trt_begin_ts(0);
+ERROR 42000: FUNCTION test.trt_begin_ts does not exist
+#
+# MDEV-21650 Non-empty statement transaction on global rollback after TRT update error
+#
+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);
+Warnings:
+Note 1060 Duplicate column name 'app'
+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;
+select * from t1 for system_time as of now();
+ERROR HY000: TRX_ID ... not found in `mysql.transaction_registry`
+connection con1;
+set innodb_lock_wait_timeout= 1, lock_wait_timeout= 1;
+alter table xx;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+disconnect con1;
+connection default;
+drop table t1;
diff --git a/mysql-test/suite/versioning/r/update,trx_id.rdiff b/mysql-test/suite/versioning/r/update,trx_id.rdiff
new file mode 100644
index 00000000..18395507
--- /dev/null
+++ b/mysql-test/suite/versioning/r/update,trx_id.rdiff
@@ -0,0 +1,24 @@
+--- update.result
++++ update.reject
+@@ -84,12 +84,10 @@
+ commit;
+ select x, y, sys_trx_end = MAXVAL as current from t1 for system_time all order by sys_trx_end, x, y;
+ x y current
+-3 1 0
+ 2 1 0
+-3 2 0
++3 1 0
+ 4 1 0
+ 5 1 0
+-5 2 0
+ 1 1 1
+ 2 2 1
+ 3 3 1
+@@ -464,7 +462,6 @@
+ select nid, nstate, check_row(row_start, row_end) from t1 for system_time all order by row_start, row_end;
+ nid nstate check_row(row_start, row_end)
+ 1 1 HISTORICAL ROW
+-1 1 HISTORICAL ROW
+ 1 3 CURRENT ROW
+ commit;
+ drop tables t1;
diff --git a/mysql-test/suite/versioning/r/update-big.result b/mysql-test/suite/versioning/r/update-big.result
new file mode 100644
index 00000000..506d1d23
--- /dev/null
+++ b/mysql-test/suite/versioning/r/update-big.result
@@ -0,0 +1,99 @@
+#
+# MDEV-15458 Segfault in heap_scan() upon UPDATE after ADD SYSTEM VERSIONING
+#
+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");
+#
+# MDEV-23642 Locking timeout caused by auto-creation affects original DML
+#
+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;
+Warnings:
+Error 1205 Lock wait timeout exceeded; try restarting transaction
+Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p0`) is out of INTERVAL, need more HISTORY partitions
+disconnect con1;
+connection default;
+select * from t1;
+x
+2
+123
+drop table t1;
+set timestamp= default;
+#
+# MDEV-25339 Assertion `thd->transaction.stmt.is_empty() || thd->in_sub_stmt' failed
+#
+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;
+x
+1
+connect con1, localhost, root;
+set lock_wait_timeout= 1;
+set innodb_lock_wait_timeout= 1;
+update t1 set x= x + 111;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+select * from t1;
+x
+disconnect con1;
+connection default;
+drop table t1;
+#
+# MDEV-25482 Auto-create: Server hangs after a failed attempt to create partition
+#
+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;
+Warnings:
+Error 1205 Lock wait timeout exceeded; try restarting transaction
+Warning 4114 Versioned table `test`.`t`: last HISTORY partition (`p0`) is out of INTERVAL, need more HISTORY partitions
+update t set a= 400 where pk = 4;
+Warnings:
+Error 1205 Lock wait timeout exceeded; try restarting transaction
+Warning 4114 Versioned table `test`.`t`: last HISTORY partition (`p0`) is out of INTERVAL, need more HISTORY partitions
+disconnect con1;
+connection default;
+select * from t where pk = 4;
+pk a
+4 400
+rollback;
+drop tables t;
diff --git a/mysql-test/suite/versioning/r/update.result b/mysql-test/suite/versioning/r/update.result
new file mode 100644
index 00000000..c439f5cf
--- /dev/null
+++ b/mysql-test/suite/versioning/r/update.result
@@ -0,0 +1,485 @@
+create table t1(
+x int unsigned,
+y int unsigned,
+sys_trx_start SYS_DATATYPE as row start invisible,
+sys_trx_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_trx_start, sys_trx_end))
+with system versioning;
+insert into t1(x, y) values (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;
+x y
+1 1000
+2 2000
+3 3000
+4 4000
+5 5000
+6 6000
+7 7000
+8 8000
+9 9000
+update t1 set y = y + 1 where x > 7;
+select x, y from t1 order by x, y;
+x y
+1 1000
+2 2000
+3 3000
+4 4000
+5 5000
+6 6000
+7 7000
+8 8001
+9 9001
+select x, y from t1 for system_time all order by sys_trx_end, x, y;
+x y
+8 8000
+9 9000
+1 1000
+2 2000
+3 3000
+4 4000
+5 5000
+6 6000
+7 7000
+8 8001
+9 9001
+drop table t1;
+create table t1 (
+id bigint primary key,
+x int,
+y int without system versioning,
+sys_trx_start SYS_DATATYPE as row start invisible,
+sys_trx_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_trx_start, sys_trx_end))
+with system versioning;
+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;
+A1 x y
+1 11 11
+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;
+A2 x
+1 11
+drop table t1;
+set timestamp= default;
+create table t1 (
+x int,
+y int,
+sys_trx_start SYS_DATATYPE as row start invisible,
+sys_trx_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_trx_start, sys_trx_end)
+) with system versioning;
+insert into t1 (x, y) values (1, 1), (2, 1), (3, 1), (4, 1), (5, 1);
+start transaction;
+update t1 set y= y + 1 where x = 3;
+update t1 set y= y + 1 where x = 2;
+update t1 set y= y + 1 where x = 3;
+update t1 set y= y + 1 where x > 3;
+update t1 set y= y + 1 where x > 4;
+commit;
+select x, y, sys_trx_end = MAXVAL as current from t1 for system_time all order by sys_trx_end, x, y;
+x y current
+3 1 0
+2 1 0
+3 2 0
+4 1 0
+5 1 0
+5 2 0
+1 1 1
+2 2 1
+3 3 1
+4 2 1
+5 3 1
+drop table t1;
+create table t1 (
+id int primary key auto_increment,
+x int,
+sys_trx_start SYS_DATATYPE as row start invisible,
+sys_trx_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_trx_start, sys_trx_end))
+with system versioning;
+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;
+x
+select x from t1 for system_time as of timestamp @t1;
+x
+1
+select x from t1 for system_time as of timestamp @t2;
+x
+2
+select x from t1 for system_time as of timestamp now(6);
+x
+3
+drop table t1;
+create table t1(
+x int unsigned,
+sys_trx_end SYS_DATATYPE as row end invisible,
+sys_trx_start SYS_DATATYPE 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;
+x y
+3 3000
+1 1000
+3 3001
+4 4000
+4 4444
+5 5000
+select x, y from t1 order by x, y;
+x y
+1 1000
+3 3001
+4 4000
+4 4444
+5 5000
+drop table t1;
+create table t1 (
+x int unsigned,
+y int unsigned,
+sys_trx_start SYS_DATATYPE as row start invisible,
+sys_trx_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_trx_start, sys_trx_end))
+with system versioning;
+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;
+x y
+8 8000
+9 9000
+1 1000
+2 2000
+3 3000
+4 4000
+5 5000
+6 6000
+7 7000
+8 8008
+9 9009
+select x, y from t1 order by x, y;
+x y
+1 1000
+2 2000
+3 3000
+4 4000
+5 5000
+6 6000
+7 7000
+8 8008
+9 9009
+select x, y from t2 for system_time all order by sys_trx_end, x, y;
+x y
+1 1010
+2 2010
+3 3010
+4 4010
+5 5010
+6 6010
+1 1011
+2 2012
+3 3013
+4 4014
+5 5015
+6 6016
+7 7010
+8 8010
+9 9010
+select x, y from t2 order by x, y;
+x y
+1 1011
+2 2012
+3 3013
+4 4014
+5 5015
+6 6016
+7 7010
+8 8010
+9 9010
+drop table t1;
+drop table t2;
+create table t1 (
+id bigint primary key without system versioning,
+name varchar(128),
+salary bigint without system versioning,
+sys_trx_start SYS_DATATYPE as row start invisible,
+sys_trx_end SYS_DATATYPE as row end invisible,
+period for system_time (sys_trx_start, sys_trx_end))
+with system versioning;
+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;
+A1 name
+1 Jerry
+select @tmp2 < sys_trx_start as A2, name from t2;
+A2 name
+1 Jerry
+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;
+B1 salary
+1 2500
+select @tmp2 = sys_trx_start as B2, salary from t2;
+B2 salary
+1 2500
+drop table t1;
+drop table t2;
+# Ensure FTS retains correct history
+create table t1 (
+x int, y text, fulltext (y),
+row_start SYS_DATATYPE as row start invisible,
+row_end SYS_DATATYPE 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;
+x left(y, 4) length(y) check_row(row_start, row_end)
+1 LONG 8192 HISTORICAL ROW
+2 LONG 8192 CURRENT ROW
+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;
+x left(y, 4) length(y) check_row(row_start, row_end)
+1 LONG 8192 HISTORICAL ROW
+2 LONG 8192 HISTORICAL ROW
+2 SHOR 5 CURRENT ROW
+drop tables t1;
+### 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);
+#
+# MDEV-14829 Assertion `0' failed in Protocol::end_statement upon concurrent UPDATE
+#
+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;
+pk a b
+1 NULL NULL
+connection default;
+update t1 set b = 'foo';
+connection con1;
+update t1 set a = 'bar';
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+disconnect con1;
+connection default;
+drop table t1;
+set @@innodb_lock_wait_timeout= @old_lock_wait_timeout;
+#
+# MDEV-19406 Assertion on updating view of join with versioned table
+#
+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;
+drop view v;
+drop table t1, t2;
+#
+# MDEV-20441 ER_CRASHED_ON_USAGE upon update on versioned Aria table
+#
+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;
+#
+# MDEV-21147 Assertion `marked_for_read()' upon UPDATE on versioned table via view
+#
+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;
+call sp;
+ERROR 42S22: Unknown column 'xx' in 'field list'
+call sp;
+ERROR 42S22: Unknown column 'xx' in 'field list'
+drop procedure sp;
+drop view v1;
+drop table t1;
+#
+# MDEV-21342 Assertion in set_ok_status() upon spatial field error on system-versioned table
+#
+create or replace table t1 (f point, key(f)) with system versioning engine=myisam;
+update t1 set f = null where f = 'foo';
+ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
+drop table t1;
+#
+# MDEV-22061 InnoDB: Assertion of missing row in sec index row_start upon REPLACE on a system-versioned table
+#
+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);
+drop table t1;
+#
+# MDEV-20661 Virtual fields are not recalculated on system fields value assignment
+#
+create table t1 (
+a int,
+row_start SYS_DATATYPE as row start invisible,
+row_end SYS_DATATYPE 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;
+drop table t1;
+#
+# MDEV-23446 UPDATE does not insert history row if the row is not changed
+#
+create table t1 (
+a int,
+row_start SYS_DATATYPE as row start invisible,
+row_end SYS_DATATYPE 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;
+a check_row(row_start, row_end)
+1 HISTORICAL ROW
+1 CURRENT ROW
+# 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;
+a check_row(row_start, row_end)
+1 HISTORICAL ROW
+1 CURRENT ROW
+select *, check_row(row_start, row_end) from t2 for system_time all order by row_end;
+a check_row(row_start, row_end)
+1 HISTORICAL ROW
+1 CURRENT ROW
+drop tables t1, t2, t3;
+#
+# MDEV-26778 row_start is not updated in current row for InnoDB
+#
+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;
+check_row_ts(row_start, row_end)
+CURRENT ROW
+drop table t1;
+#
+# MDEV-22973 Assertion in compare_record upon multi-update involving versioned table via view
+#
+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;
+drop view v;
+drop table t1, t2;
+#
+# MDEV-24522 Assertion `inited==NONE' fails upon UPDATE on versioned table with unique blob
+#
+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;
+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;
+drop tables t1, t2;
+#
+# MDEV-23100 ODKU of non-versioning column inserts history row
+#
+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;
+x y check_row_ts(row_start, row_end)
+1 3 CURRENT ROW
+drop table t1;
+#
+# MDEV-25644 UPDATE not working properly on transaction precise system versioned table
+#
+create or replace table t1 (nid int primary key, nstate int, ntype int) engine innodb;
+alter table t1 add
+row_start SYS_DATATYPE generated always as row start invisible,
+add row_end SYS_DATATYPE 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;
+nid nstate check_row(row_start, row_end)
+1 1 CURRENT ROW
+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;
+nid nstate check_row(row_start, row_end)
+1 1 HISTORICAL ROW
+1 1 CURRENT ROW
+# 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;
+select nid, nstate, check_row(row_start, row_end) from t1 for system_time all order by row_start, row_end;
+nid nstate check_row(row_start, row_end)
+1 1 HISTORICAL ROW
+1 1 HISTORICAL ROW
+1 3 CURRENT ROW
+commit;
+drop tables t1;
+# End of 10.4 tests
diff --git a/mysql-test/suite/versioning/r/view.result b/mysql-test/suite/versioning/r/view.result
new file mode 100644
index 00000000..0528edc4
--- /dev/null
+++ b/mysql-test/suite/versioning/r/view.result
@@ -0,0 +1,292 @@
+create or replace table t1 (x int) with system versioning;
+insert into t1 values (1);
+select now(6) into @t1;
+update t1 set x= 2;
+select now(6) into @t2;
+delete from t1;
+set @vt1= concat("create or replace view vt1 as select * from t1 for system_time as of timestamp '", @t1, "'");
+prepare stmt from @vt1;
+execute stmt;
+drop prepare stmt;
+set @vt2= concat("create or replace view vt2 as select *, row_end from t1 for system_time as of timestamp '", @t2, "'");
+prepare stmt from @vt2;
+execute stmt;
+drop prepare stmt;
+select * from t1;
+x
+create or replace view vt1 as select * from t1;
+show create view vt1;
+View Create View character_set_client collation_connection
+vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`x` AS `x` from `t1` latin1 latin1_swedish_ci
+drop view vt1;
+drop view vt2;
+create or replace view vt1 as select * from t1 for system_time all;
+select * from vt1;
+x
+2
+1
+prepare stmt from 'select * from vt1';
+execute stmt;
+x
+2
+1
+drop prepare stmt;
+set @str= concat('create or replace view vt1 as
+select * from t1 for system_time as of timestamp "', @t1, '"');
+prepare stmt from @str;
+execute stmt;
+drop prepare stmt;
+select * from t1 for system_time as of timestamp @t1;
+x
+1
+select * from vt1;
+x
+1
+insert into vt1 values (3);
+select * from t1;
+x
+3
+select * from vt1;
+x
+1
+create or replace table t1 (x int) with system versioning;
+insert into t1 values (1), (2);
+set @t1=now(6);
+delete from t1 where x=2;
+set @t2=now(6);
+delete from t1 where x=1;
+set @t3=now(6);
+set @tmp= concat("create or replace view vt1 as select * from t1 for system_time as of timestamp '", @t1, "'");
+prepare stmt from @tmp;
+execute stmt;
+drop prepare stmt;
+select * from vt1;
+x
+1
+2
+# VIEW with parameters [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;
+show create view vt1;
+View Create View character_set_client collation_connection
+vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`x` AS `c` from `t1` latin1 latin1_swedish_ci
+# 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;
+a b
+1 2
+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;
+a b
+# VIEW improvements [tempesta-tech/mariadb#183]
+create or replace table t3 (x int);
+create or replace view vt1 as select * from t1, t2, t3;
+show create view vt1;
+View Create View character_set_client collation_connection
+vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`a` AS `a`,`t2`.`b` AS `b`,`t3`.`x` AS `x` from ((`t1` join `t2`) join `t3`) latin1 latin1_swedish_ci
+create or replace view vt1 as select * from t3, t2, t1;
+show create view vt1;
+View Create View character_set_client collation_connection
+vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t3`.`x` AS `x`,`t2`.`b` AS `b`,`t1`.`a` AS `a` from ((`t3` join `t2`) join `t1`) latin1 latin1_swedish_ci
+create or replace view vt1 as select a, t2.row_end as endo from t3, t1, t2;
+show create view vt1;
+View Create View character_set_client collation_connection
+vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`a` AS `a`,`t2`.`row_end` AS `endo` from ((`t3` join `t1`) join `t2`) latin1 latin1_swedish_ci
+# VIEW over UNION [tempesta-tech/mariadb#269]
+create or replace view vt1 as select * from t1 union select * from t1;
+select * from vt1;
+a
+1
+# VIEW over UNION with non-versioned [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;
+a
+1
+#
+# MDEV-14689 crash on second PS execute
+#
+create or replace table t1 (a int);
+create or replace view v1 as select * from t1;
+create or replace table t2 (b int) with system versioning;
+prepare stmt from 'select a from v1 inner join t2 group by a order by a';
+execute stmt;
+a
+execute stmt;
+a
+drop view v1;
+drop tables t1, t2;
+#
+# MDEV-15146 SQLError[4122]: View is not system versioned
+#
+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;
+a
+select * from v1 for system_time as of @a;
+a
+1
+2
+show create view v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1` latin1 latin1_swedish_ci
+#
+# MDEV-15378 Valid query causes invalid view definition due to syntax limitation in FOR SYSTEM_TIME
+#
+create or replace table t1 (i int) with system versioning;
+select * from t1 for system_time as of now() - interval 6 second;
+i
+create or replace view v1 as select * from t1 for system_time as of date_sub(now(), interval 6 second);
+show create view v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`i` AS `i` from `t1` FOR SYSTEM_TIME AS OF TIMESTAMP current_timestamp() - interval 6 second latin1 latin1_swedish_ci
+drop view v1, vt1, vt12;
+drop tables t1, t3;
+#
+# MDEV-18727 improve DML operation of System Versioning
+#
+create or replace table t1 (
+x int,
+row_start SYS_DATATYPE as row start invisible,
+row_end SYS_DATATYPE 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;
+# update, delete
+update v1 set x= x + 1;
+select *, check_row(row_start, row_end) from t1 for system_time all order by x;
+x check_row(row_start, row_end)
+1 CURRENT ROW
+2 HISTORICAL ROW
+3 CURRENT ROW
+insert v1 values (4);
+select *, check_row(row_start, row_end) from t1 for system_time all order by x;
+x check_row(row_start, row_end)
+1 CURRENT ROW
+2 HISTORICAL ROW
+3 CURRENT ROW
+4 CURRENT ROW
+delete from v1 where x < 4;
+select *, check_row(row_start, row_end) from t1 for system_time all order by x;
+x check_row(row_start, row_end)
+1 CURRENT ROW
+2 HISTORICAL ROW
+3 HISTORICAL ROW
+4 CURRENT ROW
+# 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;
+x check_row(row_start, row_end)
+1 CURRENT ROW
+2 HISTORICAL ROW
+3 HISTORICAL ROW
+4 HISTORICAL ROW
+5 CURRENT ROW
+select *, check_row(row_start, row_end) from t2 for system_time all order by x;
+x check_row(row_start, row_end)
+1 CURRENT ROW
+2 HISTORICAL ROW
+3 CURRENT ROW
+# 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;
+x check_row(row_start, row_end)
+1 CURRENT ROW
+2 HISTORICAL ROW
+3 HISTORICAL ROW
+4 HISTORICAL ROW
+5 HISTORICAL ROW
+select *, check_row(row_start, row_end) from t2 for system_time all order by x;
+x check_row(row_start, row_end)
+1 CURRENT ROW
+2 HISTORICAL ROW
+3 HISTORICAL ROW
+# replace
+create or replace table t1 (
+x int primary key, y int,
+row_start SYS_DATATYPE as row start invisible,
+row_end SYS_DATATYPE 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);
+# 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;
+x y check_row(row_start, row_end)
+1 0 HISTORICAL ROW
+1 1 CURRENT ROW
+2 0 HISTORICAL ROW
+2 1 CURRENT ROW
+3 1 CURRENT ROW
+# 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;
+x y check_row(row_start, row_end)
+0 1 CURRENT ROW
+1 0 HISTORICAL ROW
+1 1 HISTORICAL ROW
+2 0 HISTORICAL ROW
+2 1 CURRENT ROW
+3 1 CURRENT ROW
+drop view v1, v2;
+drop tables t1, t2;
+#
+# MDEV-21146 Assertion `m_lock_type == 2' in handler::ha_drop_table upon LOAD DATA
+#
+create table t1 (a int);
+create view v1 as select * from t1;
+create or replace table t1 (b int) with system versioning;
+load data infile 'xx' into table v1;
+ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+drop view v1;
+drop table t1;
+#
+# MDEV-21155 Assertion with versioned table upon DELETE from view of view after replacing first view
+#
+create table t1 (a int);
+insert into t1 values (1);
+create table t2 (
+b int,
+row_start SYS_DATATYPE as row start invisible,
+row_end SYS_DATATYPE 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;
+a
+1
+select *, check_row(row_start, row_end) from t2 for system_time all;
+b check_row(row_start, row_end)
+2 HISTORICAL ROW
+drop view v2;
+drop view v1;
+drop table t1, t2;
+#
+# MDEV-23779 Error upon querying the view, that selecting from versioned table with partitions
+#
+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;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`i` AS `i` from `t1` PARTITION (`pn`) latin1 latin1_swedish_ci
+drop view v1;
+drop table t1;
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
diff --git a/mysql-test/suite/versioning/wait_system_clock.inc b/mysql-test/suite/versioning/wait_system_clock.inc
new file mode 100644
index 00000000..21bbe7ae
--- /dev/null
+++ b/mysql-test/suite/versioning/wait_system_clock.inc
@@ -0,0 +1,10 @@
+#
+# windows has a rather low-resolution system clock
+# wait until the event from the past will actually be in the past
+#
+if (`select @@version_compile_os in ("win32","win64","windows")`)
+{
+ let $_past=`select max(row_start) from t1`;
+ --let $wait_condition=select TIMESTAMP'$_past' < sysdate(6)
+ --source include/wait_condition.inc
+}