Commit fbcfbb0e authored by Aleksey Midenkov's avatar Aleksey Midenkov

MDEV-19751 Wrong partitioning by KEY() after primary key dropped

Default (empty) field list in partitioning by KEY() clause is assigned
from primary key. If primary key is changed the partitioning field
list is changed as well, so repartitioning required. Not applicable to
any non-primary keys as default field list may be taken only from
primary key.
parent 5530a93f
...@@ -122,3 +122,46 @@ t1 CREATE TABLE `t1` ( ...@@ -122,3 +122,46 @@ t1 CREATE TABLE `t1` (
PARTITION `p02` ENGINE = MyISAM, PARTITION `p02` ENGINE = MyISAM,
PARTITION `p03` ENGINE = MyISAM) PARTITION `p03` ENGINE = MyISAM)
drop table t1; 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;
...@@ -112,3 +112,42 @@ insert into t1 values(0, 1, 1, NULL, now(), now()); ...@@ -112,3 +112,42 @@ insert into t1 values(0, 1, 1, NULL, now(), now());
alter online table t1 delay_key_write=1; alter online table t1 delay_key_write=1;
show create table t1; show create table t1;
drop 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;
...@@ -5473,6 +5473,28 @@ the generated partition syntax in a correct manner. ...@@ -5473,6 +5473,28 @@ the generated partition syntax in a correct manner.
*partition_changed= TRUE; *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) if (thd->work_part_info)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment