summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/partition_alter.result43
-rw-r--r--mysql-test/t/partition_alter.test39
-rw-r--r--sql/sql_partition.cc22
3 files changed, 104 insertions, 0 deletions
diff --git a/mysql-test/r/partition_alter.result b/mysql-test/r/partition_alter.result
index 1dced95b17a..8de3d4b45ad 100644
--- a/mysql-test/r/partition_alter.result
+++ b/mysql-test/r/partition_alter.result
@@ -122,3 +122,46 @@ t1 CREATE TABLE `t1` (
PARTITION `p02` ENGINE = MyISAM,
PARTITION `p03` ENGINE = MyISAM)
drop table t1;
+#
+# MDEV-19751 Wrong partitioning by KEY() after key dropped
+#
+create or replace table t1 (pk int, x timestamp(6), primary key (pk, x)) engine innodb
+partition by key() partitions 2;
+insert into t1 (pk, x) values (1, '2000-01-01 00:00'), (2, '2000-01-01 00:01');
+# Inplace for DROP PRIMARY KEY when partitioned by default field list is denied
+alter table t1 drop primary key, drop column x, add primary key (pk), algorithm=inplace;
+ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY
+alter table t1 drop primary key, drop column x, add primary key (pk);
+select * from t1 partition (p0);
+pk
+1
+drop table t1;
+create or replace table t1 (pk int not null, x timestamp(6), unique u(pk, x)) engine innodb
+partition by key() partitions 2;
+insert into t1 (pk, x) values (1, '2000-01-01 00:00'), (2, '2000-01-01 00:01');
+# Same for NOT NULL UNIQUE KEY as this is actually primary key
+alter table t1 drop key u, drop column x, add unique (pk), algorithm=inplace;
+ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY
+alter table t1 drop key u, drop column x, add unique (pk);
+select * from t1 partition (p0);
+pk
+1
+drop table t1;
+create or replace table t1 (pk int, x timestamp(6), primary key (pk)) engine innodb
+partition by key(pk) partitions 2;
+insert into t1 (pk, x) values (1, '2000-01-01 00:00'), (2, '2000-01-01 00:01');
+# Inplace for DROP PRIMARY KEY when partitioned by explicit field list is allowed
+alter table t1 drop primary key, add primary key (pk, x), algorithm=inplace;
+select * from t1 partition (p0);
+pk x
+1 2000-01-01 00:00:00.000000
+drop table t1;
+create or replace table t1 (k int, x timestamp(6), unique key u (x, k)) engine innodb
+partition by key(k) partitions 2;
+insert into t1 (k, x) values (1, '2000-01-01 00:00'), (2, '2000-01-01 00:01');
+# Inplace for DROP KEY is allowed
+alter table t1 drop key u, algorithm=inplace;
+select * from t1 partition (p0);
+k x
+1 2000-01-01 00:00:00.000000
+drop table t1;
diff --git a/mysql-test/t/partition_alter.test b/mysql-test/t/partition_alter.test
index 1235e5b8dc2..3c783ebe375 100644
--- a/mysql-test/t/partition_alter.test
+++ b/mysql-test/t/partition_alter.test
@@ -112,3 +112,42 @@ insert into t1 values(0, 1, 1, NULL, now(), now());
alter online table t1 delay_key_write=1;
show create table t1;
drop table t1;
+
+--echo #
+--echo # MDEV-19751 Wrong partitioning by KEY() after key dropped
+--echo #
+create or replace table t1 (pk int, x timestamp(6), primary key (pk, x)) engine innodb
+partition by key() partitions 2;
+insert into t1 (pk, x) values (1, '2000-01-01 00:00'), (2, '2000-01-01 00:01');
+--echo # Inplace for DROP PRIMARY KEY when partitioned by default field list is denied
+--error ER_ALTER_OPERATION_NOT_SUPPORTED
+alter table t1 drop primary key, drop column x, add primary key (pk), algorithm=inplace;
+alter table t1 drop primary key, drop column x, add primary key (pk);
+select * from t1 partition (p0);
+drop table t1;
+
+create or replace table t1 (pk int not null, x timestamp(6), unique u(pk, x)) engine innodb
+partition by key() partitions 2;
+insert into t1 (pk, x) values (1, '2000-01-01 00:00'), (2, '2000-01-01 00:01');
+--echo # Same for NOT NULL UNIQUE KEY as this is actually primary key
+--error ER_ALTER_OPERATION_NOT_SUPPORTED
+alter table t1 drop key u, drop column x, add unique (pk), algorithm=inplace;
+alter table t1 drop key u, drop column x, add unique (pk);
+select * from t1 partition (p0);
+drop table t1;
+
+create or replace table t1 (pk int, x timestamp(6), primary key (pk)) engine innodb
+partition by key(pk) partitions 2;
+insert into t1 (pk, x) values (1, '2000-01-01 00:00'), (2, '2000-01-01 00:01');
+--echo # Inplace for DROP PRIMARY KEY when partitioned by explicit field list is allowed
+alter table t1 drop primary key, add primary key (pk, x), algorithm=inplace;
+select * from t1 partition (p0);
+drop table t1;
+
+create or replace table t1 (k int, x timestamp(6), unique key u (x, k)) engine innodb
+partition by key(k) partitions 2;
+insert into t1 (k, x) values (1, '2000-01-01 00:00'), (2, '2000-01-01 00:01');
+--echo # Inplace for DROP KEY is allowed
+alter table t1 drop key u, algorithm=inplace;
+select * from t1 partition (p0);
+drop table t1;
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 071c9c05129..2334286b039 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -5473,6 +5473,28 @@ the generated partition syntax in a correct manner.
*partition_changed= TRUE;
}
}
+ /*
+ Prohibit inplace when partitioned by primary key and the primary key is dropped.
+ */
+ if (!*partition_changed &&
+ tab_part_info->part_field_array &&
+ !tab_part_info->part_field_list.elements &&
+ table->s->primary_key != MAX_KEY)
+ {
+ KEY *primary_key= table->key_info + table->s->primary_key;
+ List_iterator_fast<Alter_drop> drop_it(alter_info->drop_list);
+ const char *primary_name= primary_key->name;
+ const Alter_drop *drop;
+ drop_it.rewind();
+ while ((drop= drop_it++))
+ {
+ if (drop->type == Alter_drop::KEY &&
+ 0 == my_strcasecmp(system_charset_info, primary_name, drop->name))
+ break;
+ }
+ if (drop)
+ *partition_changed= TRUE;
+ }
}
if (thd->work_part_info)
{