Skip to content

Commit fbcfbb0

Browse files
committed
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.
1 parent 5530a93 commit fbcfbb0

File tree

3 files changed

+104
-0
lines changed

3 files changed

+104
-0
lines changed

mysql-test/r/partition_alter.result

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,46 @@ t1 CREATE TABLE `t1` (
122122
PARTITION `p02` ENGINE = MyISAM,
123123
PARTITION `p03` ENGINE = MyISAM)
124124
drop table t1;
125+
#
126+
# MDEV-19751 Wrong partitioning by KEY() after key dropped
127+
#
128+
create or replace table t1 (pk int, x timestamp(6), primary key (pk, x)) engine innodb
129+
partition by key() partitions 2;
130+
insert into t1 (pk, x) values (1, '2000-01-01 00:00'), (2, '2000-01-01 00:01');
131+
# Inplace for DROP PRIMARY KEY when partitioned by default field list is denied
132+
alter table t1 drop primary key, drop column x, add primary key (pk), algorithm=inplace;
133+
ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY
134+
alter table t1 drop primary key, drop column x, add primary key (pk);
135+
select * from t1 partition (p0);
136+
pk
137+
1
138+
drop table t1;
139+
create or replace table t1 (pk int not null, x timestamp(6), unique u(pk, x)) engine innodb
140+
partition by key() partitions 2;
141+
insert into t1 (pk, x) values (1, '2000-01-01 00:00'), (2, '2000-01-01 00:01');
142+
# Same for NOT NULL UNIQUE KEY as this is actually primary key
143+
alter table t1 drop key u, drop column x, add unique (pk), algorithm=inplace;
144+
ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY
145+
alter table t1 drop key u, drop column x, add unique (pk);
146+
select * from t1 partition (p0);
147+
pk
148+
1
149+
drop table t1;
150+
create or replace table t1 (pk int, x timestamp(6), primary key (pk)) engine innodb
151+
partition by key(pk) partitions 2;
152+
insert into t1 (pk, x) values (1, '2000-01-01 00:00'), (2, '2000-01-01 00:01');
153+
# Inplace for DROP PRIMARY KEY when partitioned by explicit field list is allowed
154+
alter table t1 drop primary key, add primary key (pk, x), algorithm=inplace;
155+
select * from t1 partition (p0);
156+
pk x
157+
1 2000-01-01 00:00:00.000000
158+
drop table t1;
159+
create or replace table t1 (k int, x timestamp(6), unique key u (x, k)) engine innodb
160+
partition by key(k) partitions 2;
161+
insert into t1 (k, x) values (1, '2000-01-01 00:00'), (2, '2000-01-01 00:01');
162+
# Inplace for DROP KEY is allowed
163+
alter table t1 drop key u, algorithm=inplace;
164+
select * from t1 partition (p0);
165+
k x
166+
1 2000-01-01 00:00:00.000000
167+
drop table t1;

mysql-test/t/partition_alter.test

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,42 @@ insert into t1 values(0, 1, 1, NULL, now(), now());
112112
alter online table t1 delay_key_write=1;
113113
show create table t1;
114114
drop table t1;
115+
116+
--echo #
117+
--echo # MDEV-19751 Wrong partitioning by KEY() after key dropped
118+
--echo #
119+
create or replace table t1 (pk int, x timestamp(6), primary key (pk, x)) engine innodb
120+
partition by key() partitions 2;
121+
insert into t1 (pk, x) values (1, '2000-01-01 00:00'), (2, '2000-01-01 00:01');
122+
--echo # Inplace for DROP PRIMARY KEY when partitioned by default field list is denied
123+
--error ER_ALTER_OPERATION_NOT_SUPPORTED
124+
alter table t1 drop primary key, drop column x, add primary key (pk), algorithm=inplace;
125+
alter table t1 drop primary key, drop column x, add primary key (pk);
126+
select * from t1 partition (p0);
127+
drop table t1;
128+
129+
create or replace table t1 (pk int not null, x timestamp(6), unique u(pk, x)) engine innodb
130+
partition by key() partitions 2;
131+
insert into t1 (pk, x) values (1, '2000-01-01 00:00'), (2, '2000-01-01 00:01');
132+
--echo # Same for NOT NULL UNIQUE KEY as this is actually primary key
133+
--error ER_ALTER_OPERATION_NOT_SUPPORTED
134+
alter table t1 drop key u, drop column x, add unique (pk), algorithm=inplace;
135+
alter table t1 drop key u, drop column x, add unique (pk);
136+
select * from t1 partition (p0);
137+
drop table t1;
138+
139+
create or replace table t1 (pk int, x timestamp(6), primary key (pk)) engine innodb
140+
partition by key(pk) partitions 2;
141+
insert into t1 (pk, x) values (1, '2000-01-01 00:00'), (2, '2000-01-01 00:01');
142+
--echo # Inplace for DROP PRIMARY KEY when partitioned by explicit field list is allowed
143+
alter table t1 drop primary key, add primary key (pk, x), algorithm=inplace;
144+
select * from t1 partition (p0);
145+
drop table t1;
146+
147+
create or replace table t1 (k int, x timestamp(6), unique key u (x, k)) engine innodb
148+
partition by key(k) partitions 2;
149+
insert into t1 (k, x) values (1, '2000-01-01 00:00'), (2, '2000-01-01 00:01');
150+
--echo # Inplace for DROP KEY is allowed
151+
alter table t1 drop key u, algorithm=inplace;
152+
select * from t1 partition (p0);
153+
drop table t1;

sql/sql_partition.cc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5473,6 +5473,28 @@ the generated partition syntax in a correct manner.
54735473
*partition_changed= TRUE;
54745474
}
54755475
}
5476+
/*
5477+
Prohibit inplace when partitioned by primary key and the primary key is dropped.
5478+
*/
5479+
if (!*partition_changed &&
5480+
tab_part_info->part_field_array &&
5481+
!tab_part_info->part_field_list.elements &&
5482+
table->s->primary_key != MAX_KEY)
5483+
{
5484+
KEY *primary_key= table->key_info + table->s->primary_key;
5485+
List_iterator_fast<Alter_drop> drop_it(alter_info->drop_list);
5486+
const char *primary_name= primary_key->name;
5487+
const Alter_drop *drop;
5488+
drop_it.rewind();
5489+
while ((drop= drop_it++))
5490+
{
5491+
if (drop->type == Alter_drop::KEY &&
5492+
0 == my_strcasecmp(system_charset_info, primary_name, drop->name))
5493+
break;
5494+
}
5495+
if (drop)
5496+
*partition_changed= TRUE;
5497+
}
54765498
}
54775499
if (thd->work_part_info)
54785500
{

0 commit comments

Comments
 (0)