diff options
Diffstat (limited to 'mysql-test/suite/period')
-rw-r--r-- | mysql-test/suite/period/create_triggers.inc | 38 | ||||
-rw-r--r-- | mysql-test/suite/period/engines.combinations | 7 | ||||
-rw-r--r-- | mysql-test/suite/period/engines.inc | 3 | ||||
-rw-r--r-- | mysql-test/suite/period/r/alter.result | 224 | ||||
-rw-r--r-- | mysql-test/suite/period/r/create.result | 113 | ||||
-rw-r--r-- | mysql-test/suite/period/r/delete,myisam.rdiff | 18 | ||||
-rw-r--r-- | mysql-test/suite/period/r/delete.result | 423 | ||||
-rw-r--r-- | mysql-test/suite/period/r/long_unique.result | 17 | ||||
-rw-r--r-- | mysql-test/suite/period/r/overlaps.result | 451 | ||||
-rw-r--r-- | mysql-test/suite/period/r/update.result | 309 | ||||
-rw-r--r-- | mysql-test/suite/period/r/versioning.result | 90 | ||||
-rw-r--r-- | mysql-test/suite/period/t/alter.test | 192 | ||||
-rw-r--r-- | mysql-test/suite/period/t/create.test | 101 | ||||
-rw-r--r-- | mysql-test/suite/period/t/delete.test | 270 | ||||
-rw-r--r-- | mysql-test/suite/period/t/long_unique.test | 23 | ||||
-rw-r--r-- | mysql-test/suite/period/t/overlaps.test | 460 | ||||
-rw-r--r-- | mysql-test/suite/period/t/update.test | 207 | ||||
-rw-r--r-- | mysql-test/suite/period/t/versioning.test | 61 |
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; |