diff options
-rw-r--r-- | mysql-test/main/partition_alter.result | 23 | ||||
-rw-r--r-- | mysql-test/main/partition_alter.test | 19 | ||||
-rw-r--r-- | mysql-test/suite/versioning/r/partition.result | 28 | ||||
-rw-r--r-- | mysql-test/suite/versioning/t/partition.test | 24 | ||||
-rw-r--r-- | sql/sql_partition.cc | 18 |
5 files changed, 112 insertions, 0 deletions
diff --git a/mysql-test/main/partition_alter.result b/mysql-test/main/partition_alter.result index ca6359f94de..d946f2b8822 100644 --- a/mysql-test/main/partition_alter.result +++ b/mysql-test/main/partition_alter.result @@ -129,3 +129,26 @@ ERROR HY000: Duplicate partition name p1 alter table t1 add partition (partition p1); ERROR HY000: Duplicate partition name p1 drop table t1; +# +# MDEV-17091 Assertion `old_part_id == m_last_part' failed in +# ha_partition::update_row or `part_id == m_last_part' in +# ha_partition::delete_row upon UPDATE/DELETE after dropping versioning +# +create or replace table t1 (pk int, f int, primary key(pk, f)) engine=innodb +partition by key() partitions 2; +insert into t1 values (1,10),(2,11); +# expected to hit same partition +select * from t1 partition (p0); +pk f +1 10 +2 11 +alter table t1 drop primary key, drop f, add primary key(pk); +# 1 and 2 are expected to be in different partitions +select * from t1 partition(p0); +pk +1 +select * from t1 partition(p1); +pk +2 +delete from t1; +drop table t1; diff --git a/mysql-test/main/partition_alter.test b/mysql-test/main/partition_alter.test index 91ae67e2f7b..dbe7802b5fb 100644 --- a/mysql-test/main/partition_alter.test +++ b/mysql-test/main/partition_alter.test @@ -123,3 +123,22 @@ alter table t1 add partition (partition p1); --error ER_SAME_NAME_PARTITION alter table t1 add partition (partition p1); drop table t1; + +--echo # +--echo # MDEV-17091 Assertion `old_part_id == m_last_part' failed in +--echo # ha_partition::update_row or `part_id == m_last_part' in +--echo # ha_partition::delete_row upon UPDATE/DELETE after dropping versioning +--echo # +create or replace table t1 (pk int, f int, primary key(pk, f)) engine=innodb + partition by key() partitions 2; + +insert into t1 values (1,10),(2,11); +--echo # expected to hit same partition +select * from t1 partition (p0); + +alter table t1 drop primary key, drop f, add primary key(pk); +--echo # 1 and 2 are expected to be in different partitions +select * from t1 partition(p0); +select * from t1 partition(p1); +delete from t1; +drop table t1; diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result index aa884743b2f..a75fa49c610 100644 --- a/mysql-test/suite/versioning/r/partition.result +++ b/mysql-test/suite/versioning/r/partition.result @@ -614,3 +614,31 @@ create table t2 (b int); insert into t2 values (1),(2); update t1, t2 set a = 1; drop table t1, t2; +# +# MDEV-17091 Assertion `old_part_id == m_last_part' failed in +# ha_partition::update_row or `part_id == m_last_part' in +# ha_partition::delete_row upon UPDATE/DELETE after dropping versioning +# +create or replace table t1 (pk int primary key, f int) engine=innodb +with system versioning +partition by key() partitions 2; +insert into t1 values (1,10),(2,20); +# expected to hit same partition +select * from t1 partition (p0); +pk f +1 10 +2 20 +alter table t1 drop system versioning; +# 1 and 2 are expected to be in different partitions +select * from t1 partition(p0); +pk f +1 10 +select * from t1 partition(p1); +pk f +2 20 +update t1 set f=pk; +delete from t1; +drop table t1; +# Test cleanup +drop database test; +create database test; diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test index 8898088b1bc..282af4b5bc7 100644 --- a/mysql-test/suite/versioning/t/partition.test +++ b/mysql-test/suite/versioning/t/partition.test @@ -568,3 +568,27 @@ update t1, t2 set a = 1; drop table t1, t2; --source suite/versioning/common_finish.inc +--echo # +--echo # MDEV-17091 Assertion `old_part_id == m_last_part' failed in +--echo # ha_partition::update_row or `part_id == m_last_part' in +--echo # ha_partition::delete_row upon UPDATE/DELETE after dropping versioning +--echo # +create or replace table t1 (pk int primary key, f int) engine=innodb + with system versioning + partition by key() partitions 2; +insert into t1 values (1,10),(2,20); +--echo # expected to hit same partition +select * from t1 partition (p0); +alter table t1 drop system versioning; + +--echo # 1 and 2 are expected to be in different partitions +select * from t1 partition(p0); +select * from t1 partition(p1); + +update t1 set f=pk; +delete from t1; +drop table t1; + +--echo # Test cleanup +drop database test; +create database test; diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index febd88c4b9b..5fdca153ef7 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -6016,6 +6016,24 @@ the generated partition syntax in a correct manner. *partition_changed= true; } } + + // In case of PARTITION BY KEY(), check if primary key has changed + // System versioning also implicitly adds/removes primary key parts + if (alter_info->partition_flags == 0 && part_info->list_of_part_fields + && part_info->part_field_list.elements == 0) + { + if (alter_info->flags & (ALTER_DROP_SYSTEM_VERSIONING | + ALTER_ADD_SYSTEM_VERSIONING)) + *partition_changed= true; + + List_iterator<Key> it(alter_info->key_list); + Key *key; + while((key= it++) && !*partition_changed) + { + if (key->type == Key::PRIMARY) + *partition_changed= true; + } + } /* Set up partition default_engine_type either from the create_info or from the previus table |