summaryrefslogtreecommitdiffstats
path: root/mysql-test/suite/period
diff options
context:
space:
mode:
Diffstat (limited to 'mysql-test/suite/period')
-rw-r--r--mysql-test/suite/period/create_triggers.inc38
-rw-r--r--mysql-test/suite/period/engines.combinations7
-rw-r--r--mysql-test/suite/period/engines.inc3
-rw-r--r--mysql-test/suite/period/r/alter.result224
-rw-r--r--mysql-test/suite/period/r/create.result113
-rw-r--r--mysql-test/suite/period/r/delete,myisam.rdiff18
-rw-r--r--mysql-test/suite/period/r/delete.result423
-rw-r--r--mysql-test/suite/period/r/long_unique.result17
-rw-r--r--mysql-test/suite/period/r/overlaps.result451
-rw-r--r--mysql-test/suite/period/r/update.result309
-rw-r--r--mysql-test/suite/period/r/versioning.result90
-rw-r--r--mysql-test/suite/period/t/alter.test192
-rw-r--r--mysql-test/suite/period/t/create.test101
-rw-r--r--mysql-test/suite/period/t/delete.test270
-rw-r--r--mysql-test/suite/period/t/long_unique.test23
-rw-r--r--mysql-test/suite/period/t/overlaps.test460
-rw-r--r--mysql-test/suite/period/t/update.test207
-rw-r--r--mysql-test/suite/period/t/versioning.test61
18 files changed, 3007 insertions, 0 deletions
diff --git a/mysql-test/suite/period/create_triggers.inc b/mysql-test/suite/period/create_triggers.inc
new file mode 100644
index 00000000..1126ae08
--- /dev/null
+++ b/mysql-test/suite/period/create_triggers.inc
@@ -0,0 +1,38 @@
+create or replace table log_tbl(id int auto_increment primary key, log text) engine=myisam;
+
+create or replace procedure log(s text)
+ insert into log_tbl(log) values(s);
+
+if (!$trig_table)
+{
+ die "No $trig_table specified";
+}
+
+if (!$trig_cols)
+{
+ let $trig_cols= s, e;
+}
+
+let $old_trig_args= `select REGEXP_REPLACE('$trig_cols', '([[:word:]]+)',
+ 'old.\\\\\\\\1')`;
+let $old_trig_args= `select REPLACE('$old_trig_args', ',', ', ", ", ')`;
+let $new_trig_args= `select REGEXP_REPLACE('$trig_cols', '([[:word:]]+)',
+ 'new.\\\\\\\\1')`;
+let $new_trig_args= `select REPLACE('$new_trig_args', ',', ', ", ", ')`;
+
+eval create trigger tr1upd_$trig_table before update on $trig_table
+ for each row call log(CONCAT('>UPD: ', $old_trig_args, ' -> ', $new_trig_args));
+eval create trigger tr2upd_$trig_table after update on $trig_table
+ for each row call log(CONCAT('<UPD: ', $old_trig_args, ' -> ', $new_trig_args));
+eval create trigger tr1del_$trig_table before delete on $trig_table
+ for each row call log(CONCAT('>DEL: ', $old_trig_args));
+eval create trigger tr2del_$trig_table after delete on $trig_table
+ for each row call log(CONCAT('<DEL: ', $old_trig_args));
+eval create trigger tr1ins_$trig_table before insert on $trig_table
+ for each row call log(CONCAT('>INS: ', $new_trig_args));
+eval create trigger tr2ins_$trig_table after insert on $trig_table
+ for each row call log(CONCAT('<INS: ', $new_trig_args));
+
+
+let trig_cols= 0;
+let trig_table= 0;
diff --git a/mysql-test/suite/period/engines.combinations b/mysql-test/suite/period/engines.combinations
new file mode 100644
index 00000000..62bf838d
--- /dev/null
+++ b/mysql-test/suite/period/engines.combinations
@@ -0,0 +1,7 @@
+[innodb]
+innodb
+default-storage-engine=innodb
+
+[myisam]
+innodb
+default-storage-engine=myisam
diff --git a/mysql-test/suite/period/engines.inc b/mysql-test/suite/period/engines.inc
new file mode 100644
index 00000000..9a52c7d0
--- /dev/null
+++ b/mysql-test/suite/period/engines.inc
@@ -0,0 +1,3 @@
+#
+# see engines.combinations
+#
diff --git a/mysql-test/suite/period/r/alter.result b/mysql-test/suite/period/r/alter.result
new file mode 100644
index 00000000..9eb4555c
--- /dev/null
+++ b/mysql-test/suite/period/r/alter.result
@@ -0,0 +1,224 @@
+set @s= '1992-01-01';
+set @e= '1999-12-31';
+create table t (s date, e date);
+# period start/end columns are implicit NOT NULL
+alter table t add period for a(s, e);
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `s` date NOT NULL,
+ `e` date NOT NULL,
+ PERIOD FOR `a` (`s`, `e`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+create or replace table t (s date, e date);
+alter table t change s s date, add period for a(s, e);
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `s` date NOT NULL,
+ `e` date NOT NULL,
+ PERIOD FOR `a` (`s`, `e`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+alter table t add id int;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `s` date NOT NULL,
+ `e` date NOT NULL,
+ `id` int(11) DEFAULT NULL,
+ PERIOD FOR `a` (`s`, `e`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+alter table t drop id;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `s` date NOT NULL,
+ `e` date NOT NULL,
+ PERIOD FOR `a` (`s`, `e`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert t values(@e, @s);
+ERROR 23000: CONSTRAINT `a` failed for `test`.`t`
+alter table t drop constraint a;
+ERROR HY000: Can't DROP CONSTRAINT `a`. Use DROP PERIOD `a` for this
+# no-op
+alter table t drop period if exists for b;
+Warnings:
+Note 1091 Can't DROP PERIOD `b`; check that it exists
+# no-op
+alter table t add period if not exists for a(e, s);
+Warnings:
+Note 1060 Duplicate column name 'a'
+alter table t drop period if exists for a;
+# no-op
+alter table t drop period if exists for a;
+Warnings:
+Note 1091 Can't DROP PERIOD `a`; check that it exists
+alter table t add period for a(s, e), add period if not exists for a(e, s);
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `s` date NOT NULL,
+ `e` date NOT NULL,
+ PERIOD FOR `a` (`s`, `e`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+alter table t drop period for a;
+# Constraint is dropped
+insert t values(@e, @s);
+alter table t drop period for a;
+ERROR 42000: Can't DROP PERIOD `a`; check that it exists
+alter table t add period for a(s, e), drop period for a;
+ERROR 42000: Can't DROP PERIOD `a`; check that it exists
+truncate t;
+alter table t add period for a(s, e);
+insert t values(@e, @s);
+ERROR 23000: CONSTRAINT `a` failed for `test`.`t`
+alter table t add period for a(s, e), drop period for a;
+insert t values(@e, @s);
+ERROR 23000: CONSTRAINT `a` failed for `test`.`t`
+alter table t add s1 date not null, add period for b(s1, e), drop period for a;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `s` date NOT NULL,
+ `e` date NOT NULL,
+ `s1` date NOT NULL,
+ PERIOD FOR `b` (`s1`, `e`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert t(s, s1, e) values(@e, @s, @e);
+insert t(s, s1, e) values(@e, @e, @s);
+ERROR 23000: CONSTRAINT `b` failed for `test`.`t`
+create table t1 like t;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `s` date NOT NULL,
+ `e` date NOT NULL,
+ `s1` date NOT NULL,
+ PERIOD FOR `b` (`s1`, `e`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+drop table t1;
+create table t2 (period for b(s,e)) select * from t;
+ERROR 23000: CONSTRAINT `b` failed for `test`.`t2`
+create table t2 (period for b(s1,e)) select * from t;
+drop table t2;
+# SQL16 11.27 <add table period definition>, Syntax Rules, 5)g)
+# The declared type of BC1 shall be either DATE or a timestamp type
+# and shall be equivalent to the declared type of BC2.
+create or replace table t (s timestamp not null, e timestamp(6) not null);
+alter table t add period for a(s, e);
+ERROR HY000: Fields of PERIOD FOR `a` have different types
+# SQL16 11.27 <add table period definition>, Syntax Rules, 5)c)
+# No column of T shall have a column name that is equivalent to ATPN.
+create or replace table t (a int, s date, e date);
+alter table t add period for a(s, e);
+ERROR 42S21: Duplicate column name 'a'
+# SQL16 11.27 <add table period definition>, Syntax Rules, 5)i)
+# Neither BC1 nor BC2 shall be an identity column, a generated column,
+# a system-time period start column, or a system-time period end column.
+create or replace table t (id int primary key,
+s date,
+e date generated always as (s+1));
+alter table t add period for a(s, e);
+ERROR HY000: Period field `e` cannot be GENERATED ALWAYS AS
+create or replace table t (id int primary key,
+s date,
+e date as (s+1) VIRTUAL);
+alter table t add period for a(s, e);
+ERROR HY000: Period field `e` cannot be GENERATED ALWAYS AS
+create or replace table t (id int primary key, s timestamp(6), e timestamp(6),
+st timestamp(6) as row start,
+en timestamp(6) as row end,
+period for system_time (st, en)) with system versioning;
+alter table t add period for a(s, en);
+ERROR HY000: Period field `en` cannot be GENERATED ALWAYS AS
+# SQL16 11.27 <add table period definition>, Syntax Rules, 5)b)
+# The table descriptor of T shall not include a period descriptor other
+# than a system-time period descriptor.
+alter table t add period for a(s, e);
+alter table t add period for b(s, e);
+ERROR HY000: Cannot specify more than one application-time period
+# SQL16, Part 2, 11.3 <table definition>, Syntax Rules, 2)e)v)2)B)
+# Let S be the schema identified by the explicit or implicit
+# <schema name> of TN. Let IDCN be an implementation-dependent
+# <constraint name> that is not equivalent to the <constraint name> of
+# any table constraint descriptor included in S. The following
+# <table constraint definition> is implicit:
+# CONSTRAINT IDCN CHECK ( CN1 < CN2 )
+#
+# Due to the above standard limitation, the constraint name can't always
+# match the period name. So it matches when possible; and when not, it
+# is unique not taken name prefixed with period name.
+create or replace table t (x int, s date, e date,
+period for mytime(s, e));
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `x` int(11) DEFAULT NULL,
+ `s` date NOT NULL,
+ `e` date NOT NULL,
+ PERIOD FOR `mytime` (`s`, `e`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+alter table t add constraint mytime check (x > 1);
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `x` int(11) DEFAULT NULL,
+ `s` date NOT NULL,
+ `e` date NOT NULL,
+ PERIOD FOR `mytime` (`s`, `e`),
+ CONSTRAINT `mytime` CHECK (`x` > 1)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert t values (2, @e, @s);
+ERROR 23000: CONSTRAINT `mytime_1` failed for `test`.`t`
+alter table t add constraint mytime_1 check (x > 2);
+insert t values (3, @e, @s);
+ERROR 23000: CONSTRAINT `mytime_2` failed for `test`.`t`
+drop table t;
+#
+# MDEV-20494 ER_NOT_FORM_FILE or assertion upon adding partition to period table
+#
+create table t1 (f date, t date, period for app(f,t)) with system versioning partition by system_time ( partition p1 history, partition pn current );
+lock table t1 write;
+alter table t1 add partition (partition p2 history);
+Warnings:
+Warning 4115 Maybe missing parameters: no rotation condition for multiple HISTORY partitions.
+unlock tables;
+create or replace table t1 (x int, s date, e date, period for app(s,e));
+insert into t1 values(1, '2020-03-01', '2020-03-02');
+insert into t1 values(1, '2020-03-01', '2020-03-02');
+alter table t1 add primary key(x, s, e);
+ERROR 23000: Duplicate entry '1-2020-03-01-2020-03-02' for key 'PRIMARY'
+alter table t1 add system versioning;
+drop table t1;
+#
+# MDEV-18873 Server crashes in Compare_identifiers::operator or in
+# my_strcasecmp_utf8 upon ADD PERIOD IF NOT EXISTS with empty name
+#
+alter table t add period if not exists for `` (s,e);
+ERROR 42000: Incorrect column name ''
+create table t(s DATE, e DATE);
+alter table t add period if not exists for `` (s,e);
+ERROR 42000: Incorrect column name ''
+alter table t add period if not exists for ` ` (s,e);
+ERROR 42000: Incorrect column name ' '
+create table t2 (period for `` (s,e)) select * from t;
+ERROR 42000: Incorrect column name ''
+drop table t;
+#
+# MDEV-21941 RENAME doesn't work for system time or period fields
+#
+create or replace table t1 (
+a int, s date, e date,
+period for mytime(s, e));
+alter table t1 rename column s to x;
+alter table t1 rename column e to y;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `x` date NOT NULL,
+ `y` date NOT NULL,
+ PERIOD FOR `mytime` (`x`, `y`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+drop table t1;
+# End of 10.5 tests
diff --git a/mysql-test/suite/period/r/create.result b/mysql-test/suite/period/r/create.result
new file mode 100644
index 00000000..ad9985d7
--- /dev/null
+++ b/mysql-test/suite/period/r/create.result
@@ -0,0 +1,113 @@
+create table t (id int primary key, s date, e date, period for mytime(s,e));
+# CONSTRAINT CHECK (s < e) is added implicitly, and shouldn't be shown
+# this is important for correct command-based replication
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `id` int(11) NOT NULL,
+ `s` date NOT NULL,
+ `e` date NOT NULL,
+ PERIOD FOR `mytime` (`s`, `e`),
+ PRIMARY KEY (`id`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+create or replace table t (id int primary key, s timestamp(6), e timestamp(6),
+period for mytime(s,e));
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `id` int(11) NOT NULL,
+ `s` timestamp(6) NOT NULL,
+ `e` timestamp(6) NOT NULL,
+ PERIOD FOR `mytime` (`s`, `e`),
+ PRIMARY KEY (`id`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+# SQL16, Part 2, 11.3 <table definition>, Syntax Rules, 2)a)
+# 2) If a <table period definition> TPD is specified, then:
+# a) <table scope> shall not be specified.
+create or replace temporary table t (s date, e date, period for mytime(s,e));
+ERROR HY000: Application-time period table cannot be temporary
+# SQL16, Part 2, 11.3 <table definition>, Syntax Rules, 2)e)iii)
+# The <data type or domain name> contained in CD1 is either DATE or a
+# timestamp type and it is equivalent to the <data type or domain name>
+# contained in CD2.
+create or replace table t (id int primary key, s datetime, e date,
+period for mytime(s,e));
+ERROR HY000: Fields of PERIOD FOR `mytime` have different types
+create or replace table t (s timestamp(2), e timestamp(6),
+period for mytime(s,e));
+ERROR HY000: Fields of PERIOD FOR `mytime` have different types
+create or replace table t (id int primary key, s int, e date,
+period for mytime(s,e));
+ERROR 42000: Incorrect column specifier for column 's'
+create or replace table t (id int primary key, s time, e time,
+period for mytime(s,e));
+ERROR 42000: Incorrect column specifier for column 's'
+create or replace table t (id int primary key, s date, e date,
+period for mytime(s,x));
+ERROR 42S22: Unknown column 'x' in 'mytime'
+# MDEV-18842: Unfortunate error message when the same column is used
+# for application period start and end
+create or replace table t (s date, t date, period for apt(s,s));
+ERROR 42000: Column 's' specified twice
+create or replace table t (id int primary key, s date, e date,
+period for mytime(s,e),
+period for mytime2(s,e));
+ERROR HY000: Cannot specify more than one application-time period
+# SQL16, Part 2, 11.3 <table definition>, Syntax Rules, 2)d)
+# No <column name> in any <column definition> shall be equivalent to PN.
+create or replace table t (mytime int, s date, e date,
+period for mytime(s,e));
+ERROR 42S21: Duplicate column name 'mytime'
+# SQL16, Part 2, 11.3 <table definition>, Syntax Rules, 2)e)v)2)A)
+# Neither CD1 nor CD2 shall contain an <identity column specification>, a
+# <generation clause>, a <system time period start column specification>,
+# or a <system time period end column specification>.
+create or replace table t (id int primary key,
+s date,
+e date generated always as (s+1),
+period for mytime(s,e));
+ERROR HY000: Period field `e` cannot be GENERATED ALWAYS AS
+create or replace table t (id int primary key,
+s date,
+e date as (s+1) VIRTUAL,
+period for mytime(s,e));
+ERROR HY000: Period field `e` cannot be GENERATED ALWAYS AS
+create or replace table t (id int primary key, s timestamp(6), e timestamp(6),
+st timestamp(6) as row start,
+en timestamp(6) as row end,
+period for system_time (st, en),
+period for mytime(st,e)) with system versioning;
+ERROR HY000: Period field `st` cannot be GENERATED ALWAYS AS
+# SQL16, Part 2, 11.3 <table definition>, Syntax Rules, 2)
+# Let IDCN be an implementation-dependent <constraint name> that is not
+# equivalent to the <constraint name> of any table constraint descriptor
+# included in S.
+create or replace table t (x int, s date, e date,
+period for mytime(s, e),
+constraint mytime check (x > 1));
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `x` int(11) DEFAULT NULL,
+ `s` date NOT NULL,
+ `e` date NOT NULL,
+ PERIOD FOR `mytime` (`s`, `e`),
+ CONSTRAINT `mytime` CHECK (`x` > 1)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert t values (2, '2001-01-01', '2001-01-01');
+ERROR 23000: CONSTRAINT `mytime_1` failed for `test`.`t`
+show status like "Feature_application_time_periods";
+Variable_name Value
+Feature_application_time_periods 6
+drop table t;
+# MDEV-29387: Period name with more than 32 symbols crashes the server
+#
+# test 34 symbols
+create table t2 (s date, e date,
+period for `abcd123456789012345678901234567890` (s,e));
+drop table t2;
+# test 64 symbols
+create table t2 (s date, e date, period for
+`abcd123456789012345678901234567890123456789012345678901234567890`
+ (s,e));
+drop table t2;
diff --git a/mysql-test/suite/period/r/delete,myisam.rdiff b/mysql-test/suite/period/r/delete,myisam.rdiff
new file mode 100644
index 00000000..78fb972b
--- /dev/null
+++ b/mysql-test/suite/period/r/delete,myisam.rdiff
@@ -0,0 +1,18 @@
+--- suite/period/r/delete.result 2019-02-16 11:14:23.511258191 +0100
++++ suite/period/r/delete.reject 2019-02-16 11:14:32.869258690 +0100
+@@ -250,7 +250,6 @@
+ ERROR 22003: Out of range value for column 'id' at row 1
+ select * from t;
+ id s e
+-127 1999-01-01 2018-12-12
+ # same for trigger case
+ create or replace table log_tbl(id int auto_increment primary key, log text) engine=myisam;
+ create or replace procedure log(s text)
+@@ -277,7 +276,6 @@
+ ERROR 22003: Out of range value for column 'id' at row 1
+ select * from t;
+ id s e
+-127 1999-01-01 2018-12-12
+ select * from log_tbl order by id;
+ id log
+ 1 >DEL: 1999-01-01, 2018-12-12
diff --git a/mysql-test/suite/period/r/delete.result b/mysql-test/suite/period/r/delete.result
new file mode 100644
index 00000000..2b0a97e0
--- /dev/null
+++ b/mysql-test/suite/period/r/delete.result
@@ -0,0 +1,423 @@
+create table t (id int, s date, e date, period for apptime(s,e));
+insert into t values(1, '1999-01-01', '2018-12-12');
+insert into t values(1, '1999-01-01', '2017-01-01');
+insert into t values(1, '2017-01-01', '2019-01-01');
+insert into t values(2, '1998-01-01', '2018-12-12');
+insert into t values(3, '1997-01-01', '2015-01-01');
+insert into t values(4, '2016-01-01', '2020-01-01');
+insert into t values(5, '2010-01-01', '2015-01-01');
+create or replace table t1 (id int, s date, e date, period for apptime(s,e));
+insert t1 select * from t;
+create or replace table t2 (id int, s date, e date, period for apptime(s,e));
+insert t2 select * from t;
+create or replace table t3 (id int, s date, e date, period for apptime(s,e));
+insert t3 select * from t;
+create or replace table log_tbl(id int auto_increment primary key, log text) engine=myisam;
+create or replace procedure log(s text)
+insert into log_tbl(log) values(s);
+create trigger tr1upd_t1 before update on t1
+for each row call log(CONCAT('>UPD: ', old.id, ", ", old.s, ", ", old.e, ' -> ', new.id, ", ", new.s, ", ", new.e));
+create trigger tr2upd_t1 after update on t1
+for each row call log(CONCAT('<UPD: ', old.id, ", ", old.s, ", ", old.e, ' -> ', new.id, ", ", new.s, ", ", new.e));
+create trigger tr1del_t1 before delete on t1
+for each row call log(CONCAT('>DEL: ', old.id, ", ", old.s, ", ", old.e));
+create trigger tr2del_t1 after delete on t1
+for each row call log(CONCAT('<DEL: ', old.id, ", ", old.s, ", ", old.e));
+create trigger tr1ins_t1 before insert on t1
+for each row call log(CONCAT('>INS: ', new.id, ", ", new.s, ", ", new.e));
+create trigger tr2ins_t1 after insert on t1
+for each row call log(CONCAT('<INS: ', new.id, ", ", new.s, ", ", new.e));
+delete from t for portion of apptime from '2000-01-01' to '2018-01-01';
+delete from t1 for portion of APPTIME from '2000-01-01' to '2018-01-01';
+select * from t;
+id s e
+1 1999-01-01 2000-01-01
+1 1999-01-01 2000-01-01
+1 2018-01-01 2018-12-12
+1 2018-01-01 2019-01-01
+2 1998-01-01 2000-01-01
+2 2018-01-01 2018-12-12
+3 1997-01-01 2000-01-01
+4 2018-01-01 2020-01-01
+select * from t1;
+id s e
+1 1999-01-01 2000-01-01
+1 1999-01-01 2000-01-01
+1 2018-01-01 2018-12-12
+1 2018-01-01 2019-01-01
+2 1998-01-01 2000-01-01
+2 2018-01-01 2018-12-12
+3 1997-01-01 2000-01-01
+4 2018-01-01 2020-01-01
+select * from log_tbl order by id;
+id log
+1 >DEL: 1, 1999-01-01, 2018-12-12
+2 >INS: 1, 1999-01-01, 2000-01-01
+3 <INS: 1, 1999-01-01, 2000-01-01
+4 >INS: 1, 2018-01-01, 2018-12-12
+5 <INS: 1, 2018-01-01, 2018-12-12
+6 <DEL: 1, 1999-01-01, 2018-12-12
+7 >DEL: 1, 1999-01-01, 2017-01-01
+8 >INS: 1, 1999-01-01, 2000-01-01
+9 <INS: 1, 1999-01-01, 2000-01-01
+10 <DEL: 1, 1999-01-01, 2017-01-01
+11 >DEL: 1, 2017-01-01, 2019-01-01
+12 >INS: 1, 2018-01-01, 2019-01-01
+13 <INS: 1, 2018-01-01, 2019-01-01
+14 <DEL: 1, 2017-01-01, 2019-01-01
+15 >DEL: 2, 1998-01-01, 2018-12-12
+16 >INS: 2, 1998-01-01, 2000-01-01
+17 <INS: 2, 1998-01-01, 2000-01-01
+18 >INS: 2, 2018-01-01, 2018-12-12
+19 <INS: 2, 2018-01-01, 2018-12-12
+20 <DEL: 2, 1998-01-01, 2018-12-12
+21 >DEL: 3, 1997-01-01, 2015-01-01
+22 >INS: 3, 1997-01-01, 2000-01-01
+23 <INS: 3, 1997-01-01, 2000-01-01
+24 <DEL: 3, 1997-01-01, 2015-01-01
+25 >DEL: 4, 2016-01-01, 2020-01-01
+26 >INS: 4, 2018-01-01, 2020-01-01
+27 <INS: 4, 2018-01-01, 2020-01-01
+28 <DEL: 4, 2016-01-01, 2020-01-01
+29 >DEL: 5, 2010-01-01, 2015-01-01
+30 <DEL: 5, 2010-01-01, 2015-01-01
+# INSERT trigger only also works
+create or replace table log_tbl(id int auto_increment primary key, log text) engine=myisam;
+create or replace procedure log(s text)
+insert into log_tbl(log) values(s);
+create trigger tr1upd_t2 before update on t2
+for each row call log(CONCAT('>UPD: ', old.id, ", ", old.s, ", ", old.e, ' -> ', new.id, ", ", new.s, ", ", new.e));
+create trigger tr2upd_t2 after update on t2
+for each row call log(CONCAT('<UPD: ', old.id, ", ", old.s, ", ", old.e, ' -> ', new.id, ", ", new.s, ", ", new.e));
+create trigger tr1del_t2 before delete on t2
+for each row call log(CONCAT('>DEL: ', old.id, ", ", old.s, ", ", old.e));
+create trigger tr2del_t2 after delete on t2
+for each row call log(CONCAT('<DEL: ', old.id, ", ", old.s, ", ", old.e));
+create trigger tr1ins_t2 before insert on t2
+for each row call log(CONCAT('>INS: ', new.id, ", ", new.s, ", ", new.e));
+create trigger tr2ins_t2 after insert on t2
+for each row call log(CONCAT('<INS: ', new.id, ", ", new.s, ", ", new.e));
+drop trigger tr1del_t2;
+drop trigger tr2del_t2;
+delete from t2 for portion of APPTIME from '2000-01-01' to '2018-01-01';
+select * from log_tbl order by id;
+id log
+1 >INS: 1, 1999-01-01, 2000-01-01
+2 <INS: 1, 1999-01-01, 2000-01-01
+3 >INS: 1, 2018-01-01, 2018-12-12
+4 <INS: 1, 2018-01-01, 2018-12-12
+5 >INS: 1, 1999-01-01, 2000-01-01
+6 <INS: 1, 1999-01-01, 2000-01-01
+7 >INS: 1, 2018-01-01, 2019-01-01
+8 <INS: 1, 2018-01-01, 2019-01-01
+9 >INS: 2, 1998-01-01, 2000-01-01
+10 <INS: 2, 1998-01-01, 2000-01-01
+11 >INS: 2, 2018-01-01, 2018-12-12
+12 <INS: 2, 2018-01-01, 2018-12-12
+13 >INS: 3, 1997-01-01, 2000-01-01
+14 <INS: 3, 1997-01-01, 2000-01-01
+15 >INS: 4, 2018-01-01, 2020-01-01
+16 <INS: 4, 2018-01-01, 2020-01-01
+# removing BEFORE INSERT trigger enables internal substitution
+# DELETE+INSERT -> UPDATE, but without any side effects.
+# The optimization is disabled for non-transactional engines
+create or replace table log_tbl(id int auto_increment primary key, log text) engine=myisam;
+create or replace procedure log(s text)
+insert into log_tbl(log) values(s);
+create trigger tr1upd_t3 before update on t3
+for each row call log(CONCAT('>UPD: ', old.s, ", ", old.e, ' -> ', new.s, ", ", new.e));
+create trigger tr2upd_t3 after update on t3
+for each row call log(CONCAT('<UPD: ', old.s, ", ", old.e, ' -> ', new.s, ", ", new.e));
+create trigger tr1del_t3 before delete on t3
+for each row call log(CONCAT('>DEL: ', old.s, ", ", old.e));
+create trigger tr2del_t3 after delete on t3
+for each row call log(CONCAT('<DEL: ', old.s, ", ", old.e));
+create trigger tr1ins_t3 before insert on t3
+for each row call log(CONCAT('>INS: ', new.s, ", ", new.e));
+create trigger tr2ins_t3 after insert on t3
+for each row call log(CONCAT('<INS: ', new.s, ", ", new.e));
+drop trigger tr1ins_t3;
+delete from t3 for portion of APPTIME from '2000-01-01' to '2018-01-01';
+select * from log_tbl order by id;
+id log
+1 >DEL: 1999-01-01, 2018-12-12
+2 <INS: 1999-01-01, 2000-01-01
+3 <INS: 2018-01-01, 2018-12-12
+4 <DEL: 1999-01-01, 2018-12-12
+5 >DEL: 1999-01-01, 2017-01-01
+6 <INS: 1999-01-01, 2000-01-01
+7 <DEL: 1999-01-01, 2017-01-01
+8 >DEL: 2017-01-01, 2019-01-01
+9 <INS: 2018-01-01, 2019-01-01
+10 <DEL: 2017-01-01, 2019-01-01
+11 >DEL: 1998-01-01, 2018-12-12
+12 <INS: 1998-01-01, 2000-01-01
+13 <INS: 2018-01-01, 2018-12-12
+14 <DEL: 1998-01-01, 2018-12-12
+15 >DEL: 1997-01-01, 2015-01-01
+16 <INS: 1997-01-01, 2000-01-01
+17 <DEL: 1997-01-01, 2015-01-01
+18 >DEL: 2016-01-01, 2020-01-01
+19 <INS: 2018-01-01, 2020-01-01
+20 <DEL: 2016-01-01, 2020-01-01
+21 >DEL: 2010-01-01, 2015-01-01
+22 <DEL: 2010-01-01, 2015-01-01
+# multi-table DELETE is not possible
+delete t, t1 from t1, t for portion of apptime from '2000-01-01' to '2018-01-01';
+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 'for portion of apptime from '2000-01-01' to '2018-01-01'' at line 1
+delete t for portion of apptime from '2000-01-01' to '2018-01-01', t1 from t, t1;
+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 'for portion of apptime from '2000-01-01' to '2018-01-01', t1 from t, t1' at line 1
+# Here another check fails before parsing ends
+delete t, t1 from t for portion of apptime from '2000-01-01' to '2018-01-01', t1;
+ERROR 42S02: Unknown table 't1' in MULTI DELETE
+delete history from t2 for portion of apptime from '2000-01-01' to '2018-01-01';
+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 'for portion of apptime from '2000-01-01' to '2018-01-01'' at line 1
+delete from t for portion of othertime from '2000-01-01' to '2018-01-01';
+ERROR HY000: Period `othertime` is not found in table
+delete from t for portion of system_time from '2000-01-01' to '2018-01-01';
+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 'of system_time from '2000-01-01' to '2018-01-01'' at line 1
+# MDEV-22596 DELETE FOR PORTION does not obey
+# "Expression in FOR PORTION OF must be constant" limitation, data can be easily lost
+delete from t for portion of apptime from s to e;
+ERROR HY000: Expression in FOR PORTION OF must be constant
+create or replace table t (id int, str text, s date, e date,
+period for apptime(s,e));
+insert into t values(1, 'data', '1999-01-01', '2018-12-12');
+insert into t values(1, 'other data', '1999-01-01', '2018-12-12');
+insert into t values(1, 'deleted', '2000-01-01', '2018-01-01');
+delete from t for portion of apptime from '2000-01-01' to '2018-01-01';
+show warnings;
+Level Code Message
+select * from t;
+id str s e
+1 data 1999-01-01 2000-01-01
+1 data 2018-01-01 2018-12-12
+1 other data 1999-01-01 2000-01-01
+1 other data 2018-01-01 2018-12-12
+drop table t1;
+# SQL16, Part 2, 15.7 <Effect of deleting rows from base tables>,
+# General rules, 8)b)i)
+# If the column descriptor that corresponds to the i-th field of BR
+# describes an identity column, a generated column, a system-time period
+# start column, or a system-time period end column, then let V i be
+# DEFAULT.
+# auto_increment field is updated
+create or replace table t (id int primary key auto_increment, s date, e date,
+period for apptime(s, e));
+insert into t values (default, '1999-01-01', '2018-12-12');
+select * from t;
+id s e
+1 1999-01-01 2018-12-12
+delete from t for portion of apptime from '2000-01-01' to '2018-01-01';
+select * from t;
+id s e
+2 1999-01-01 2000-01-01
+3 2018-01-01 2018-12-12
+truncate t;
+# same for trigger case
+insert into t values (default, '1999-01-01', '2018-12-12');
+create or replace table log_tbl(id int auto_increment primary key, log text) engine=myisam;
+create or replace procedure log(s text)
+insert into log_tbl(log) values(s);
+create trigger tr1upd_t before update on t
+for each row call log(CONCAT('>UPD: ', old.s, ", ", old.e, ' -> ', new.s, ", ", new.e));
+create trigger tr2upd_t after update on t
+for each row call log(CONCAT('<UPD: ', old.s, ", ", old.e, ' -> ', new.s, ", ", new.e));
+create trigger tr1del_t before delete on t
+for each row call log(CONCAT('>DEL: ', old.s, ", ", old.e));
+create trigger tr2del_t after delete on t
+for each row call log(CONCAT('<DEL: ', old.s, ", ", old.e));
+create trigger tr1ins_t before insert on t
+for each row call log(CONCAT('>INS: ', new.s, ", ", new.e));
+create trigger tr2ins_t after insert on t
+for each row call log(CONCAT('<INS: ', new.s, ", ", new.e));
+delete from t for portion of apptime from '2000-01-01' to '2018-01-01';
+select * from t;
+id s e
+2 1999-01-01 2000-01-01
+3 2018-01-01 2018-12-12
+select * from log_tbl order by id;
+id log
+1 >DEL: 1999-01-01, 2018-12-12
+2 >INS: 1999-01-01, 2000-01-01
+3 <INS: 1999-01-01, 2000-01-01
+4 >INS: 2018-01-01, 2018-12-12
+5 <INS: 2018-01-01, 2018-12-12
+6 <DEL: 1999-01-01, 2018-12-12
+# generated columns are updated
+create or replace table t (s date, e date,
+xs date as (s) stored, xe date as (e) stored,
+period for apptime(s, e));
+insert into t values('1999-01-01', '2018-12-12', default, default);
+select * from t;
+s e xs xe
+1999-01-01 2018-12-12 1999-01-01 2018-12-12
+delete from t for portion of apptime from '2000-01-01' to '2018-01-01';
+select * from t;
+s e xs xe
+1999-01-01 2000-01-01 1999-01-01 2000-01-01
+2018-01-01 2018-12-12 2018-01-01 2018-12-12
+truncate t;
+# same for trigger case
+insert into t values('1999-01-01', '2018-12-12', default, default);
+create or replace table log_tbl(id int auto_increment primary key, log text) engine=myisam;
+create or replace procedure log(s text)
+insert into log_tbl(log) values(s);
+create trigger tr1upd_t before update on t
+for each row call log(CONCAT('>UPD: ', old.s, ", ", old.e, ' -> ', new.s, ", ", new.e));
+create trigger tr2upd_t after update on t
+for each row call log(CONCAT('<UPD: ', old.s, ", ", old.e, ' -> ', new.s, ", ", new.e));
+create trigger tr1del_t before delete on t
+for each row call log(CONCAT('>DEL: ', old.s, ", ", old.e));
+create trigger tr2del_t after delete on t
+for each row call log(CONCAT('<DEL: ', old.s, ", ", old.e));
+create trigger tr1ins_t before insert on t
+for each row call log(CONCAT('>INS: ', new.s, ", ", new.e));
+create trigger tr2ins_t after insert on t
+for each row call log(CONCAT('<INS: ', new.s, ", ", new.e));
+delete from t for portion of apptime from '2000-01-01' to '2018-01-01';
+select * from t;
+s e xs xe
+1999-01-01 2000-01-01 1999-01-01 2000-01-01
+2018-01-01 2018-12-12 2018-01-01 2018-12-12
+select * from log_tbl order by id;
+id log
+1 >DEL: 1999-01-01, 2018-12-12
+2 >INS: 1999-01-01, 2000-01-01
+3 <INS: 1999-01-01, 2000-01-01
+4 >INS: 2018-01-01, 2018-12-12
+5 <INS: 2018-01-01, 2018-12-12
+6 <DEL: 1999-01-01, 2018-12-12
+# View can't be used
+create or replace view v as select * from t;
+delete from v for portion of p from '2000-01-01' to '2018-01-01';
+ERROR 42S02: 'v' is a view
+# View can't be used
+create or replace view v as select t.* from t, t as t1;
+delete from v for portion of p from '2000-01-01' to '2018-01-01';
+ERROR HY000: Can not delete from join view 'test.v'
+# auto_increment field overflow
+create or replace table t (id tinyint auto_increment primary key,
+s date, e date, period for apptime(s,e));
+insert into t values(127, '1999-01-01', '2018-12-12');
+delete from t for portion of apptime from '2000-01-01' to '2018-01-01';
+ERROR 22003: Out of range value for column 'id' at row 1
+select * from t;
+id s e
+127 1999-01-01 2018-12-12
+# same for trigger case
+create or replace table log_tbl(id int auto_increment primary key, log text) engine=myisam;
+create or replace procedure log(s text)
+insert into log_tbl(log) values(s);
+create trigger tr1upd_t before update on t
+for each row call log(CONCAT('>UPD: ', old.s, ", ", old.e, ' -> ', new.s, ", ", new.e));
+create trigger tr2upd_t after update on t
+for each row call log(CONCAT('<UPD: ', old.s, ", ", old.e, ' -> ', new.s, ", ", new.e));
+create trigger tr1del_t before delete on t
+for each row call log(CONCAT('>DEL: ', old.s, ", ", old.e));
+create trigger tr2del_t after delete on t
+for each row call log(CONCAT('<DEL: ', old.s, ", ", old.e));
+create trigger tr1ins_t before insert on t
+for each row call log(CONCAT('>INS: ', new.s, ", ", new.e));
+create trigger tr2ins_t after insert on t
+for each row call log(CONCAT('<INS: ', new.s, ", ", new.e));
+# negotiate side effects of non-transactional MyISAM engine
+replace into t values(127, '1999-01-01', '2018-12-12');
+select * from t;
+id s e
+127 1999-01-01 2018-12-12
+truncate table log_tbl;
+delete from t for portion of apptime from '2000-01-01' to '2018-01-01';
+ERROR 22003: Out of range value for column 'id' at row 1
+select * from t;
+id s e
+127 1999-01-01 2018-12-12
+select * from log_tbl order by id;
+id log
+1 >DEL: 1999-01-01, 2018-12-12
+# custom constraint for period fields
+create or replace table t(id int, s date, e date, period for apptime(s,e),
+constraint dist2days check (datediff(e, s) >= 2));
+insert into t values(1, '1999-01-01', '2018-12-12'),
+(2, '1999-01-01', '1999-12-12');
+delete from t for portion of apptime from '1999-01-02' to '2018-12-12';
+ERROR 23000: CONSTRAINT `dist2days` failed for `test`.`t`
+# negotiate side effects of non-transactional MyISAM engine
+truncate t;
+insert into t values(1, '1999-01-01', '2018-12-12'),
+(2, '1999-01-01', '1999-12-12');
+delete from t for portion of apptime from '1999-01-01' to '2018-12-11';
+ERROR 23000: CONSTRAINT `dist2days` failed for `test`.`t`
+truncate t;
+insert into t values(1, '1999-01-01', '2018-12-12'),
+(2, '1999-01-01', '1999-12-12');
+delete from t for portion of apptime from '1999-01-03' to '2018-12-10';
+select *, datediff(e, s) from t;
+id s e datediff(e, s)
+1 1999-01-01 1999-01-03 2
+1 2018-12-10 2018-12-12 2
+2 1999-01-01 1999-01-03 2
+#
+# MDEV-18929 2nd execution of SP does not detect ER_VERS_NOT_VERSIONED
+#
+create or replace table t1 (id int, s date, e date, period for apptime(s,e));
+create or replace procedure sp()
+delete from t1 for portion of othertime from '2000-01-01' to '2018-01-01';
+call sp;
+ERROR HY000: Period `othertime` is not found in table
+call sp;
+ERROR HY000: Period `othertime` is not found in table
+drop table t1;
+drop procedure sp;
+drop table t,t2,t3,log_tbl;
+drop view v;
+drop procedure log;
+# MDEV-19130 Assertion
+# `next_insert_id >= auto_inc_interval_for_cur_row.minimum()'
+# failed in handler::update_auto_increment after error 167
+create or replace table t (f tinyint auto_increment null,
+s timestamp, e timestamp,
+period for app(s,e), key(f, s));
+insert into t (s,e) values
+('2021-08-22 10:28:43', '2023-09-17 00:00:00'),
+('2019-05-09 21:45:24', '2020-04-22 14:38:49');
+insert into t (s,e) select s,e from t;
+insert into t (s,e) select s,e from t;
+insert into t (s,e) select s,e from t;
+insert into t (s,e) values ('2015-07-07 00:00:00','2020-03-11 08:48:52');
+insert into t (s,e) select s,e from t;
+insert into t (s,e) select s,e from t;
+insert into t select * from t;
+ERROR 22003: Out of range value for column 'f' at row ROW
+delete ignore from t
+for portion of app from '2015-07-07 00:00:00' to '2020-03-11 08:48:52';
+drop table t;
+create table t1 (pk int, s date, e date, period for se (s,e), primary key (pk,se without overlaps));
+insert into t1 values (1,'2020-01-01','2020-02-20');
+delete from t1 for portion of se from '2020-01-30' to '2020-01-31';
+drop table t1;
+# End of 10.5 tests
+#
+# MDEV-19190 Assertion `part_share->auto_inc_initialized` failed in
+# ha_partition::get_auto_increment
+#
+create table t1 (id int, s date, e date, period for app(s,e))
+partition by key(id);
+insert into t1 (s,e) values ('2023-07-21','2024-06-07');
+alter table t1 modify id int auto_increment key;
+delete from t1 for portion of app from '2023-07-20' to '2024-05-23';
+select * from t1;
+id s e
+2 2024-05-23 2024-06-07
+drop table t1;
+create table t1 (id int, s date, e date, period for app(s,e))
+partition by key(id);
+insert into t1 (s,e) values ('2023-07-21','2024-06-07');
+alter table t1 modify id int auto_increment key;
+delete from t1 for portion of app from '2023-07-20' to '2024-05-23';
+select * from t1;
+id s e
+2 2024-05-23 2024-06-07
+drop table t1;
+drop table log_tbl;
+drop procedure log;
diff --git a/mysql-test/suite/period/r/long_unique.result b/mysql-test/suite/period/r/long_unique.result
new file mode 100644
index 00000000..5c5f4297
--- /dev/null
+++ b/mysql-test/suite/period/r/long_unique.result
@@ -0,0 +1,17 @@
+#
+# Assertion `inited == NONE || update_handler != this' failed in
+# handler::ha_write_row
+#
+CREATE TABLE t1 (f VARCHAR(4096), s DATE, e DATE, PERIOD FOR app(s,e), UNIQUE(f)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('foo', '2023-08-30', '2025-07-09'),('bar', '2021-01-01', '2021-12-31');
+DELETE FROM t1 FOR PORTION OF app FROM '2023-08-29' TO '2025-07-01';
+DROP TABLE t1;
+#
+# MDEV-21819 Assertion `inited == NONE || update_handler != this'
+# failed in handler::ha_write_row
+#
+CREATE OR REPLACE TABLE t1 (a INT, b BLOB, s DATE, e DATE, PERIOD FOR app(s,e), UNIQUE(b)) ENGINE=MyISAM PARTITION BY HASH(a) PARTITIONS 2;
+INSERT INTO t1 VALUES (1,'foo','2022-01-01', '2025-01-01');
+DELETE FROM t1 FOR PORTION OF app FROM '2023-01-01' TO '2024-01-01';
+ERROR 23000: Duplicate entry 'foo' for key 'b'
+DROP TABLE t1;
diff --git a/mysql-test/suite/period/r/overlaps.result b/mysql-test/suite/period/r/overlaps.result
new file mode 100644
index 00000000..78b1ac18
--- /dev/null
+++ b/mysql-test/suite/period/r/overlaps.result
@@ -0,0 +1,451 @@
+create or replace table t(id int, s date, e date,
+period for p(s,e),
+primary key(id, p without overlaps)
+) partition by key (id);
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `id` int(11) NOT NULL,
+ `s` date NOT NULL,
+ `e` date NOT NULL,
+ PERIOD FOR `p` (`s`, `e`),
+ PRIMARY KEY (`id`,`p` WITHOUT OVERLAPS)
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+ PARTITION BY KEY (`id`)
+insert into t values (1, '2003-01-01', '2003-03-01'),
+(1, '2003-05-01', '2003-07-01');
+insert into t values (1, '2003-02-01', '2003-04-01');
+ERROR 23000: Duplicate entry '1-2003-04-01-2003-02-01' for key 'PRIMARY'
+insert into t values (1, '2003-04-01', '2003-06-01');
+ERROR 23000: Duplicate entry '1-2003-06-01-2003-04-01' for key 'PRIMARY'
+insert into t values (1, '2003-05-15', '2003-06-15');
+ERROR 23000: Duplicate entry '1-2003-06-15-2003-05-15' for key 'PRIMARY'
+insert into t values (1, '2003-04-01', '2003-08-01');
+ERROR 23000: Duplicate entry '1-2003-08-01-2003-04-01' for key 'PRIMARY'
+insert into t values (1, '2003-03-01', '2003-05-01');
+# expand/shrink period
+update t set s= '2002-12-01' where s = '2003-01-01';
+update t set s= '2003-01-01' where s = '2002-12-01';
+update t set e= '2003-08-01' where s = '2003-05-01';
+update t set e= '2003-07-01' where s = '2003-05-01';
+# move left/right
+update t set s= '2002-12-15', e= '2003-01-15' where s = '2003-01-01';
+update t set s= '2003-01-01', e= '2003-02-01' where s = '2002-12-15';
+# diminish/enlarge
+update t set s= '2003-01-10', e= '2003-01-20' where s = '2003-01-01';
+update t set s= '2003-01-01', e= '2003-02-01' where s = '2003-01-10';
+select * from t;
+id s e
+1 2003-01-01 2003-02-01
+1 2003-03-01 2003-05-01
+1 2003-05-01 2003-07-01
+# intersect left/right, strict inclusion/containment
+update t set e= '2003-04-01' where s = '2003-01-01';
+ERROR 23000: Duplicate entry '1-2003-04-01-2003-01-01' for key 'PRIMARY'
+update t set s= '2003-04-01' where s = '2003-05-01';
+ERROR 23000: Duplicate entry '1-2003-07-01-2003-04-01' for key 'PRIMARY'
+update t set s= '2003-03-10', e= '2003-03-20' where s = '2003-01-01';
+ERROR 23000: Duplicate entry '1-2003-03-20-2003-03-10' for key 'PRIMARY'
+update t set s= '2003-04-01', e= '2003-08-01' where s = '2003-03-01';
+ERROR 23000: Duplicate entry '1-2003-08-01-2003-04-01' for key 'PRIMARY'
+# inclusion/containment with partial match
+update t set s= '2003-03-01', e= '2003-04-01' where s = '2003-01-01';
+ERROR 23000: Duplicate entry '1-2003-04-01-2003-03-01' for key 'PRIMARY'
+update t set s= '2003-04-01', e= '2003-05-01' where s = '2003-01-01';
+ERROR 23000: Duplicate entry '1-2003-05-01-2003-04-01' for key 'PRIMARY'
+update t set s= '2003-03-01' where s = '2003-05-01';
+ERROR 23000: Duplicate entry '1-2003-07-01-2003-03-01' for key 'PRIMARY'
+update t set e= '2003-05-01' where s = '2003-01-01';
+ERROR 23000: Duplicate entry '1-2003-05-01-2003-01-01' for key 'PRIMARY'
+select * from t where year(s) = 2003;
+id s e
+1 2003-01-01 2003-02-01
+1 2003-03-01 2003-05-01
+1 2003-05-01 2003-07-01
+# UPDATE ... FOR PORTION test
+insert t values (2, '2003-04-15', '2003-05-01');
+update t for portion of p from '2003-01-01' to '2003-01-15'
+ set id= 2;
+select * from t;
+id s e
+1 2003-01-15 2003-02-01
+1 2003-03-01 2003-05-01
+1 2003-05-01 2003-07-01
+2 2003-01-01 2003-01-15
+2 2003-04-15 2003-05-01
+update t for portion of p from '2003-01-15' to '2003-02-01'
+ set id= 2;
+select * from t;
+id s e
+1 2003-03-01 2003-05-01
+1 2003-05-01 2003-07-01
+2 2003-01-01 2003-01-15
+2 2003-01-15 2003-02-01
+2 2003-04-15 2003-05-01
+# Next, test UPDATE ... FOR PORTION resulting with an error
+# Since MyISAM/Aria engines lack atomicity, the results would differ with
+# innodb. So a table is going to be copied to one with explicit engine.
+create table t_myisam (id int, s date, e date,
+period for p(s,e),
+primary key(id, p without overlaps))
+engine=myisam
+select * from t;
+update t_myisam for portion of p from '2003-04-01' to '2003-06-01'
+ set id= 2 order by s desc;
+ERROR 23000: Duplicate entry '2-2003-05-01-2003-04-01' for key 'PRIMARY'
+select * from t_myisam;
+id s e
+1 2003-03-01 2003-05-01
+1 2003-06-01 2003-07-01
+2 2003-01-01 2003-01-15
+2 2003-01-15 2003-02-01
+2 2003-04-15 2003-05-01
+2 2003-05-01 2003-06-01
+create table t_innodb (id int, s date, e date,
+period for p(s,e),
+primary key(id, p without overlaps))
+engine=innodb
+select * from t;
+update t_innodb for portion of p from '2003-04-01' to '2003-06-01'
+ set id= 2 order by s desc;
+ERROR 23000: Duplicate entry '2-2003-05-01-2003-04-01' for key 'PRIMARY'
+select * from t_innodb;
+id s e
+1 2003-03-01 2003-05-01
+1 2003-05-01 2003-07-01
+2 2003-01-01 2003-01-15
+2 2003-01-15 2003-02-01
+2 2003-04-15 2003-05-01
+drop table t_myisam, t_innodb;
+create or replace table t(id int, s date, e date,
+period for p(s,e),
+primary key(id, q without overlaps));
+ERROR HY000: Period `q` is not found in table
+create or replace table t(id int, s date, e date,
+primary key(id, p without overlaps));
+ERROR HY000: Period `p` is not found in table
+create or replace table t(id int, s date, e date,
+period for p(s,e),
+primary key(id, s, p without overlaps));
+ERROR HY000: Key `PRIMARY` cannot explicitly include column `s`
+create or replace table t(id int, s date, e date,
+period for p(s,e),
+primary key(id));
+insert into t values (1, '2003-03-01', '2003-05-01');
+insert into t values (1, '2003-04-01', '2003-05-01');
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+create or replace table t(id int, u int, s date, e date,
+period for p(s,e),
+primary key(id, p without overlaps),
+unique(u));
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `id` int(11) NOT NULL,
+ `u` int(11) DEFAULT NULL,
+ `s` date NOT NULL,
+ `e` date NOT NULL,
+ PERIOD FOR `p` (`s`, `e`),
+ PRIMARY KEY (`id`,`p` WITHOUT OVERLAPS),
+ UNIQUE KEY `u` (`u`)
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t values (1, 1, '2003-03-01', '2003-05-01');
+insert into t values (1, 2, '2003-05-01', '2003-07-01');
+insert into t values (1, 3, '2003-04-01', '2003-05-01');
+ERROR 23000: Duplicate entry '1-2003-05-01-2003-04-01' for key 'PRIMARY'
+create or replace table t(id int, u int, s date, e date,
+period for p(s,e),
+primary key(id, p without overlaps),
+unique(u, p without overlaps));
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `id` int(11) NOT NULL,
+ `u` int(11) DEFAULT NULL,
+ `s` date NOT NULL,
+ `e` date NOT NULL,
+ PERIOD FOR `p` (`s`, `e`),
+ PRIMARY KEY (`id`,`p` WITHOUT OVERLAPS),
+ UNIQUE KEY `u` (`u`,`p` WITHOUT OVERLAPS)
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t values (2, NULL, '2003-03-01', '2003-05-01');
+insert into t values (2, NULL, '2003-03-01', '2003-05-01');
+ERROR 23000: Duplicate entry '2-2003-05-01-2003-03-01' for key 'PRIMARY'
+insert into t values (3, NULL, '2003-03-01', '2003-05-01');
+insert into t values (1, 1, '2003-03-01', '2003-05-01');
+insert into t values (1, 2, '2003-05-01', '2003-07-01');
+insert into t values (4, NULL, '2003-03-01', '2003-05-01');
+create sequence seq start=5 engine=myisam;
+update t set id= nextval(seq), u= nextval(seq), s='2003-05-01', e='2003-07-01'
+ where u is NULL;
+select * from t;
+id u s e
+1 1 2003-03-01 2003-05-01
+1 2 2003-05-01 2003-07-01
+5 6 2003-05-01 2003-07-01
+7 8 2003-05-01 2003-07-01
+9 10 2003-05-01 2003-07-01
+drop sequence seq;
+create or replace table t(id int, s date, e date,
+period for p(s,e));
+insert into t values (1, '2003-01-01', '2003-03-01'),
+(1, '2003-05-01', '2003-07-01'),
+(1, '2003-02-01', '2003-04-01');
+alter table t add primary key(id, p without overlaps);
+ERROR 23000: Duplicate entry '1-2003-04-01-2003-02-01' for key 'PRIMARY'
+# Historical rows are not checked against constraints
+set @@system_versioning_alter_history= keep;
+alter table t add system versioning;
+delete from t;
+alter table t add primary key(id, p without overlaps);
+insert into t values (1, '2003-01-01', '2003-03-01'),
+(1, '2003-03-01', '2003-05-01');
+# `without overlaps` is not lost on alter table
+alter table t add y int;
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `id` int(11) NOT NULL,
+ `s` date NOT NULL,
+ `e` date NOT NULL,
+ `y` int(11) DEFAULT NULL,
+ PERIOD FOR `p` (`s`, `e`),
+ PRIMARY KEY (`id`,`p` WITHOUT OVERLAPS)
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+alter table t drop y;
+create or replace table t1 like t;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) NOT NULL,
+ `s` date NOT NULL,
+ `e` date NOT NULL,
+ PERIOD FOR `p` (`s`, `e`),
+ PRIMARY KEY (`id`,`p` WITHOUT OVERLAPS)
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+create or replace table t1 (x int, s date, e date,
+period for p(s,e),
+primary key(x, p without overlaps));
+alter table t1 partition by key (x);
+create or replace table t1 (x int, s date, e date, period for p (s, e))
+partition by hash (x);
+alter table t1 add primary key (x, p without overlaps);
+create or replace table t2 (x int, s date, e date,
+period for p (s, e),
+key(x, p without overlaps));
+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 overlaps))' at line 3
+create or replace table t2 (x int, s date, e date,
+period for p (s, e),
+unique(x, p without overlaps, x, p without overlaps));
+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 ' x, p without overlaps))' at line 3
+create or replace table t1 (x varchar(100), s date, e date,
+period for p(s,e),
+primary key(x, p without overlaps));
+create or replace table t1 (x varchar(100) compressed, s date, e date,
+period for p(s,e),
+primary key(x, p without overlaps));
+ERROR HY000: Compressed column 'x' can't be used in key specification
+create or replace table t (x int, s date, e date, period for apptime(s,e),
+unique(x, apptime without overlaps) using hash);
+ERROR HY000: Key `x` cannot have WITHOUT OVERLAPS
+create or replace table t (x int, s date, e date, period for apptime(s,e),
+b blob, unique(x, b, apptime without overlaps));
+ERROR HY000: Key `x` cannot have WITHOUT OVERLAPS
+create or replace table t (x int, s date, e date, b blob unique,
+period for apptime(s,e),
+unique(x, apptime without overlaps));
+insert into t values (1, '2020-03-01', '2020-03-05', 'test');
+insert into t values (1, '2020-03-05', '2020-03-10', 'test');
+ERROR 23000: Duplicate entry 'test' for key 'b'
+insert into t values (1, '2020-03-05', '2020-03-10', 'test2');
+insert into t values (1, '2020-03-03', '2020-03-10', 'test3');
+ERROR 23000: Duplicate entry '1-2020-03-10-2020-03-03' for key 'x'
+create or replace table t (x int, s date, e date, period for apptime(s,e),
+unique(x, apptime without overlaps));
+replace into t values (1, '2020-03-03', '2020-03-10');
+ERROR 42000: This version of MariaDB doesn't yet support 'WITHOUT OVERLAPS'
+insert into t values (1, '2020-03-03', '2020-03-10')
+on duplicate key update x = 2;
+ERROR 42000: This version of MariaDB doesn't yet support 'WITHOUT OVERLAPS'
+select * from t;
+x s e
+select * into outfile 'tmp_t.txt' from t;
+load data infile 'tmp_t.txt' into table t;
+load data infile 'tmp_t.txt' replace into table t;
+ERROR 42000: This version of MariaDB doesn't yet support 'WITHOUT OVERLAPS'
+insert into t values (1, '2020-03-01', '2020-03-05');
+select * into outfile 'tmp_t.txt' from t;
+load data infile 'tmp_t.txt' into table t;
+ERROR 23000: Duplicate entry '1-2020-03-05-2020-03-01' for key 'x'
+load data infile 'tmp_t.txt' ignore into table t;
+Warnings:
+Warning 1062 Duplicate entry '1-2020-03-05-2020-03-01' for key 'x'
+load data infile 'tmp_t.txt' replace into table t;
+ERROR 42000: This version of MariaDB doesn't yet support 'WITHOUT OVERLAPS'
+# MDEV-22599 WITHOUT OVERLAPS does not work with prefix indexes
+create or replace table t1 (a varchar(6), s timestamp, e timestamp,
+period for p(s,e),
+unique(a(3), p without overlaps));
+insert into t1 values ('foo', '2012-01-01', '2015-12-31');
+insert into t1 values ('foobar', '2013-01-01', '2014-01-01');
+ERROR 23000: Duplicate entry 'foo-2014-01-01 00:00:00-2013-01-01 00:00:00' for key 'a'
+insert into t1 values ('bar', '2012-01-01', '2015-12-31'),
+('baz', '2013-01-01', '2014-01-01');
+select * from t1;
+a s e
+foo 2012-01-01 00:00:00 2015-12-31 00:00:00
+bar 2012-01-01 00:00:00 2015-12-31 00:00:00
+baz 2013-01-01 00:00:00 2014-01-01 00:00:00
+# MDEV-22753 Server crashes in handler::ha_check_overlaps or error 190
+# "Incompatible key or row definition" upon INSERT into versioned
+# partitioned table with WITHOUT OVERLAPS
+create or replace table t1 (f int, s date, e date, period for p(s,e),
+unique(f, p without overlaps)
+) engine=innodb with system versioning
+partition by system_time limit 1000
+(partition p1 history, partition pn current);
+alter table t1 add partition (partition p2 history);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `f` int(11) DEFAULT NULL,
+ `s` date NOT NULL,
+ `e` date NOT NULL,
+ PERIOD FOR `p` (`s`, `e`),
+ UNIQUE KEY `f` (`f`,`p` WITHOUT OVERLAPS)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
+ PARTITION BY SYSTEM_TIME LIMIT 1000
+(PARTITION `p1` HISTORY ENGINE = InnoDB,
+ PARTITION `p2` HISTORY ENGINE = InnoDB,
+ PARTITION `pn` CURRENT ENGINE = InnoDB)
+insert into t1 values (1,'2013-01-12','2015-11-04'),
+(2,'2016-03-15','2024-11-09');
+# MDEV-22714 Assertion `index->table->is_instant()' failed upon
+# multi-update on table with WITHOUT OVERLAPS
+create or replace table t (a int);
+insert into t values (0),(null),(0);
+create or replace table t1 (f int, s date, e date, period for p(s,e),
+unique(f, p without overlaps));
+insert into t1 values (0,'2026-02-12','2036-09-16'),
+(null,'2025-03-09','2032-12-05');
+update ignore t join t1 set f = a;
+# MDEV-22639 Assertion `inited != NONE' failed in
+# handler::ha_check_overlaps upon multi-table update
+create or replace table t (f int, s date, e date, period for p(s,e),
+unique(f, p without overlaps)) engine=myisam;
+insert into t values (1,'1988-08-25','2024-03-06');
+create or replace table t1 (a int) engine=myisam;
+insert into t1 values (1),(2);
+update t join t1 set s = '2020-01-01';
+# MDEV-22608 ASAN use-after-poison in TABLE::check_period_overlaps
+create or replace table t1 (s date, e date, b bit, period for p(s,e),
+unique(b, p without overlaps)) engine=myisam;
+insert into t1 values ('2024-12-21','2034-06-29',0),
+('2024-12-21','2034-06-29',1);
+update t1 set b = 1;
+ERROR 23000: Duplicate entry '\x01-2034-06-29-2024-12-21' for key 'b'
+# MDEV-22677 Server crashes in ha_partition::open upon update on
+# partitioned HEAP table with WITHOUT OVERLAPS
+create or replace table t (id int, s date, e date, period for p(s,e),
+primary key(id, p without overlaps)
+) engine=heap partition by hash(id);
+update t set id = 1;
+drop table t, t1;
+#
+# MDEV-30415 PERIOD false positive overlap wtih utf8mb4_unicode_nopad_ci
+#
+CREATE TABLE t1 (
+datetime_column_name_1 DATETIME(6) NOT NULL,
+datetime_column_name_2 DATETIME(6) NOT NULL,
+text_column_name TEXT COLLATE utf8mb4_unicode_nopad_ci NOT NULL,
+PERIOD FOR period_name (datetime_column_name_1, datetime_column_name_2),
+UNIQUE KEY index_name (text_column_name(191),period_name WITHOUT OVERLAPS)
+) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_nopad_ci;
+INSERT INTO t1 (datetime_column_name_1, datetime_column_name_2, text_column_name)
+VALUES
+('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc'),
+('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc ');
+TRUNCATE TABLE t1;
+INSERT INTO t1 (datetime_column_name_1, datetime_column_name_2, text_column_name)
+VALUES
+('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc '),
+('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc');
+DROP TABLE t1;
+CREATE TABLE `t1` (
+datetime_column_name_1 DATETIME(6) NOT NULL,
+datetime_column_name_2 DATETIME(6) NOT NULL,
+text_column_name TEXT COLLATE utf8mb4_unicode_nopad_ci NOT NULL,
+PERIOD FOR period_name (datetime_column_name_1, datetime_column_name_2),
+UNIQUE KEY index_name (text_column_name(191),period_name WITHOUT OVERLAPS)
+) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_nopad_ci;
+INSERT INTO t1 VALUES
+('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'def '),
+('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'def');
+TRUNCATE TABLE t1;
+INSERT INTO t1 VALUES
+('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'def'),
+('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'def '),
+('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'def ');
+SELECT *, LENGTH(text_column_name) FROM t1;
+datetime_column_name_1 datetime_column_name_2 text_column_name LENGTH(text_column_name)
+2000-01-01 00:00:00.000000 2001-01-01 00:00:00.000000 def 3
+2000-01-01 00:00:00.000000 2001-01-01 00:00:00.000000 def 4
+2000-01-01 00:00:00.000000 2001-01-01 00:00:00.000000 def 5
+DROP TABLE t1;
+CREATE TABLE t1 (
+datetime_column_name_1 DATETIME(6) NOT NULL,
+datetime_column_name_2 DATETIME(6) NOT NULL,
+text_column_name TEXT COLLATE utf8mb4_unicode_nopad_ci NOT NULL,
+PERIOD FOR period_name (datetime_column_name_1, datetime_column_name_2),
+UNIQUE KEY index_name (text_column_name(3),period_name WITHOUT OVERLAPS)
+) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_nopad_ci;
+INSERT INTO t1 (datetime_column_name_1, datetime_column_name_2, text_column_name)
+VALUES
+('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc'),
+('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc ');
+ERROR 23000: Duplicate entry 'abc-2001-01-01 00:00:00.000000-2000-01-01 00:00:00.000000' for key 'index_name'
+TRUNCATE TABLE t1;
+INSERT INTO t1 (datetime_column_name_1, datetime_column_name_2, text_column_name)
+VALUES
+('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc '),
+('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc');
+ERROR 23000: Duplicate entry 'abc-2001-01-01 00:00:00.000000-2000-01-01 00:00:00.000000' for key 'index_name'
+DROP TABLE t1;
+CREATE TABLE t1 (
+datetime_column_name_1 DATETIME(6) NOT NULL,
+datetime_column_name_2 DATETIME(6) NOT NULL,
+char_column_name CHAR(255) COLLATE utf8mb4_unicode_nopad_ci NOT NULL,
+PERIOD FOR period_name (datetime_column_name_1, datetime_column_name_2),
+UNIQUE KEY index_name (char_column_name(191),period_name WITHOUT OVERLAPS)
+) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_nopad_ci;
+INSERT INTO t1 (datetime_column_name_1, datetime_column_name_2, char_column_name)
+VALUES
+('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc'),
+('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc ');
+ERROR 23000: Duplicate entry 'abc-2001-01-01 00:00:00.000000-2000-01-01 00:00:00.000000' for key 'index_name'
+TRUNCATE TABLE t1;
+INSERT INTO t1 (datetime_column_name_1, datetime_column_name_2, char_column_name)
+VALUES
+('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc '),
+('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc');
+ERROR 23000: Duplicate entry 'abc-2001-01-01 00:00:00.000000-2000-01-01 00:00:00.000000' for key 'index_name'
+DROP TABLE t1;
+CREATE TABLE t1 (
+datetime_column_name_1 DATETIME(6) NOT NULL,
+datetime_column_name_2 DATETIME(6) NOT NULL,
+char_column_name CHAR(255) COLLATE utf8mb4_unicode_nopad_ci NOT NULL,
+PERIOD FOR period_name (datetime_column_name_1, datetime_column_name_2),
+UNIQUE KEY index_name (char_column_name(3),period_name WITHOUT OVERLAPS)
+) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_nopad_ci;
+INSERT INTO t1 (datetime_column_name_1, datetime_column_name_2, char_column_name)
+VALUES
+('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc'),
+('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc ');
+ERROR 23000: Duplicate entry 'abc-2001-01-01 00:00:00.000000-2000-01-01 00:00:00.000000' for key 'index_name'
+TRUNCATE TABLE t1;
+INSERT INTO t1 (datetime_column_name_1, datetime_column_name_2, char_column_name)
+VALUES
+('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc '),
+('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc');
+ERROR 23000: Duplicate entry 'abc-2001-01-01 00:00:00.000000-2000-01-01 00:00:00.000000' for key 'index_name'
+DROP TABLE t1;
diff --git a/mysql-test/suite/period/r/update.result b/mysql-test/suite/period/r/update.result
new file mode 100644
index 00000000..f726b4c0
--- /dev/null
+++ b/mysql-test/suite/period/r/update.result
@@ -0,0 +1,309 @@
+create table t (id int, s date, e date, period for apptime(s,e));
+insert into t values(1, '1999-01-01', '2018-12-12');
+insert into t values(1, '1999-01-01', '2017-01-01');
+insert into t values(1, '2017-01-01', '2019-01-01');
+insert into t values(2, '1998-01-01', '2018-12-12');
+insert into t values(3, '1997-01-01', '2015-01-01');
+insert into t values(4, '2016-01-01', '2020-01-01');
+insert into t values(5, '2010-01-01', '2015-01-01');
+create or replace table t1 (id int, s date, e date, period for apptime(s,e));
+insert t1 select * from t;
+create or replace table t2 (id int, s date, e date, period for apptime(s,e));
+insert t2 select * from t;
+update t for portion of apptime from '2000-01-01' to '2018-01-01'
+ set id=id + 6;
+select * from t;
+id s e
+1 1999-01-01 2000-01-01
+1 1999-01-01 2000-01-01
+1 2018-01-01 2018-12-12
+1 2018-01-01 2019-01-01
+10 2016-01-01 2018-01-01
+11 2010-01-01 2015-01-01
+2 1998-01-01 2000-01-01
+2 2018-01-01 2018-12-12
+3 1997-01-01 2000-01-01
+4 2018-01-01 2020-01-01
+7 2000-01-01 2017-01-01
+7 2000-01-01 2018-01-01
+7 2017-01-01 2018-01-01
+8 2000-01-01 2018-01-01
+9 2000-01-01 2015-01-01
+# Check triggers
+create or replace table log_tbl(id int auto_increment primary key, log text) engine=myisam;
+create or replace procedure log(s text)
+insert into log_tbl(log) values(s);
+create trigger tr1upd_t1 before update on t1
+for each row call log(CONCAT('>UPD: ', old.id, ", ", old.s, ", ", old.e, ' -> ', new.id, ", ", new.s, ", ", new.e));
+create trigger tr2upd_t1 after update on t1
+for each row call log(CONCAT('<UPD: ', old.id, ", ", old.s, ", ", old.e, ' -> ', new.id, ", ", new.s, ", ", new.e));
+create trigger tr1del_t1 before delete on t1
+for each row call log(CONCAT('>DEL: ', old.id, ", ", old.s, ", ", old.e));
+create trigger tr2del_t1 after delete on t1
+for each row call log(CONCAT('<DEL: ', old.id, ", ", old.s, ", ", old.e));
+create trigger tr1ins_t1 before insert on t1
+for each row call log(CONCAT('>INS: ', new.id, ", ", new.s, ", ", new.e));
+create trigger tr2ins_t1 after insert on t1
+for each row call log(CONCAT('<INS: ', new.id, ", ", new.s, ", ", new.e));
+update t1 for portion of apptime from '2000-01-01' to '2018-01-01'
+ set id=id + 6;
+select * from t1;
+id s e
+1 1999-01-01 2000-01-01
+1 1999-01-01 2000-01-01
+1 2018-01-01 2018-12-12
+1 2018-01-01 2019-01-01
+10 2016-01-01 2018-01-01
+11 2010-01-01 2015-01-01
+2 1998-01-01 2000-01-01
+2 2018-01-01 2018-12-12
+3 1997-01-01 2000-01-01
+4 2018-01-01 2020-01-01
+7 2000-01-01 2017-01-01
+7 2000-01-01 2018-01-01
+7 2017-01-01 2018-01-01
+8 2000-01-01 2018-01-01
+9 2000-01-01 2015-01-01
+select * from log_tbl order by id;
+id log
+1 >UPD: 1, 1999-01-01, 2018-12-12 -> 7, 2000-01-01, 2018-01-01
+2 >INS: 1, 1999-01-01, 2000-01-01
+3 <INS: 1, 1999-01-01, 2000-01-01
+4 >INS: 1, 2018-01-01, 2018-12-12
+5 <INS: 1, 2018-01-01, 2018-12-12
+6 <UPD: 1, 1999-01-01, 2018-12-12 -> 7, 2000-01-01, 2018-01-01
+7 >UPD: 1, 1999-01-01, 2017-01-01 -> 7, 2000-01-01, 2017-01-01
+8 >INS: 1, 1999-01-01, 2000-01-01
+9 <INS: 1, 1999-01-01, 2000-01-01
+10 <UPD: 1, 1999-01-01, 2017-01-01 -> 7, 2000-01-01, 2017-01-01
+11 >UPD: 1, 2017-01-01, 2019-01-01 -> 7, 2017-01-01, 2018-01-01
+12 >INS: 1, 2018-01-01, 2019-01-01
+13 <INS: 1, 2018-01-01, 2019-01-01
+14 <UPD: 1, 2017-01-01, 2019-01-01 -> 7, 2017-01-01, 2018-01-01
+15 >UPD: 2, 1998-01-01, 2018-12-12 -> 8, 2000-01-01, 2018-01-01
+16 >INS: 2, 1998-01-01, 2000-01-01
+17 <INS: 2, 1998-01-01, 2000-01-01
+18 >INS: 2, 2018-01-01, 2018-12-12
+19 <INS: 2, 2018-01-01, 2018-12-12
+20 <UPD: 2, 1998-01-01, 2018-12-12 -> 8, 2000-01-01, 2018-01-01
+21 >UPD: 3, 1997-01-01, 2015-01-01 -> 9, 2000-01-01, 2015-01-01
+22 >INS: 3, 1997-01-01, 2000-01-01
+23 <INS: 3, 1997-01-01, 2000-01-01
+24 <UPD: 3, 1997-01-01, 2015-01-01 -> 9, 2000-01-01, 2015-01-01
+25 >UPD: 4, 2016-01-01, 2020-01-01 -> 10, 2016-01-01, 2018-01-01
+26 >INS: 4, 2018-01-01, 2020-01-01
+27 <INS: 4, 2018-01-01, 2020-01-01
+28 <UPD: 4, 2016-01-01, 2020-01-01 -> 10, 2016-01-01, 2018-01-01
+29 >UPD: 5, 2010-01-01, 2015-01-01 -> 11, 2010-01-01, 2015-01-01
+30 <UPD: 5, 2010-01-01, 2015-01-01 -> 11, 2010-01-01, 2015-01-01
+# INSERT trigger only also works
+create or replace table log_tbl(id int auto_increment primary key, log text) engine=myisam;
+create or replace procedure log(s text)
+insert into log_tbl(log) values(s);
+create trigger tr1upd_t2 before update on t2
+for each row call log(CONCAT('>UPD: ', old.id, ", ", old.s, ", ", old.e, ' -> ', new.id, ", ", new.s, ", ", new.e));
+create trigger tr2upd_t2 after update on t2
+for each row call log(CONCAT('<UPD: ', old.id, ", ", old.s, ", ", old.e, ' -> ', new.id, ", ", new.s, ", ", new.e));
+create trigger tr1del_t2 before delete on t2
+for each row call log(CONCAT('>DEL: ', old.id, ", ", old.s, ", ", old.e));
+create trigger tr2del_t2 after delete on t2
+for each row call log(CONCAT('<DEL: ', old.id, ", ", old.s, ", ", old.e));
+create trigger tr1ins_t2 before insert on t2
+for each row call log(CONCAT('>INS: ', new.id, ", ", new.s, ", ", new.e));
+create trigger tr2ins_t2 after insert on t2
+for each row call log(CONCAT('<INS: ', new.id, ", ", new.s, ", ", new.e));
+drop trigger tr1upd_t2;
+drop trigger tr2upd_t2;
+update t2 for portion of apptime from '2000-01-01' to '2018-01-01'
+ set id=id + 6;
+select * from t2;
+id s e
+1 1999-01-01 2000-01-01
+1 1999-01-01 2000-01-01
+1 2018-01-01 2018-12-12
+1 2018-01-01 2019-01-01
+10 2016-01-01 2018-01-01
+11 2010-01-01 2015-01-01
+2 1998-01-01 2000-01-01
+2 2018-01-01 2018-12-12
+3 1997-01-01 2000-01-01
+4 2018-01-01 2020-01-01
+7 2000-01-01 2017-01-01
+7 2000-01-01 2018-01-01
+7 2017-01-01 2018-01-01
+8 2000-01-01 2018-01-01
+9 2000-01-01 2015-01-01
+select * from log_tbl order by id;
+id log
+1 >INS: 1, 1999-01-01, 2000-01-01
+2 <INS: 1, 1999-01-01, 2000-01-01
+3 >INS: 1, 2018-01-01, 2018-12-12
+4 <INS: 1, 2018-01-01, 2018-12-12
+5 >INS: 1, 1999-01-01, 2000-01-01
+6 <INS: 1, 1999-01-01, 2000-01-01
+7 >INS: 1, 2018-01-01, 2019-01-01
+8 <INS: 1, 2018-01-01, 2019-01-01
+9 >INS: 2, 1998-01-01, 2000-01-01
+10 <INS: 2, 1998-01-01, 2000-01-01
+11 >INS: 2, 2018-01-01, 2018-12-12
+12 <INS: 2, 2018-01-01, 2018-12-12
+13 >INS: 3, 1997-01-01, 2000-01-01
+14 <INS: 3, 1997-01-01, 2000-01-01
+15 >INS: 4, 2018-01-01, 2020-01-01
+16 <INS: 4, 2018-01-01, 2020-01-01
+select * from t for portion of apptime from 0 to 1 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 'portion of apptime from 0 to 1 for system_time all' at line 1
+update t for portion of apptime from 0 to 1 for system_time all set id=1;
+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 set id=1' at line 1
+# Modifying period start/end fields is forbidden.
+# SQL16: 14.14 <update statement: searched>, Syntax Rules, 7)a)ii)
+# Neither BSTARTCOL nor BENDCOL shall be an explicit <object column>
+# contained in the <set clause list>.
+update t for portion of apptime from '2000-01-01' to '2018-01-01'
+ set id= id + 6, s=subdate(s, 5), e=adddate(e, 5);
+ERROR HY000: Column `s` used in period `apptime` specified in update SET list
+# Precision timestamps
+create or replace table t (id int, s timestamp(5), e timestamp(5),
+period for apptime(s,e));
+insert into t values(1, '1999-01-01', '2018-12-12');
+insert into t values(1, '1999-01-01', '2017-01-01');
+update t for portion of apptime from '2000-01-01 00:00:00.00015'
+ to '2018-01-01 12:34:56.31415'
+ set id= id + 5;
+select * from t;
+id s e
+1 1999-01-01 00:00:00.00000 2000-01-01 00:00:00.00015
+1 1999-01-01 00:00:00.00000 2000-01-01 00:00:00.00015
+1 2018-01-01 12:34:56.31415 2018-12-12 00:00:00.00000
+6 2000-01-01 00:00:00.00015 2017-01-01 00:00:00.00000
+6 2000-01-01 00:00:00.00015 2018-01-01 12:34:56.31415
+# Strings
+create or replace table t (id int, str text, s date, e date,
+period for apptime(s,e));
+insert into t values(1, 'data', '1999-01-01', '2018-12-12');
+insert into t values(1, 'other data', '1999-01-01', '2018-12-12');
+update t for portion of apptime from '2000-01-01' to '2018-01-01'
+ set id= id + 5;
+select * from t;
+id str s e
+1 data 1999-01-01 2000-01-01
+1 data 2018-01-01 2018-12-12
+1 other data 1999-01-01 2000-01-01
+1 other data 2018-01-01 2018-12-12
+6 data 2000-01-01 2018-01-01
+6 other data 2000-01-01 2018-01-01
+# multi-table UPDATE is impossible
+create or replace table t1(x int);
+update t for portion of apptime from '2000-01-01' to '2018-01-01', t1
+set t.id= t.id + 5;
+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 ' t1
+set t.id= t.id + 5' at line 1
+update t1 set x= (select id from t for portion of apptime from '2000-01-01' to '2018-01-01');
+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 'portion of apptime from '2000-01-01' to '2018-01-01')' at line 1
+# single-table views
+create or replace view v1 as select * from t where id<10;
+update v1 for portion of apptime from '2000-01-01' to '2018-01-01' set id= id + 5;
+ERROR 42S02: 'v1' is a view
+# multi-table views
+create or replace view v1 as select * from t, t1 where x=id;
+update v1 for portion of apptime from '2000-01-01' to '2018-01-01' set id= id + 5;
+ERROR 42S02: 'v1' is a view
+# SQL16: 14.14 <update statement: searched>, Syntax Rules, 7)a) iii-iv)
+# Let FROMVAL be <point in time 1>. FROMVAL shall not generally contain a
+# reference to a column of T or a <routine invocation>
+# whose subject routine is an SQL-invoked routine that
+# is possibly non-deterministic or that possibly modifies SQL-data.
+# ...Same for <point in time 2> (TOVAL)
+update t for portion of apptime from 5*(5+s) to 1 set t.id= t.id + 5;
+ERROR HY000: Expression in FOR PORTION OF must be constant
+update t for portion of apptime from 1 to e set t.id= t.id + 5;
+ERROR HY000: Expression in FOR PORTION OF must be constant
+set @s= '2000-01-01';
+set @e= '2018-01-01';
+create or replace function f() returns date return @e;
+create or replace function g() returns date not deterministic return @e;
+create or replace function h() returns date deterministic return @e;
+update t for portion of apptime from @s to f() set t.id= t.id + 5;
+ERROR HY000: Expression in FOR PORTION OF must be constant
+update t for portion of apptime from @s to g() set t.id= t.id + 5;
+ERROR HY000: Expression in FOR PORTION OF must be constant
+# success
+update t for portion of apptime from @s to h() set t.id= t.id + 5;
+# select value is cached
+update t for portion of apptime from (select s from t2 limit 1) to h() set t.id= t.id + 5;
+# auto_inrement field is updated
+create or replace table t (id int primary key auto_increment, x int,
+s date, e date, period for apptime(s, e));
+insert into t values (default, 1, '1999-01-01', '2018-12-12');
+update t for portion of apptime from '2000-01-01' to '2018-01-01' set x= x + 5;
+select * from t;
+id x s e
+1 6 2000-01-01 2018-01-01
+2 1 1999-01-01 2000-01-01
+3 1 2018-01-01 2018-12-12
+truncate t;
+insert into t values (default, 1, '1999-01-01', '2018-12-12');
+update t for portion of apptime from '2000-01-01' to '2018-01-01' set x= 1;
+select * from t;
+id x s e
+1 1 2000-01-01 2018-01-01
+2 1 1999-01-01 2000-01-01
+3 1 2018-01-01 2018-12-12
+# generated columns are updated
+create or replace table t (x int, s date, e date,
+xs date as (s) stored, xe date as (e) stored,
+period for apptime(s, e));
+insert into t values(1, '1999-01-01', '2018-12-12', default, default);
+select * from t;
+x s e xs xe
+1 1999-01-01 2018-12-12 1999-01-01 2018-12-12
+update t for portion of apptime from '2000-01-01' to '2018-01-01' set x= x + 5;
+select *, xs=s and xe=e from t;
+x s e xs xe xs=s and xe=e
+1 1999-01-01 2000-01-01 1999-01-01 2000-01-01 1
+1 2018-01-01 2018-12-12 2018-01-01 2018-12-12 1
+6 2000-01-01 2018-01-01 2000-01-01 2018-01-01 1
+# MDEV-18921 Server crashes in bitmap_bits_set or bitmap_is_set upon
+# UPDATE IGNORE .. FOR PORTION with binary logging
+create or replace table t1 (f int, s date, e date, period for app(s,e));
+insert into t1 values (1,'2016-09-21','2019-06-14');
+update ignore t1 for portion of app from '2019-03-13' to '2019-03-14' set f = 1;
+drop table t,t1,t2,log_tbl;
+drop view v1;
+drop function f;
+drop function g;
+drop function h;
+drop procedure log;
+#
+# MDEV-21471 ER_CRASHED_ON_USAGE upon UPDATE FOR PORTION on Aria table
+#
+create table t1 (s date, e date, period for app(s,e), f varchar(8)) engine=aria row_format=fixed;
+insert into t1 values ('2024-05-13','2026-03-25','foo');
+update t1 for portion of app from '2024-04-02' to '2026-03-15' set f = 'bar';
+drop table t1;
+# MDEV-19130 Assertion
+# `next_insert_id >= auto_inc_interval_for_cur_row.minimum()'
+# failed in handler::update_auto_increment after error 167
+create table t1 (id int auto_increment, f int, s datetime, e datetime, period for p(s,e), primary key(id));
+insert into t1 (s,e) values ('1994-01-06','2004-11-30'),('1994-06-21','1997-06-20');
+update ignore t1 set id = 2429681664;
+Warnings:
+Warning 1264 Out of range value for column 'id' at row 1
+Warning 1264 Out of range value for column 'id' at row 2
+update ignore t1 for portion of p from '1995-07-06' to '2009-01-12' set f = 1;
+drop table t1;
+#
+# MDEV-22805 SIGSEGV in check_fields on UPDATE (optimized builds) | Assertion `thd->lex->sql_command == SQLCOM_UPDATE' failed.
+#
+CREATE TABLE t1 (a INT, b DATE, c DATE, PERIOD FOR APPTIME(b, c));
+INSERT INTO t1 VALUES(1, '1999-01-01', '2018-12-12');
+UPDATE t1 FOR PORTION OF APPTIME FROM (SELECT '1999-01-01' FROM t1 WHERE a=2) TO '2018-01-01' SET a = 100;
+ERROR 42000: This version of MariaDB doesn't yet support 'updating and querying the same temporal periods table'
+set @tmp= "UPDATE t1 FOR PORTION OF APPTIME FROM (SELECT '1999-01-01' FROM t1 WHERE a=2) TO '2018-01-01' SET a = 100";
+execute immediate @tmp;
+ERROR 42000: This version of MariaDB doesn't yet support 'updating and querying the same temporal periods table'
+CREATE VIEW v1 AS SELECT * FROM t1;
+UPDATE v1 FOR PORTION OF APPTIME FROM (SELECT '1999-01-01' FROM t1 WHERE a=2) TO '2018-01-01' SET a = 100;
+ERROR 42S02: 'v1' is a view
+DROP VIEW v1;
+DROP TABLE t1;
diff --git a/mysql-test/suite/period/r/versioning.result b/mysql-test/suite/period/r/versioning.result
new file mode 100644
index 00000000..6a55e482
--- /dev/null
+++ b/mysql-test/suite/period/r/versioning.result
@@ -0,0 +1,90 @@
+# DELETE
+create table t (
+s date, e date,
+row_start SYS_TYPE as row start invisible,
+row_end SYS_TYPE as row end invisible,
+period for apptime(s, e),
+period for system_time (row_start, row_end)) with system versioning;
+insert into t values('1999-01-01', '2018-12-12'),
+('1999-01-01', '1999-12-12');
+select row_start into @ins_time from t limit 1;
+select * from t order by s, e;
+s e
+1999-01-01 1999-12-12
+1999-01-01 2018-12-12
+delete from t for portion of apptime from '2000-01-01' to '2018-01-01';
+select *, if(row_start = @ins_time, "OLD", "NEW"), check_row(row_start, row_end)
+from t for system_time all
+order by s, e, row_start;
+s e if(row_start = @ins_time, "OLD", "NEW") check_row(row_start, row_end)
+1999-01-01 1999-12-12 OLD CURRENT ROW
+1999-01-01 2000-01-01 NEW CURRENT ROW
+1999-01-01 2018-12-12 OLD HISTORICAL ROW
+2018-01-01 2018-12-12 NEW CURRENT ROW
+# same for trigger case
+delete from t;
+delete history from t;
+insert into t values('1999-01-01', '2018-12-12'),
+('1999-01-01', '1999-12-12');
+create or replace table log_tbl(id int auto_increment primary key, log text) engine=myisam;
+create or replace procedure log(s text)
+insert into log_tbl(log) values(s);
+create trigger tr1upd_t before update on t
+for each row call log(CONCAT('>UPD: ', old.s, ", ", old.e, ' -> ', new.s, ", ", new.e));
+create trigger tr2upd_t after update on t
+for each row call log(CONCAT('<UPD: ', old.s, ", ", old.e, ' -> ', new.s, ", ", new.e));
+create trigger tr1del_t before delete on t
+for each row call log(CONCAT('>DEL: ', old.s, ", ", old.e));
+create trigger tr2del_t after delete on t
+for each row call log(CONCAT('<DEL: ', old.s, ", ", old.e));
+create trigger tr1ins_t before insert on t
+for each row call log(CONCAT('>INS: ', new.s, ", ", new.e));
+create trigger tr2ins_t after insert on t
+for each row call log(CONCAT('<INS: ', new.s, ", ", new.e));
+select row_start into @ins_time from t limit 1;
+select * from t order by s, e;
+s e
+1999-01-01 1999-12-12
+1999-01-01 2018-12-12
+delete from t for portion of apptime from '2000-01-01' to '2018-01-01';
+select *, if(row_start = @ins_time, "OLD", "NEW"), check_row(row_start, row_end)
+from t for system_time all
+order by s, e, row_start;
+s e if(row_start = @ins_time, "OLD", "NEW") check_row(row_start, row_end)
+1999-01-01 1999-12-12 OLD CURRENT ROW
+1999-01-01 2000-01-01 NEW CURRENT ROW
+1999-01-01 2018-12-12 OLD HISTORICAL ROW
+2018-01-01 2018-12-12 NEW CURRENT ROW
+select * from log_tbl order by id;
+id log
+1 >DEL: 1999-01-01, 2018-12-12
+2 >INS: 1999-01-01, 2000-01-01
+3 <INS: 1999-01-01, 2000-01-01
+4 >INS: 2018-01-01, 2018-12-12
+5 <INS: 2018-01-01, 2018-12-12
+6 <DEL: 1999-01-01, 2018-12-12
+# UPDATE
+create or replace table t (x int, s date, e date,
+row_start SYS_TYPE as row start invisible,
+row_end SYS_TYPE as row end invisible,
+period for apptime(s, e),
+period for system_time(row_start, row_end)) with system versioning;
+insert into t values(1, '1999-01-01', '2018-12-12'),
+(2, '1999-01-01', '1999-12-12');
+select row_start into @ins_time from t limit 1;
+select * from t;
+x s e
+1 1999-01-01 2018-12-12
+2 1999-01-01 1999-12-12
+update t for portion of apptime from '2000-01-01' to '2018-01-01' set x= x + 5;
+select *, if(row_start = @ins_time, "OLD", "NEW"), check_row(row_start, row_end)
+from t for system_time all
+order by x, s, e, row_start;
+x s e if(row_start = @ins_time, "OLD", "NEW") check_row(row_start, row_end)
+1 1999-01-01 2000-01-01 NEW CURRENT ROW
+1 1999-01-01 2018-12-12 OLD HISTORICAL ROW
+1 2018-01-01 2018-12-12 NEW CURRENT ROW
+2 1999-01-01 1999-12-12 OLD CURRENT ROW
+6 2000-01-01 2018-01-01 NEW CURRENT ROW
+drop table t,log_tbl;
+drop procedure log;
diff --git a/mysql-test/suite/period/t/alter.test b/mysql-test/suite/period/t/alter.test
new file mode 100644
index 00000000..fab933ec
--- /dev/null
+++ b/mysql-test/suite/period/t/alter.test
@@ -0,0 +1,192 @@
+--source include/have_partition.inc
+
+set @s= '1992-01-01';
+set @e= '1999-12-31';
+
+create table t (s date, e date);
+
+--echo # period start/end columns are implicit NOT NULL
+alter table t add period for a(s, e);
+show create table t;
+
+create or replace table t (s date, e date);
+alter table t change s s date, add period for a(s, e);
+show create table t;
+
+alter table t add id int;
+show create table t;
+alter table t drop id;
+show create table t;
+
+--error ER_CONSTRAINT_FAILED
+insert t values(@e, @s);
+
+--error ER_PERIOD_CONSTRAINT_DROP
+alter table t drop constraint a;
+
+--echo # no-op
+alter table t drop period if exists for b;
+--echo # no-op
+alter table t add period if not exists for a(e, s);
+
+alter table t drop period if exists for a;
+--echo # no-op
+alter table t drop period if exists for a;
+
+alter table t add period for a(s, e), add period if not exists for a(e, s);
+show create table t;
+
+alter table t drop period for a;
+--echo # Constraint is dropped
+insert t values(@e, @s);
+
+--error ER_CANT_DROP_FIELD_OR_KEY
+alter table t drop period for a;
+--error ER_CANT_DROP_FIELD_OR_KEY
+alter table t add period for a(s, e), drop period for a;
+
+truncate t;
+alter table t add period for a(s, e);
+--error ER_CONSTRAINT_FAILED
+insert t values(@e, @s);
+alter table t add period for a(s, e), drop period for a;
+--error ER_CONSTRAINT_FAILED
+insert t values(@e, @s);
+alter table t add s1 date not null, add period for b(s1, e), drop period for a;
+show create table t;
+insert t(s, s1, e) values(@e, @s, @e);
+--error ER_CONSTRAINT_FAILED
+insert t(s, s1, e) values(@e, @e, @s);
+
+create table t1 like t;
+show create table t1;
+drop table t1;
+
+--error ER_CONSTRAINT_FAILED
+create table t2 (period for b(s,e)) select * from t;
+
+create table t2 (period for b(s1,e)) select * from t;
+drop table t2;
+
+--echo # SQL16 11.27 <add table period definition>, Syntax Rules, 5)g)
+--echo # The declared type of BC1 shall be either DATE or a timestamp type
+--echo # and shall be equivalent to the declared type of BC2.
+create or replace table t (s timestamp not null, e timestamp(6) not null);
+--error ER_PERIOD_TYPES_MISMATCH
+alter table t add period for a(s, e);
+
+--echo # SQL16 11.27 <add table period definition>, Syntax Rules, 5)c)
+--echo # No column of T shall have a column name that is equivalent to ATPN.
+create or replace table t (a int, s date, e date);
+--error ER_DUP_FIELDNAME
+alter table t add period for a(s, e);
+
+--echo # SQL16 11.27 <add table period definition>, Syntax Rules, 5)i)
+--echo # Neither BC1 nor BC2 shall be an identity column, a generated column,
+--echo # a system-time period start column, or a system-time period end column.
+create or replace table t (id int primary key,
+ s date,
+ e date generated always as (s+1));
+--error ER_PERIOD_FIELD_WRONG_ATTRIBUTES
+alter table t add period for a(s, e);
+
+create or replace table t (id int primary key,
+ s date,
+ e date as (s+1) VIRTUAL);
+--error ER_PERIOD_FIELD_WRONG_ATTRIBUTES
+alter table t add period for a(s, e);
+
+create or replace table t (id int primary key, s timestamp(6), e timestamp(6),
+ st timestamp(6) as row start,
+ en timestamp(6) as row end,
+ period for system_time (st, en)) with system versioning;
+--error ER_PERIOD_FIELD_WRONG_ATTRIBUTES
+alter table t add period for a(s, en);
+
+--echo # SQL16 11.27 <add table period definition>, Syntax Rules, 5)b)
+--echo # The table descriptor of T shall not include a period descriptor other
+--echo # than a system-time period descriptor.
+alter table t add period for a(s, e);
+--error ER_MORE_THAN_ONE_PERIOD
+alter table t add period for b(s, e);
+
+--echo # SQL16, Part 2, 11.3 <table definition>, Syntax Rules, 2)e)v)2)B)
+--echo # Let S be the schema identified by the explicit or implicit
+--echo # <schema name> of TN. Let IDCN be an implementation-dependent
+--echo # <constraint name> that is not equivalent to the <constraint name> of
+--echo # any table constraint descriptor included in S. The following
+--echo # <table constraint definition> is implicit:
+--echo # CONSTRAINT IDCN CHECK ( CN1 < CN2 )
+--echo #
+--echo # Due to the above standard limitation, the constraint name can't always
+--echo # match the period name. So it matches when possible; and when not, it
+--echo # is unique not taken name prefixed with period name.
+create or replace table t (x int, s date, e date,
+ period for mytime(s, e));
+show create table t;
+alter table t add constraint mytime check (x > 1);
+show create table t;
+--error ER_CONSTRAINT_FAILED
+insert t values (2, @e, @s);
+alter table t add constraint mytime_1 check (x > 2);
+--error ER_CONSTRAINT_FAILED
+insert t values (3, @e, @s);
+
+drop table t;
+
+--echo #
+--echo # MDEV-20494 ER_NOT_FORM_FILE or assertion upon adding partition to period table
+--echo #
+create table t1 (f date, t date, period for app(f,t)) with system versioning partition by system_time ( partition p1 history, partition pn current );
+lock table t1 write;
+alter table t1 add partition (partition p2 history);
+unlock tables;
+
+create or replace table t1 (x int, s date, e date, period for app(s,e));
+insert into t1 values(1, '2020-03-01', '2020-03-02');
+insert into t1 values(1, '2020-03-01', '2020-03-02');
+--error ER_DUP_ENTRY
+alter table t1 add primary key(x, s, e);
+alter table t1 add system versioning;
+
+# cleanup
+drop table t1;
+
+--echo #
+--echo # MDEV-18873 Server crashes in Compare_identifiers::operator or in
+--echo # my_strcasecmp_utf8 upon ADD PERIOD IF NOT EXISTS with empty name
+--echo #
+
+# When there is no table defined.
+--error ER_WRONG_COLUMN_NAME
+alter table t add period if not exists for `` (s,e);
+
+# When there is an actual table.
+create table t(s DATE, e DATE);
+--error ER_WRONG_COLUMN_NAME
+alter table t add period if not exists for `` (s,e);
+
+# When the last character is space
+--error ER_WRONG_COLUMN_NAME
+alter table t add period if not exists for ` ` (s,e);
+
+# Create table with an empty period name
+--error ER_WRONG_COLUMN_NAME
+create table t2 (period for `` (s,e)) select * from t;
+drop table t;
+
+--echo #
+--echo # MDEV-21941 RENAME doesn't work for system time or period fields
+--echo #
+create or replace table t1 (
+ a int, s date, e date,
+ period for mytime(s, e));
+
+alter table t1 rename column s to x;
+alter table t1 rename column e to y;
+
+show create table t1;
+# cleanup
+drop table t1;
+
+--echo # End of 10.5 tests
diff --git a/mysql-test/suite/period/t/create.test b/mysql-test/suite/period/t/create.test
new file mode 100644
index 00000000..0bca5b6d
--- /dev/null
+++ b/mysql-test/suite/period/t/create.test
@@ -0,0 +1,101 @@
+create table t (id int primary key, s date, e date, period for mytime(s,e));
+--echo # CONSTRAINT CHECK (s < e) is added implicitly, and shouldn't be shown
+--echo # this is important for correct command-based replication
+show create table t;
+create or replace table t (id int primary key, s timestamp(6), e timestamp(6),
+ period for mytime(s,e));
+show create table t;
+
+--echo # SQL16, Part 2, 11.3 <table definition>, Syntax Rules, 2)a)
+--echo # 2) If a <table period definition> TPD is specified, then:
+--echo # a) <table scope> shall not be specified.
+--error ER_PERIOD_TEMPORARY_NOT_ALLOWED
+create or replace temporary table t (s date, e date, period for mytime(s,e));
+
+--echo # SQL16, Part 2, 11.3 <table definition>, Syntax Rules, 2)e)iii)
+--echo # The <data type or domain name> contained in CD1 is either DATE or a
+--echo # timestamp type and it is equivalent to the <data type or domain name>
+--echo # contained in CD2.
+--error ER_PERIOD_TYPES_MISMATCH
+create or replace table t (id int primary key, s datetime, e date,
+ period for mytime(s,e));
+--error ER_PERIOD_TYPES_MISMATCH
+create or replace table t (s timestamp(2), e timestamp(6),
+ period for mytime(s,e));
+--error ER_WRONG_FIELD_SPEC
+create or replace table t (id int primary key, s int, e date,
+ period for mytime(s,e));
+--error ER_WRONG_FIELD_SPEC
+create or replace table t (id int primary key, s time, e time,
+ period for mytime(s,e));
+--error ER_BAD_FIELD_ERROR
+create or replace table t (id int primary key, s date, e date,
+ period for mytime(s,x));
+
+--echo # MDEV-18842: Unfortunate error message when the same column is used
+--echo # for application period start and end
+--error ER_FIELD_SPECIFIED_TWICE
+create or replace table t (s date, t date, period for apt(s,s));
+
+--error ER_MORE_THAN_ONE_PERIOD
+create or replace table t (id int primary key, s date, e date,
+ period for mytime(s,e),
+ period for mytime2(s,e));
+
+--echo # SQL16, Part 2, 11.3 <table definition>, Syntax Rules, 2)d)
+--echo # No <column name> in any <column definition> shall be equivalent to PN.
+--error ER_DUP_FIELDNAME
+create or replace table t (mytime int, s date, e date,
+ period for mytime(s,e));
+
+--echo # SQL16, Part 2, 11.3 <table definition>, Syntax Rules, 2)e)v)2)A)
+--echo # Neither CD1 nor CD2 shall contain an <identity column specification>, a
+--echo # <generation clause>, a <system time period start column specification>,
+--echo # or a <system time period end column specification>.
+--error ER_PERIOD_FIELD_WRONG_ATTRIBUTES
+create or replace table t (id int primary key,
+ s date,
+ e date generated always as (s+1),
+ period for mytime(s,e));
+
+--error ER_PERIOD_FIELD_WRONG_ATTRIBUTES
+create or replace table t (id int primary key,
+ s date,
+ e date as (s+1) VIRTUAL,
+ period for mytime(s,e));
+
+--error ER_PERIOD_FIELD_WRONG_ATTRIBUTES
+create or replace table t (id int primary key, s timestamp(6), e timestamp(6),
+ st timestamp(6) as row start,
+ en timestamp(6) as row end,
+ period for system_time (st, en),
+ period for mytime(st,e)) with system versioning;
+
+--echo # SQL16, Part 2, 11.3 <table definition>, Syntax Rules, 2)
+--echo # Let IDCN be an implementation-dependent <constraint name> that is not
+--echo # equivalent to the <constraint name> of any table constraint descriptor
+--echo # included in S.
+create or replace table t (x int, s date, e date,
+ period for mytime(s, e),
+ constraint mytime check (x > 1));
+show create table t;
+--error ER_CONSTRAINT_FAILED
+insert t values (2, '2001-01-01', '2001-01-01');
+
+show status like "Feature_application_time_periods";
+
+drop table t;
+
+--echo # MDEV-29387: Period name with more than 32 symbols crashes the server
+--echo #
+
+--echo # test 34 symbols
+create table t2 (s date, e date,
+ period for `abcd123456789012345678901234567890` (s,e));
+drop table t2;
+
+--echo # test 64 symbols
+create table t2 (s date, e date, period for
+ `abcd123456789012345678901234567890123456789012345678901234567890`
+ (s,e));
+drop table t2;
diff --git a/mysql-test/suite/period/t/delete.test b/mysql-test/suite/period/t/delete.test
new file mode 100644
index 00000000..676fa256
--- /dev/null
+++ b/mysql-test/suite/period/t/delete.test
@@ -0,0 +1,270 @@
+source suite/period/engines.inc;
+source include/have_log_bin.inc;
+source include/have_partition.inc;
+
+create table t (id int, s date, e date, period for apptime(s,e));
+
+insert into t values(1, '1999-01-01', '2018-12-12');
+insert into t values(1, '1999-01-01', '2017-01-01');
+insert into t values(1, '2017-01-01', '2019-01-01');
+insert into t values(2, '1998-01-01', '2018-12-12');
+insert into t values(3, '1997-01-01', '2015-01-01');
+insert into t values(4, '2016-01-01', '2020-01-01');
+insert into t values(5, '2010-01-01', '2015-01-01');
+
+create or replace table t1 (id int, s date, e date, period for apptime(s,e));
+insert t1 select * from t;
+create or replace table t2 (id int, s date, e date, period for apptime(s,e));
+insert t2 select * from t;
+create or replace table t3 (id int, s date, e date, period for apptime(s,e));
+insert t3 select * from t;
+
+--let $trig_cols=id, s, e
+--let $trig_table=t1
+--source suite/period/create_triggers.inc
+
+delete from t for portion of apptime from '2000-01-01' to '2018-01-01';
+delete from t1 for portion of APPTIME from '2000-01-01' to '2018-01-01';
+--sorted_result
+select * from t;
+--sorted_result
+select * from t1;
+select * from log_tbl order by id;
+
+--echo # INSERT trigger only also works
+--let $trig_cols=id, s, e
+--let $trig_table=t2
+--source suite/period/create_triggers.inc
+drop trigger tr1del_t2;
+drop trigger tr2del_t2;
+delete from t2 for portion of APPTIME from '2000-01-01' to '2018-01-01';
+select * from log_tbl order by id;
+
+--echo # removing BEFORE INSERT trigger enables internal substitution
+--echo # DELETE+INSERT -> UPDATE, but without any side effects.
+--echo # The optimization is disabled for non-transactional engines
+--let $trig_table=t3
+--source suite/period/create_triggers.inc
+drop trigger tr1ins_t3;
+delete from t3 for portion of APPTIME from '2000-01-01' to '2018-01-01';
+select * from log_tbl order by id;
+
+--echo # multi-table DELETE is not possible
+--error ER_PARSE_ERROR
+delete t, t1 from t1, t for portion of apptime from '2000-01-01' to '2018-01-01';
+
+--error ER_PARSE_ERROR
+delete t for portion of apptime from '2000-01-01' to '2018-01-01', t1 from t, t1;
+
+--echo # Here another check fails before parsing ends
+--error ER_UNKNOWN_TABLE
+delete t, t1 from t for portion of apptime from '2000-01-01' to '2018-01-01', t1;
+
+--error ER_PARSE_ERROR
+delete history from t2 for portion of apptime from '2000-01-01' to '2018-01-01';
+
+--error ER_PERIOD_NOT_FOUND
+delete from t for portion of othertime from '2000-01-01' to '2018-01-01';
+--error ER_PARSE_ERROR
+delete from t for portion of system_time from '2000-01-01' to '2018-01-01';
+
+--echo # MDEV-22596 DELETE FOR PORTION does not obey
+--echo # "Expression in FOR PORTION OF must be constant" limitation, data can be easily lost
+--error ER_NOT_CONSTANT_EXPRESSION
+delete from t for portion of apptime from s to e;
+
+create or replace table t (id int, str text, s date, e date,
+ period for apptime(s,e));
+
+insert into t values(1, 'data', '1999-01-01', '2018-12-12');
+insert into t values(1, 'other data', '1999-01-01', '2018-12-12');
+insert into t values(1, 'deleted', '2000-01-01', '2018-01-01');
+delete from t for portion of apptime from '2000-01-01' to '2018-01-01';
+show warnings;
+--sorted_result
+select * from t;
+
+drop table t1;
+
+--echo # SQL16, Part 2, 15.7 <Effect of deleting rows from base tables>,
+--echo # General rules, 8)b)i)
+--echo # If the column descriptor that corresponds to the i-th field of BR
+--echo # describes an identity column, a generated column, a system-time period
+--echo # start column, or a system-time period end column, then let V i be
+--echo # DEFAULT.
+
+--echo # auto_increment field is updated
+create or replace table t (id int primary key auto_increment, s date, e date,
+ period for apptime(s, e));
+insert into t values (default, '1999-01-01', '2018-12-12');
+select * from t;
+delete from t for portion of apptime from '2000-01-01' to '2018-01-01';
+--sorted_result
+select * from t;
+truncate t;
+--echo # same for trigger case
+insert into t values (default, '1999-01-01', '2018-12-12');
+--let $trig_table=t
+--source suite/period/create_triggers.inc
+
+delete from t for portion of apptime from '2000-01-01' to '2018-01-01';
+--sorted_result
+select * from t;
+select * from log_tbl order by id;
+
+--echo # generated columns are updated
+create or replace table t (s date, e date,
+ xs date as (s) stored, xe date as (e) stored,
+ period for apptime(s, e));
+insert into t values('1999-01-01', '2018-12-12', default, default);
+--sorted_result
+select * from t;
+delete from t for portion of apptime from '2000-01-01' to '2018-01-01';
+--sorted_result
+select * from t;
+truncate t;
+--echo # same for trigger case
+insert into t values('1999-01-01', '2018-12-12', default, default);
+--let $trig_table=t
+--source suite/period/create_triggers.inc
+
+delete from t for portion of apptime from '2000-01-01' to '2018-01-01';
+--sorted_result
+select * from t;
+select * from log_tbl order by id;
+
+--echo # View can't be used
+create or replace view v as select * from t;
+--error ER_IT_IS_A_VIEW
+delete from v for portion of p from '2000-01-01' to '2018-01-01';
+
+--echo # View can't be used
+create or replace view v as select t.* from t, t as t1;
+--error ER_VIEW_DELETE_MERGE_VIEW
+delete from v for portion of p from '2000-01-01' to '2018-01-01';
+
+--echo # auto_increment field overflow
+create or replace table t (id tinyint auto_increment primary key,
+ s date, e date, period for apptime(s,e));
+
+insert into t values(127, '1999-01-01', '2018-12-12');
+
+--error HA_ERR_AUTOINC_ERANGE
+delete from t for portion of apptime from '2000-01-01' to '2018-01-01';
+select * from t;
+
+--echo # same for trigger case
+--let $trig_table=t
+--source suite/period/create_triggers.inc
+--echo # negotiate side effects of non-transactional MyISAM engine
+replace into t values(127, '1999-01-01', '2018-12-12');
+select * from t;
+truncate table log_tbl;
+
+--error HA_ERR_AUTOINC_ERANGE
+delete from t for portion of apptime from '2000-01-01' to '2018-01-01';
+select * from t;
+select * from log_tbl order by id;
+
+--echo # custom constraint for period fields
+create or replace table t(id int, s date, e date, period for apptime(s,e),
+ constraint dist2days check (datediff(e, s) >= 2));
+insert into t values(1, '1999-01-01', '2018-12-12'),
+ (2, '1999-01-01', '1999-12-12');
+--error ER_CONSTRAINT_FAILED
+delete from t for portion of apptime from '1999-01-02' to '2018-12-12';
+--echo # negotiate side effects of non-transactional MyISAM engine
+truncate t;
+insert into t values(1, '1999-01-01', '2018-12-12'),
+ (2, '1999-01-01', '1999-12-12');
+--error ER_CONSTRAINT_FAILED
+delete from t for portion of apptime from '1999-01-01' to '2018-12-11';
+truncate t;
+insert into t values(1, '1999-01-01', '2018-12-12'),
+ (2, '1999-01-01', '1999-12-12');
+
+delete from t for portion of apptime from '1999-01-03' to '2018-12-10';
+--sorted_result
+select *, datediff(e, s) from t;
+
+--echo #
+--echo # MDEV-18929 2nd execution of SP does not detect ER_VERS_NOT_VERSIONED
+--echo #
+create or replace table t1 (id int, s date, e date, period for apptime(s,e));
+create or replace procedure sp()
+delete from t1 for portion of othertime from '2000-01-01' to '2018-01-01';
+--error ER_PERIOD_NOT_FOUND
+call sp;
+--error ER_PERIOD_NOT_FOUND
+call sp;
+drop table t1;
+drop procedure sp;
+
+drop table t,t2,t3,log_tbl;
+drop view v;
+drop procedure log;
+
+--echo # MDEV-19130 Assertion
+--echo # `next_insert_id >= auto_inc_interval_for_cur_row.minimum()'
+--echo # failed in handler::update_auto_increment after error 167
+
+create or replace table t (f tinyint auto_increment null,
+ s timestamp, e timestamp,
+ period for app(s,e), key(f, s));
+insert into t (s,e) values
+ ('2021-08-22 10:28:43', '2023-09-17 00:00:00'),
+ ('2019-05-09 21:45:24', '2020-04-22 14:38:49');
+insert into t (s,e) select s,e from t;
+insert into t (s,e) select s,e from t;
+insert into t (s,e) select s,e from t;
+insert into t (s,e) values ('2015-07-07 00:00:00','2020-03-11 08:48:52');
+insert into t (s,e) select s,e from t;
+insert into t (s,e) select s,e from t;
+
+--replace_regex /row \d+/row ROW/
+--error HA_ERR_AUTOINC_ERANGE
+insert into t select * from t;
+
+--disable_warnings
+delete ignore from t
+ for portion of app from '2015-07-07 00:00:00' to '2020-03-11 08:48:52';
+--enable_warnings
+
+drop table t;
+
+#
+# MDEV-22424 Server crashes in handler::check_duplicate_long_entry_key or Assertion `inited == NONE || lookup_handler != this' failed upon DELETE FOR PORTION on table with long unique key
+#
+create table t1 (pk int, s date, e date, period for se (s,e), primary key (pk,se without overlaps));
+insert into t1 values (1,'2020-01-01','2020-02-20');
+delete from t1 for portion of se from '2020-01-30' to '2020-01-31';
+drop table t1;
+
+--echo # End of 10.5 tests
+--echo #
+--echo # MDEV-19190 Assertion `part_share->auto_inc_initialized` failed in
+--echo # ha_partition::get_auto_increment
+--echo #
+create table t1 (id int, s date, e date, period for app(s,e))
+ partition by key(id);
+insert into t1 (s,e) values ('2023-07-21','2024-06-07');
+alter table t1 modify id int auto_increment key;
+delete from t1 for portion of app from '2023-07-20' to '2024-05-23';
+select * from t1;
+drop table t1;
+
+create table t1 (id int, s date, e date, period for app(s,e))
+ partition by key(id);
+insert into t1 (s,e) values ('2023-07-21','2024-06-07');
+alter table t1 modify id int auto_increment key;
+--let $trig_table=t1
+--let $trig_cols=id, s, e
+--disable_query_log
+--source suite/period/create_triggers.inc
+--enable_query_log
+
+delete from t1 for portion of app from '2023-07-20' to '2024-05-23';
+select * from t1;
+drop table t1;
+drop table log_tbl;
+drop procedure log;
diff --git a/mysql-test/suite/period/t/long_unique.test b/mysql-test/suite/period/t/long_unique.test
new file mode 100644
index 00000000..c2dcd3f6
--- /dev/null
+++ b/mysql-test/suite/period/t/long_unique.test
@@ -0,0 +1,23 @@
+--source include/have_partition.inc
+
+--echo #
+--echo # Assertion `inited == NONE || update_handler != this' failed in
+--echo # handler::ha_write_row
+--echo #
+
+CREATE TABLE t1 (f VARCHAR(4096), s DATE, e DATE, PERIOD FOR app(s,e), UNIQUE(f)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('foo', '2023-08-30', '2025-07-09'),('bar', '2021-01-01', '2021-12-31');
+DELETE FROM t1 FOR PORTION OF app FROM '2023-08-29' TO '2025-07-01';
+DROP TABLE t1;
+
+--echo #
+--echo # MDEV-21819 Assertion `inited == NONE || update_handler != this'
+--echo # failed in handler::ha_write_row
+--echo #
+
+CREATE OR REPLACE TABLE t1 (a INT, b BLOB, s DATE, e DATE, PERIOD FOR app(s,e), UNIQUE(b)) ENGINE=MyISAM PARTITION BY HASH(a) PARTITIONS 2;
+INSERT INTO t1 VALUES (1,'foo','2022-01-01', '2025-01-01');
+--error ER_DUP_ENTRY
+DELETE FROM t1 FOR PORTION OF app FROM '2023-01-01' TO '2024-01-01';
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/period/t/overlaps.test b/mysql-test/suite/period/t/overlaps.test
new file mode 100644
index 00000000..4e71d64d
--- /dev/null
+++ b/mysql-test/suite/period/t/overlaps.test
@@ -0,0 +1,460 @@
+--source include/have_partition.inc
+
+# Test both myisam and innodb
+--source suite/period/engines.inc
+
+let $default_engine= `select @@default_storage_engine`;
+
+create or replace table t(id int, s date, e date,
+ period for p(s,e),
+ primary key(id, p without overlaps)
+) partition by key (id);
+
+--replace_result $default_engine DEFAULT_ENGINE
+show create table t;
+
+
+insert into t values (1, '2003-01-01', '2003-03-01'),
+ (1, '2003-05-01', '2003-07-01');
+
+--error ER_DUP_ENTRY
+insert into t values (1, '2003-02-01', '2003-04-01');
+--error ER_DUP_ENTRY
+insert into t values (1, '2003-04-01', '2003-06-01');
+--error ER_DUP_ENTRY
+insert into t values (1, '2003-05-15', '2003-06-15');
+--error ER_DUP_ENTRY
+insert into t values (1, '2003-04-01', '2003-08-01');
+
+insert into t values (1, '2003-03-01', '2003-05-01');
+
+--echo # expand/shrink period
+update t set s= '2002-12-01' where s = '2003-01-01';
+update t set s= '2003-01-01' where s = '2002-12-01';
+
+update t set e= '2003-08-01' where s = '2003-05-01';
+update t set e= '2003-07-01' where s = '2003-05-01';
+
+--echo # move left/right
+update t set s= '2002-12-15', e= '2003-01-15' where s = '2003-01-01';
+update t set s= '2003-01-01', e= '2003-02-01' where s = '2002-12-15';
+
+--echo # diminish/enlarge
+update t set s= '2003-01-10', e= '2003-01-20' where s = '2003-01-01';
+update t set s= '2003-01-01', e= '2003-02-01' where s = '2003-01-10';
+
+select * from t;
+
+--echo # intersect left/right, strict inclusion/containment
+--error ER_DUP_ENTRY
+update t set e= '2003-04-01' where s = '2003-01-01';
+--error ER_DUP_ENTRY
+update t set s= '2003-04-01' where s = '2003-05-01';
+--error ER_DUP_ENTRY
+update t set s= '2003-03-10', e= '2003-03-20' where s = '2003-01-01';
+--error ER_DUP_ENTRY
+update t set s= '2003-04-01', e= '2003-08-01' where s = '2003-03-01';
+
+--echo # inclusion/containment with partial match
+--error ER_DUP_ENTRY
+update t set s= '2003-03-01', e= '2003-04-01' where s = '2003-01-01';
+--error ER_DUP_ENTRY
+update t set s= '2003-04-01', e= '2003-05-01' where s = '2003-01-01';
+--error ER_DUP_ENTRY
+update t set s= '2003-03-01' where s = '2003-05-01';
+--error ER_DUP_ENTRY
+update t set e= '2003-05-01' where s = '2003-01-01';
+
+select * from t where year(s) = 2003;
+
+--echo # UPDATE ... FOR PORTION test
+insert t values (2, '2003-04-15', '2003-05-01');
+
+update t for portion of p from '2003-01-01' to '2003-01-15'
+ set id= 2;
+--sorted_result
+select * from t;
+
+update t for portion of p from '2003-01-15' to '2003-02-01'
+ set id= 2;
+--sorted_result
+select * from t;
+
+--echo # Next, test UPDATE ... FOR PORTION resulting with an error
+--echo # Since MyISAM/Aria engines lack atomicity, the results would differ with
+--echo # innodb. So a table is going to be copied to one with explicit engine.
+
+create table t_myisam (id int, s date, e date,
+ period for p(s,e),
+ primary key(id, p without overlaps))
+ engine=myisam
+ select * from t;
+--error ER_DUP_ENTRY
+update t_myisam for portion of p from '2003-04-01' to '2003-06-01'
+ set id= 2 order by s desc;
+--sorted_result
+select * from t_myisam;
+
+create table t_innodb (id int, s date, e date,
+ period for p(s,e),
+ primary key(id, p without overlaps))
+ engine=innodb
+ select * from t;
+--error ER_DUP_ENTRY
+update t_innodb for portion of p from '2003-04-01' to '2003-06-01'
+ set id= 2 order by s desc;
+--sorted_result
+select * from t_innodb;
+
+drop table t_myisam, t_innodb;
+
+--error ER_PERIOD_NOT_FOUND
+create or replace table t(id int, s date, e date,
+ period for p(s,e),
+ primary key(id, q without overlaps));
+
+--error ER_PERIOD_NOT_FOUND
+create or replace table t(id int, s date, e date,
+ primary key(id, p without overlaps));
+
+--error ER_KEY_CONTAINS_PERIOD_FIELDS
+create or replace table t(id int, s date, e date,
+ period for p(s,e),
+ primary key(id, s, p without overlaps));
+
+create or replace table t(id int, s date, e date,
+ period for p(s,e),
+ primary key(id));
+insert into t values (1, '2003-03-01', '2003-05-01');
+--error ER_DUP_ENTRY
+insert into t values (1, '2003-04-01', '2003-05-01');
+
+create or replace table t(id int, u int, s date, e date,
+ period for p(s,e),
+ primary key(id, p without overlaps),
+ unique(u));
+--replace_result $default_engine DEFAULT_ENGINE
+show create table t;
+insert into t values (1, 1, '2003-03-01', '2003-05-01');
+insert into t values (1, 2, '2003-05-01', '2003-07-01');
+--error ER_DUP_ENTRY
+insert into t values (1, 3, '2003-04-01', '2003-05-01');
+
+
+
+create or replace table t(id int, u int, s date, e date,
+ period for p(s,e),
+ primary key(id, p without overlaps),
+ unique(u, p without overlaps));
+--replace_result $default_engine DEFAULT_ENGINE
+show create table t;
+
+insert into t values (2, NULL, '2003-03-01', '2003-05-01');
+--error ER_DUP_ENTRY
+insert into t values (2, NULL, '2003-03-01', '2003-05-01');
+insert into t values (3, NULL, '2003-03-01', '2003-05-01');
+insert into t values (1, 1, '2003-03-01', '2003-05-01');
+insert into t values (1, 2, '2003-05-01', '2003-07-01');
+insert into t values (4, NULL, '2003-03-01', '2003-05-01');
+
+create sequence seq start=5 engine=myisam;
+update t set id= nextval(seq), u= nextval(seq), s='2003-05-01', e='2003-07-01'
+ where u is NULL;
+
+--sorted_result
+select * from t;
+drop sequence seq;
+
+create or replace table t(id int, s date, e date,
+ period for p(s,e));
+
+insert into t values (1, '2003-01-01', '2003-03-01'),
+ (1, '2003-05-01', '2003-07-01'),
+ (1, '2003-02-01', '2003-04-01');
+
+--replace_regex /#sql-\w+/#sql-temp/
+--error ER_DUP_ENTRY
+alter table t add primary key(id, p without overlaps);
+
+--echo # Historical rows are not checked against constraints
+set @@system_versioning_alter_history= keep;
+alter table t add system versioning;
+delete from t;
+alter table t add primary key(id, p without overlaps);
+
+insert into t values (1, '2003-01-01', '2003-03-01'),
+ (1, '2003-03-01', '2003-05-01');
+
+
+--echo # `without overlaps` is not lost on alter table
+alter table t add y int;
+--replace_result $default_engine DEFAULT_ENGINE
+show create table t;
+alter table t drop y;
+
+create or replace table t1 like t;
+--replace_result $default_engine DEFAULT_ENGINE
+show create table t1;
+
+create or replace table t1 (x int, s date, e date,
+ period for p(s,e),
+ primary key(x, p without overlaps));
+alter table t1 partition by key (x);
+
+create or replace table t1 (x int, s date, e date, period for p (s, e))
+ partition by hash (x);
+alter table t1 add primary key (x, p without overlaps);
+
+--error ER_PARSE_ERROR
+create or replace table t2 (x int, s date, e date,
+ period for p (s, e),
+ key(x, p without overlaps));
+
+--error ER_PARSE_ERROR
+create or replace table t2 (x int, s date, e date,
+ period for p (s, e),
+ unique(x, p without overlaps, x, p without overlaps));
+
+create or replace table t1 (x varchar(100), s date, e date,
+ period for p(s,e),
+ primary key(x, p without overlaps));
+
+--error ER_COMPRESSED_COLUMN_USED_AS_KEY
+create or replace table t1 (x varchar(100) compressed, s date, e date,
+ period for p(s,e),
+ primary key(x, p without overlaps));
+
+--error ER_KEY_CANT_HAVE_WITHOUT_OVERLAPS
+create or replace table t (x int, s date, e date, period for apptime(s,e),
+ unique(x, apptime without overlaps) using hash);
+
+--error ER_KEY_CANT_HAVE_WITHOUT_OVERLAPS
+create or replace table t (x int, s date, e date, period for apptime(s,e),
+ b blob, unique(x, b, apptime without overlaps));
+
+create or replace table t (x int, s date, e date, b blob unique,
+ period for apptime(s,e),
+ unique(x, apptime without overlaps));
+
+insert into t values (1, '2020-03-01', '2020-03-05', 'test');
+--error ER_DUP_ENTRY
+insert into t values (1, '2020-03-05', '2020-03-10', 'test');
+insert into t values (1, '2020-03-05', '2020-03-10', 'test2');
+--error ER_DUP_ENTRY
+insert into t values (1, '2020-03-03', '2020-03-10', 'test3');
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+create or replace table t (x int, s date, e date, period for apptime(s,e),
+ unique(x, apptime without overlaps));
+--error ER_NOT_SUPPORTED_YET
+replace into t values (1, '2020-03-03', '2020-03-10');
+--error ER_NOT_SUPPORTED_YET
+insert into t values (1, '2020-03-03', '2020-03-10')
+ on duplicate key update x = 2;
+
+select * from t;
+--disable_ps2_protocol
+select * into outfile 'tmp_t.txt' from t;
+--enable_ps2_protocol
+load data infile 'tmp_t.txt' into table t;
+--error ER_NOT_SUPPORTED_YET
+load data infile 'tmp_t.txt' replace into table t;
+remove_file $MYSQLD_DATADIR/test/tmp_t.txt;
+
+insert into t values (1, '2020-03-01', '2020-03-05');
+--disable_ps2_protocol
+select * into outfile 'tmp_t.txt' from t;
+--enable_ps2_protocol
+--error ER_DUP_ENTRY
+load data infile 'tmp_t.txt' into table t;
+
+load data infile 'tmp_t.txt' ignore into table t;
+
+--error ER_NOT_SUPPORTED_YET
+load data infile 'tmp_t.txt' replace into table t;
+
+remove_file $MYSQLD_DATADIR/test/tmp_t.txt;
+
+
+--echo # MDEV-22599 WITHOUT OVERLAPS does not work with prefix indexes
+create or replace table t1 (a varchar(6), s timestamp, e timestamp,
+ period for p(s,e),
+ unique(a(3), p without overlaps));
+
+insert into t1 values ('foo', '2012-01-01', '2015-12-31');
+--error ER_DUP_ENTRY
+insert into t1 values ('foobar', '2013-01-01', '2014-01-01');
+
+insert into t1 values ('bar', '2012-01-01', '2015-12-31'),
+ ('baz', '2013-01-01', '2014-01-01');
+select * from t1;
+
+--echo # MDEV-22753 Server crashes in handler::ha_check_overlaps or error 190
+--echo # "Incompatible key or row definition" upon INSERT into versioned
+--echo # partitioned table with WITHOUT OVERLAPS
+create or replace table t1 (f int, s date, e date, period for p(s,e),
+ unique(f, p without overlaps)
+ ) engine=innodb with system versioning
+ partition by system_time limit 1000
+ (partition p1 history, partition pn current);
+alter table t1 add partition (partition p2 history);
+show create table t1;
+insert into t1 values (1,'2013-01-12','2015-11-04'),
+ (2,'2016-03-15','2024-11-09');
+
+
+--echo # MDEV-22714 Assertion `index->table->is_instant()' failed upon
+--echo # multi-update on table with WITHOUT OVERLAPS
+
+create or replace table t (a int);
+insert into t values (0),(null),(0);
+
+create or replace table t1 (f int, s date, e date, period for p(s,e),
+ unique(f, p without overlaps));
+
+insert into t1 values (0,'2026-02-12','2036-09-16'),
+ (null,'2025-03-09','2032-12-05');
+
+update ignore t join t1 set f = a;
+
+--echo # MDEV-22639 Assertion `inited != NONE' failed in
+--echo # handler::ha_check_overlaps upon multi-table update
+
+create or replace table t (f int, s date, e date, period for p(s,e),
+ unique(f, p without overlaps)) engine=myisam;
+insert into t values (1,'1988-08-25','2024-03-06');
+create or replace table t1 (a int) engine=myisam;
+insert into t1 values (1),(2);
+
+update t join t1 set s = '2020-01-01';
+
+
+--echo # MDEV-22608 ASAN use-after-poison in TABLE::check_period_overlaps
+
+create or replace table t1 (s date, e date, b bit, period for p(s,e),
+ unique(b, p without overlaps)) engine=myisam;
+insert into t1 values ('2024-12-21','2034-06-29',0),
+ ('2024-12-21','2034-06-29',1);
+--error ER_DUP_ENTRY
+update t1 set b = 1;
+
+
+--echo # MDEV-22677 Server crashes in ha_partition::open upon update on
+--echo # partitioned HEAP table with WITHOUT OVERLAPS
+
+create or replace table t (id int, s date, e date, period for p(s,e),
+ primary key(id, p without overlaps)
+ ) engine=heap partition by hash(id);
+update t set id = 1;
+
+drop table t, t1;
+
+--echo #
+--echo # MDEV-30415 PERIOD false positive overlap wtih utf8mb4_unicode_nopad_ci
+--echo #
+
+# The originally reported script with a TEXT column (slightly modified)
+CREATE TABLE t1 (
+ datetime_column_name_1 DATETIME(6) NOT NULL,
+ datetime_column_name_2 DATETIME(6) NOT NULL,
+ text_column_name TEXT COLLATE utf8mb4_unicode_nopad_ci NOT NULL,
+ PERIOD FOR period_name (datetime_column_name_1, datetime_column_name_2),
+ UNIQUE KEY index_name (text_column_name(191),period_name WITHOUT OVERLAPS)
+) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_nopad_ci;
+INSERT INTO t1 (datetime_column_name_1, datetime_column_name_2, text_column_name)
+VALUES
+ ('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc'),
+ ('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc ');
+TRUNCATE TABLE t1;
+INSERT INTO t1 (datetime_column_name_1, datetime_column_name_2, text_column_name)
+VALUES
+ ('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc '),
+ ('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc');
+DROP TABLE t1;
+
+
+# The script reported by Alice with a TEXT column
+CREATE TABLE `t1` (
+ datetime_column_name_1 DATETIME(6) NOT NULL,
+ datetime_column_name_2 DATETIME(6) NOT NULL,
+ text_column_name TEXT COLLATE utf8mb4_unicode_nopad_ci NOT NULL,
+ PERIOD FOR period_name (datetime_column_name_1, datetime_column_name_2),
+ UNIQUE KEY index_name (text_column_name(191),period_name WITHOUT OVERLAPS)
+) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_nopad_ci;
+INSERT INTO t1 VALUES
+ ('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'def '),
+ ('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'def');
+TRUNCATE TABLE t1;
+INSERT INTO t1 VALUES
+ ('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'def'),
+ ('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'def '),
+ ('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'def ');
+--sorted_result
+SELECT *, LENGTH(text_column_name) FROM t1;
+DROP TABLE t1;
+
+
+# A TEXT column with a short prefix
+CREATE TABLE t1 (
+ datetime_column_name_1 DATETIME(6) NOT NULL,
+ datetime_column_name_2 DATETIME(6) NOT NULL,
+ text_column_name TEXT COLLATE utf8mb4_unicode_nopad_ci NOT NULL,
+ PERIOD FOR period_name (datetime_column_name_1, datetime_column_name_2),
+ UNIQUE KEY index_name (text_column_name(3),period_name WITHOUT OVERLAPS)
+) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_nopad_ci;
+--error ER_DUP_ENTRY
+INSERT INTO t1 (datetime_column_name_1, datetime_column_name_2, text_column_name)
+VALUES
+ ('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc'),
+ ('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc ');
+TRUNCATE TABLE t1;
+--error ER_DUP_ENTRY
+INSERT INTO t1 (datetime_column_name_1, datetime_column_name_2, text_column_name)
+VALUES
+ ('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc '),
+ ('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc');
+DROP TABLE t1;
+
+
+# A CHAR with a long prefix
+CREATE TABLE t1 (
+ datetime_column_name_1 DATETIME(6) NOT NULL,
+ datetime_column_name_2 DATETIME(6) NOT NULL,
+ char_column_name CHAR(255) COLLATE utf8mb4_unicode_nopad_ci NOT NULL,
+ PERIOD FOR period_name (datetime_column_name_1, datetime_column_name_2),
+ UNIQUE KEY index_name (char_column_name(191),period_name WITHOUT OVERLAPS)
+) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_nopad_ci;
+--error ER_DUP_ENTRY
+INSERT INTO t1 (datetime_column_name_1, datetime_column_name_2, char_column_name)
+VALUES
+ ('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc'),
+ ('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc ');
+TRUNCATE TABLE t1;
+--error ER_DUP_ENTRY
+INSERT INTO t1 (datetime_column_name_1, datetime_column_name_2, char_column_name)
+VALUES
+ ('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc '),
+ ('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc');
+DROP TABLE t1;
+
+
+# A CHAR column with a short prefix
+CREATE TABLE t1 (
+ datetime_column_name_1 DATETIME(6) NOT NULL,
+ datetime_column_name_2 DATETIME(6) NOT NULL,
+ char_column_name CHAR(255) COLLATE utf8mb4_unicode_nopad_ci NOT NULL,
+ PERIOD FOR period_name (datetime_column_name_1, datetime_column_name_2),
+ UNIQUE KEY index_name (char_column_name(3),period_name WITHOUT OVERLAPS)
+) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_nopad_ci;
+--error ER_DUP_ENTRY
+INSERT INTO t1 (datetime_column_name_1, datetime_column_name_2, char_column_name)
+VALUES
+ ('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc'),
+ ('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc ');
+TRUNCATE TABLE t1;
+--error ER_DUP_ENTRY
+INSERT INTO t1 (datetime_column_name_1, datetime_column_name_2, char_column_name)
+VALUES
+ ('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc '),
+ ('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc');
+DROP TABLE t1;
diff --git a/mysql-test/suite/period/t/update.test b/mysql-test/suite/period/t/update.test
new file mode 100644
index 00000000..3f4dd2bd
--- /dev/null
+++ b/mysql-test/suite/period/t/update.test
@@ -0,0 +1,207 @@
+source suite/period/engines.inc;
+source include/have_log_bin.inc;
+
+create table t (id int, s date, e date, period for apptime(s,e));
+
+insert into t values(1, '1999-01-01', '2018-12-12');
+insert into t values(1, '1999-01-01', '2017-01-01');
+insert into t values(1, '2017-01-01', '2019-01-01');
+insert into t values(2, '1998-01-01', '2018-12-12');
+insert into t values(3, '1997-01-01', '2015-01-01');
+insert into t values(4, '2016-01-01', '2020-01-01');
+insert into t values(5, '2010-01-01', '2015-01-01');
+
+create or replace table t1 (id int, s date, e date, period for apptime(s,e));
+insert t1 select * from t;
+create or replace table t2 (id int, s date, e date, period for apptime(s,e));
+insert t2 select * from t;
+
+update t for portion of apptime from '2000-01-01' to '2018-01-01'
+ set id=id + 6;
+--sorted_result
+select * from t;
+
+--echo # Check triggers
+--let $trig_cols=id, s, e
+--let $trig_table=t1
+--source suite/period/create_triggers.inc
+
+update t1 for portion of apptime from '2000-01-01' to '2018-01-01'
+ set id=id + 6;
+--sorted_result
+select * from t1;
+select * from log_tbl order by id;
+
+--echo # INSERT trigger only also works
+--let $trig_cols=id, s, e
+--let $trig_table=t2
+--source suite/period/create_triggers.inc
+drop trigger tr1upd_t2;
+drop trigger tr2upd_t2;
+update t2 for portion of apptime from '2000-01-01' to '2018-01-01'
+ set id=id + 6;
+--sorted_result
+select * from t2;
+select * from log_tbl order by id;
+
+--error ER_PARSE_ERROR
+select * from t for portion of apptime from 0 to 1 for system_time all;
+--error ER_PARSE_ERROR
+update t for portion of apptime from 0 to 1 for system_time all set id=1;
+
+--echo # Modifying period start/end fields is forbidden.
+--echo # SQL16: 14.14 <update statement: searched>, Syntax Rules, 7)a)ii)
+--echo # Neither BSTARTCOL nor BENDCOL shall be an explicit <object column>
+--echo # contained in the <set clause list>.
+--error ER_PERIOD_COLUMNS_UPDATED
+update t for portion of apptime from '2000-01-01' to '2018-01-01'
+ set id= id + 6, s=subdate(s, 5), e=adddate(e, 5);
+
+--echo # Precision timestamps
+create or replace table t (id int, s timestamp(5), e timestamp(5),
+ period for apptime(s,e));
+insert into t values(1, '1999-01-01', '2018-12-12');
+insert into t values(1, '1999-01-01', '2017-01-01');
+update t for portion of apptime from '2000-01-01 00:00:00.00015'
+ to '2018-01-01 12:34:56.31415'
+ set id= id + 5;
+--sorted_result
+select * from t;
+
+-- echo # Strings
+create or replace table t (id int, str text, s date, e date,
+ period for apptime(s,e));
+
+insert into t values(1, 'data', '1999-01-01', '2018-12-12');
+insert into t values(1, 'other data', '1999-01-01', '2018-12-12');
+update t for portion of apptime from '2000-01-01' to '2018-01-01'
+ set id= id + 5;
+--sorted_result
+select * from t;
+
+--echo # multi-table UPDATE is impossible
+create or replace table t1(x int);
+--error ER_PARSE_ERROR
+update t for portion of apptime from '2000-01-01' to '2018-01-01', t1
+ set t.id= t.id + 5;
+
+--error ER_PARSE_ERROR
+update t1 set x= (select id from t for portion of apptime from '2000-01-01' to '2018-01-01');
+
+--echo # single-table views
+create or replace view v1 as select * from t where id<10;
+--error ER_IT_IS_A_VIEW
+update v1 for portion of apptime from '2000-01-01' to '2018-01-01' set id= id + 5;
+
+--echo # multi-table views
+create or replace view v1 as select * from t, t1 where x=id;
+--error ER_IT_IS_A_VIEW
+update v1 for portion of apptime from '2000-01-01' to '2018-01-01' set id= id + 5;
+
+--echo # SQL16: 14.14 <update statement: searched>, Syntax Rules, 7)a) iii-iv)
+--echo # Let FROMVAL be <point in time 1>. FROMVAL shall not generally contain a
+--echo # reference to a column of T or a <routine invocation>
+--echo # whose subject routine is an SQL-invoked routine that
+--echo # is possibly non-deterministic or that possibly modifies SQL-data.
+--echo # ...Same for <point in time 2> (TOVAL)
+--error ER_NOT_CONSTANT_EXPRESSION
+update t for portion of apptime from 5*(5+s) to 1 set t.id= t.id + 5;
+--error ER_NOT_CONSTANT_EXPRESSION
+update t for portion of apptime from 1 to e set t.id= t.id + 5;
+
+set @s= '2000-01-01';
+set @e= '2018-01-01';
+
+create or replace function f() returns date return @e;
+create or replace function g() returns date not deterministic return @e;
+create or replace function h() returns date deterministic return @e;
+
+--error ER_NOT_CONSTANT_EXPRESSION
+update t for portion of apptime from @s to f() set t.id= t.id + 5;
+--error ER_NOT_CONSTANT_EXPRESSION
+update t for portion of apptime from @s to g() set t.id= t.id + 5;
+
+--echo # success
+update t for portion of apptime from @s to h() set t.id= t.id + 5;
+--echo # select value is cached
+update t for portion of apptime from (select s from t2 limit 1) to h() set t.id= t.id + 5;
+
+--echo # auto_inrement field is updated
+create or replace table t (id int primary key auto_increment, x int,
+ s date, e date, period for apptime(s, e));
+insert into t values (default, 1, '1999-01-01', '2018-12-12');
+update t for portion of apptime from '2000-01-01' to '2018-01-01' set x= x + 5;
+--sorted_result
+select * from t;
+
+truncate t;
+insert into t values (default, 1, '1999-01-01', '2018-12-12');
+update t for portion of apptime from '2000-01-01' to '2018-01-01' set x= 1;
+--sorted_result
+select * from t;
+
+--echo # generated columns are updated
+create or replace table t (x int, s date, e date,
+ xs date as (s) stored, xe date as (e) stored,
+ period for apptime(s, e));
+insert into t values(1, '1999-01-01', '2018-12-12', default, default);
+--sorted_result
+select * from t;
+update t for portion of apptime from '2000-01-01' to '2018-01-01' set x= x + 5;
+--sorted_result
+select *, xs=s and xe=e from t;
+
+--echo # MDEV-18921 Server crashes in bitmap_bits_set or bitmap_is_set upon
+--echo # UPDATE IGNORE .. FOR PORTION with binary logging
+create or replace table t1 (f int, s date, e date, period for app(s,e));
+insert into t1 values (1,'2016-09-21','2019-06-14');
+update ignore t1 for portion of app from '2019-03-13' to '2019-03-14' set f = 1;
+
+drop table t,t1,t2,log_tbl;
+drop view v1;
+drop function f;
+drop function g;
+drop function h;
+drop procedure log;
+
+--echo #
+--echo # MDEV-21471 ER_CRASHED_ON_USAGE upon UPDATE FOR PORTION on Aria table
+--echo #
+create table t1 (s date, e date, period for app(s,e), f varchar(8)) engine=aria row_format=fixed;
+insert into t1 values ('2024-05-13','2026-03-25','foo');
+update t1 for portion of app from '2024-04-02' to '2026-03-15' set f = 'bar';
+
+# cleanup
+drop table t1;
+
+--echo # MDEV-19130 Assertion
+--echo # `next_insert_id >= auto_inc_interval_for_cur_row.minimum()'
+--echo # failed in handler::update_auto_increment after error 167
+create table t1 (id int auto_increment, f int, s datetime, e datetime, period for p(s,e), primary key(id));
+insert into t1 (s,e) values ('1994-01-06','2004-11-30'),('1994-06-21','1997-06-20');
+update ignore t1 set id = 2429681664;
+update ignore t1 for portion of p from '1995-07-06' to '2009-01-12' set f = 1;
+
+drop table t1;
+
+--echo #
+--echo # MDEV-22805 SIGSEGV in check_fields on UPDATE (optimized builds) | Assertion `thd->lex->sql_command == SQLCOM_UPDATE' failed.
+--echo #
+CREATE TABLE t1 (a INT, b DATE, c DATE, PERIOD FOR APPTIME(b, c));
+
+INSERT INTO t1 VALUES(1, '1999-01-01', '2018-12-12');
+
+# Without a patch the following statement crashs a server built in debug mode
+let $stmt= UPDATE t1 FOR PORTION OF APPTIME FROM (SELECT '1999-01-01' FROM t1 WHERE a=2) TO '2018-01-01' SET a = 100;
+--error ER_NOT_SUPPORTED_YET
+eval $stmt;
+eval set @tmp= "$stmt";
+--error ER_NOT_SUPPORTED_YET
+execute immediate @tmp;
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+--error ER_IT_IS_A_VIEW
+UPDATE v1 FOR PORTION OF APPTIME FROM (SELECT '1999-01-01' FROM t1 WHERE a=2) TO '2018-01-01' SET a = 100;
+
+DROP VIEW v1;
+DROP TABLE t1;
diff --git a/mysql-test/suite/period/t/versioning.test b/mysql-test/suite/period/t/versioning.test
new file mode 100644
index 00000000..5d38d813
--- /dev/null
+++ b/mysql-test/suite/period/t/versioning.test
@@ -0,0 +1,61 @@
+source suite/versioning/engines.inc;
+source suite/versioning/common.inc;
+
+--echo # DELETE
+--replace_result $sys_datatype_expl SYS_TYPE
+eval create table t (
+ s date, e date,
+ row_start $sys_datatype_expl as row start invisible,
+ row_end $sys_datatype_expl as row end invisible,
+ period for apptime(s, e),
+ period for system_time (row_start, row_end)) with system versioning;
+insert into t values('1999-01-01', '2018-12-12'),
+ ('1999-01-01', '1999-12-12');
+
+select row_start into @ins_time from t limit 1;
+select * from t order by s, e;
+
+delete from t for portion of apptime from '2000-01-01' to '2018-01-01';
+select *, if(row_start = @ins_time, "OLD", "NEW"), check_row(row_start, row_end)
+ from t for system_time all
+ order by s, e, row_start;
+
+--echo # same for trigger case
+delete from t;
+delete history from t;
+insert into t values('1999-01-01', '2018-12-12'),
+ ('1999-01-01', '1999-12-12');
+--let $trig_table=t
+--source suite/period/create_triggers.inc
+
+select row_start into @ins_time from t limit 1;
+select * from t order by s, e;
+
+delete from t for portion of apptime from '2000-01-01' to '2018-01-01';
+select *, if(row_start = @ins_time, "OLD", "NEW"), check_row(row_start, row_end)
+ from t for system_time all
+ order by s, e, row_start;
+select * from log_tbl order by id;
+
+--echo # UPDATE
+--replace_result $sys_datatype_expl SYS_TYPE
+eval create or replace table t (x int, s date, e date,
+ row_start $sys_datatype_expl as row start invisible,
+ row_end $sys_datatype_expl as row end invisible,
+ period for apptime(s, e),
+ period for system_time(row_start, row_end)) with system versioning;
+insert into t values(1, '1999-01-01', '2018-12-12'),
+ (2, '1999-01-01', '1999-12-12');
+
+select row_start into @ins_time from t limit 1;
+--sorted_result
+select * from t;
+
+update t for portion of apptime from '2000-01-01' to '2018-01-01' set x= x + 5;
+select *, if(row_start = @ins_time, "OLD", "NEW"), check_row(row_start, row_end)
+ from t for system_time all
+ order by x, s, e, row_start;
+
+drop table t,log_tbl;
+drop procedure log;
+source suite/versioning/common_finish.inc;