From ea2f09979fc74a8fa7fb1e74c874e00df757c6db Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Sun, 24 Apr 2022 00:28:54 +0300 Subject: [PATCH] MDEV-28271 Assertion on TRUNCATE PARTITION for PARTITION BY SYSTEM_TIME Like in MDEV-27217 vers_set_hist_part() for LIMIT depends on all partitions selected in read_partitions. That bugfix just disabled partition selection for DELETE with this check: if (table->pos_in_table_list && table->pos_in_table_list->partition_names) { return HA_ERR_PARTITION_LIST; } ALTER TABLE TRUNCATE PARTITION is a different story. First, it doesn't update pos_in_table_list->partition_names, but thd->lex->alter_info.partition_names. But we cannot depend on that since alter_info will be stale for DML. Second, we should not disable TRUNCATE PARTITION for that to be consistent with TRUNCATE TABLE behavior. Now we don't do vers_set_hist_part() for ALTER TABLE as this command is not DML, so it does not produce history. --- .../suite/versioning/r/partition.result | 72 +++++++++++++++++++ mysql-test/suite/versioning/t/partition.test | 60 ++++++++++++++++ sql/ha_partition.cc | 1 + 3 files changed, 133 insertions(+) diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result index 70416360697..cada225db7e 100644 --- a/mysql-test/suite/versioning/r/partition.result +++ b/mysql-test/suite/versioning/r/partition.result @@ -839,5 +839,77 @@ p0 10 p1 0 pn 90 drop table t1; +# +# MDEV-28271 Assertion on TRUNCATE PARTITION for PARTITION BY SYSTEM_TIME +# +create table t1 (x int) with system versioning +partition by system_time limit 1 ( +partition p0 history, +partition p1 history, +partition pn current); +insert into t1 values (0); +update t1 set x= x + 1; +update t1 set x= x + 1; +update t1 set x= x + 1; +update t1 set x= x + 1; +select * from t1 partition (p0); +x +0 +1 +select * from t1 partition (p1); +x +2 +3 +select * from t1 partition (pn); +x +4 +# TRUNCATE TABLE deletes history and current data +truncate table t1; +select * from t1 partition (p0); +x +select * from t1 partition (p1); +x +select * from t1 partition (pn); +x +insert into t1 values (0); +update t1 set x= x + 1; +update t1 set x= x + 1; +update t1 set x= x + 1; +update t1 set x= x + 1; +# TRUNCATE PARTITION ALL does the same +alter table t1 truncate partition all; +select * from t1 partition (p0); +x +select * from t1 partition (p1); +x +select * from t1 partition (pn); +x +insert into t1 values (0); +update t1 set x= x + 1; +update t1 set x= x + 1; +update t1 set x= x + 1; +update t1 set x= x + 1; +# TRUNCATE PARTITION deletes data from HISTORY partition +alter table t1 truncate partition p1; +select * from t1 partition (p0); +x +0 +1 +select * from t1 partition (p1); +x +select * from t1 partition (pn); +x +4 +# or from CURRENT partition +alter table t1 truncate partition pn; +select * from t1 partition (p0); +x +0 +1 +select * from t1 partition (p1); +x +select * from t1 partition (pn); +x +drop table t1; # End of 10.3 tests set global innodb_stats_persistent= @save_persistent; diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test index a687cd9b09f..7f75f905254 100644 --- a/mysql-test/suite/versioning/t/partition.test +++ b/mysql-test/suite/versioning/t/partition.test @@ -822,6 +822,66 @@ from information_schema.partitions where table_name = 't1'; # Cleanup drop table t1; + +--echo # +--echo # MDEV-28271 Assertion on TRUNCATE PARTITION for PARTITION BY SYSTEM_TIME +--echo # +create table t1 (x int) with system versioning +partition by system_time limit 1 ( + partition p0 history, + partition p1 history, + partition pn current); + +insert into t1 values (0); +update t1 set x= x + 1; +update t1 set x= x + 1; +update t1 set x= x + 1; +update t1 set x= x + 1; + +select * from t1 partition (p0); +select * from t1 partition (p1); +select * from t1 partition (pn); + +--echo # TRUNCATE TABLE deletes history and current data +--disable_warnings +truncate table t1; +--enable_warnings +select * from t1 partition (p0); +select * from t1 partition (p1); +select * from t1 partition (pn); + +insert into t1 values (0); +update t1 set x= x + 1; +update t1 set x= x + 1; +update t1 set x= x + 1; +update t1 set x= x + 1; + +--echo # TRUNCATE PARTITION ALL does the same +alter table t1 truncate partition all; +select * from t1 partition (p0); +select * from t1 partition (p1); +select * from t1 partition (pn); + +insert into t1 values (0); +update t1 set x= x + 1; +update t1 set x= x + 1; +update t1 set x= x + 1; +update t1 set x= x + 1; + +--echo # TRUNCATE PARTITION deletes data from HISTORY partition +alter table t1 truncate partition p1; +select * from t1 partition (p0); +select * from t1 partition (p1); +select * from t1 partition (pn); + +--echo # or from CURRENT partition +alter table t1 truncate partition pn; +select * from t1 partition (p0); +select * from t1 partition (p1); +select * from t1 partition (pn); + +drop table t1; + --echo # End of 10.3 tests set global innodb_stats_persistent= @save_persistent; diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index b4bb3e7e61e..b1645a9c4a7 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -4034,6 +4034,7 @@ int ha_partition::external_lock(THD *thd, int lock_type) only for versioned DML. */ thd->lex->sql_command != SQLCOM_SELECT && thd->lex->sql_command != SQLCOM_INSERT_SELECT && + thd->lex->sql_command != SQLCOM_ALTER_TABLE && (error= m_part_info->vers_set_hist_part(thd))) goto err_handler; }