summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/main/partition_alter.result23
-rw-r--r--mysql-test/main/partition_alter.test19
-rw-r--r--mysql-test/suite/versioning/r/partition.result28
-rw-r--r--mysql-test/suite/versioning/t/partition.test24
-rw-r--r--sql/sql_partition.cc18
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