From 9a0cbd31ce8576468981b14b066dea155cb922d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 4 Jul 2022 08:04:44 +0300 Subject: [PATCH] MDEV-26294 Duplicate entries in unique index not detected when changing collation ha_innobase::check_if_supported_inplace_alter(): Refuse to change the collation of a column that would become or remain indexed as part of the ALTER TABLE operation. In MariaDB Server 10.6, we will allow this type of operation; that fix depends on MDEV-15250. --- .../innodb/r/change_column_collation.result | 19 ++ .../r/instant_alter_charset,redundant.rdiff | 13 +- .../innodb/r/instant_alter_charset.result | 178 ++++++++++++++++-- .../innodb/t/change_column_collation.test | 24 +++ .../suite/innodb/t/instant_alter_charset.test | 23 +++ storage/innobase/handler/handler0alter.cc | 13 +- 6 files changed, 249 insertions(+), 21 deletions(-) create mode 100644 mysql-test/suite/innodb/r/change_column_collation.result create mode 100644 mysql-test/suite/innodb/t/change_column_collation.test diff --git a/mysql-test/suite/innodb/r/change_column_collation.result b/mysql-test/suite/innodb/r/change_column_collation.result new file mode 100644 index 00000000000..fa1df1df830 --- /dev/null +++ b/mysql-test/suite/innodb/r/change_column_collation.result @@ -0,0 +1,19 @@ +# +# MDEV-26294 Duplicate entries in unique index not detected when +# changing collation with INPLACE algorithm +# +SET NAMES utf8; +CREATE TABLE t1 ( +id INT PRIMARY KEY, +msg VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_swedish_ci UNIQUE +) ENGINE=INNODB; +INSERT INTO t1 VALUES (1, 'aaa'); +INSERT INTO t1 VALUES (2, 'ååå'); +ALTER TABLE t1 +MODIFY msg VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_unicode_ci, +ALGORITHM=NOCOPY; +ERROR 0A000: ALGORITHM=NOCOPY is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +ALTER TABLE t1 DROP INDEX msg, +MODIFY msg VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_unicode_ci, +ALGORITHM=NOCOPY; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/instant_alter_charset,redundant.rdiff b/mysql-test/suite/innodb/r/instant_alter_charset,redundant.rdiff index 22b7e46ea9c..dd4caf125af 100644 --- a/mysql-test/suite/innodb/r/instant_alter_charset,redundant.rdiff +++ b/mysql-test/suite/innodb/r/instant_alter_charset,redundant.rdiff @@ -1,6 +1,4 @@ ---- instant_alter_charset.result 2019-06-17 14:36:02.311515062 +0300 -+++ instant_alter_charset,redundant.result 2019-06-17 14:50:11.888705725 +0300 -@@ -279,7 +279,6 @@ +@@ -288,7 +288,6 @@ alter table boundary_255 modify a varchar(70) charset utf8mb4, algorithm=instant; @@ -8,7 +6,7 @@ drop table boundary_255; create table t ( a char(10) collate utf8mb3_general_ci, -@@ -297,32 +296,21 @@ +@@ -306,35 +305,21 @@ repeat('a', 10), repeat('a', 10) ); alter table t modify a char(10) collate utf8mb4_general_ci, algorithm=instant; @@ -27,16 +25,19 @@ -test.t check status OK +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY alter table t modify aa char(10) collate utf8mb4_general_ci, algorithm=instant; +-ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY -check table t; -Table Op Msg_type Msg_text -test.t check status OK +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY alter table t modify bb char(70) collate utf8mb4_general_ci, algorithm=instant; +-ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY -check table t; -Table Op Msg_type Msg_text -test.t check status OK +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY alter table t modify cc char(100) collate utf8mb4_general_ci, algorithm=instant; +-ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY -check table t; -Table Op Msg_type Msg_text -test.t check status OK @@ -44,8 +45,10 @@ alter table t modify d char(10) collate utf8mb4_spanish_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY alter table t modify dd char(10) collate utf8mb4_spanish_ci, algorithm=instant; --ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY +-ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY select * from t; a b c aa bb cc d dd aaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaa aaaaaaaaaa + +mysqltest: Result length mismatch diff --git a/mysql-test/suite/innodb/r/instant_alter_charset.result b/mysql-test/suite/innodb/r/instant_alter_charset.result index 43b4b2453e8..8fcdca6fc93 100644 --- a/mysql-test/suite/innodb/r/instant_alter_charset.result +++ b/mysql-test/suite/innodb/r/instant_alter_charset.result @@ -199,6 +199,15 @@ a varchar(150) charset utf8mb3 unique key alter table key_part_bug modify a varchar(150) charset utf8mb4, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table key_part_bug +modify a varchar(150) charset utf8mb4, +algorithm=nocopy; +ERROR 0A000: ALGORITHM=NOCOPY is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table key_part_bug +drop index a, +modify a varchar(150) charset utf8mb4, +algorithm=nocopy; drop table key_part_bug; create table latin1_swedish_special_case ( copy1 varchar(150) charset ascii collate ascii_general_ci, @@ -309,20 +318,23 @@ check table t; Table Op Msg_type Msg_text test.t check status OK alter table t modify aa char(10) collate utf8mb4_general_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY check table t; Table Op Msg_type Msg_text test.t check status OK alter table t modify bb char(70) collate utf8mb4_general_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY check table t; Table Op Msg_type Msg_text test.t check status OK alter table t modify cc char(100) collate utf8mb4_general_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY check table t; Table Op Msg_type Msg_text test.t check status OK alter table t modify d char(10) collate utf8mb4_spanish_ci, algorithm=instant; alter table t modify dd char(10) collate utf8mb4_spanish_ci, algorithm=instant; -ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY select * from t; a b c aa bb cc d dd aaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaa aaaaaaaaaa @@ -378,6 +390,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_general_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_general_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_general_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -391,6 +407,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_bin, modify b varchar(50) charset utf8mb4 collate utf8mb4_bin, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_bin, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -404,6 +424,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_unicode_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_unicode_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_unicode_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -417,6 +441,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_icelandic_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_icelandic_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_icelandic_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -430,6 +458,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_latvian_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_latvian_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_latvian_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -443,6 +475,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_romanian_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_romanian_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_romanian_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -456,6 +492,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_slovenian_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_slovenian_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_slovenian_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -469,6 +509,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_polish_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_polish_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_polish_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -482,6 +526,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_estonian_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_estonian_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_estonian_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -495,6 +543,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_spanish_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_spanish_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_spanish_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -508,6 +560,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_swedish_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_swedish_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_swedish_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -521,6 +577,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_turkish_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_turkish_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_turkish_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -534,6 +594,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_czech_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_czech_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_czech_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -547,6 +611,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_danish_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_danish_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_danish_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -560,6 +628,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_lithuanian_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_lithuanian_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_lithuanian_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -573,6 +645,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_slovak_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_slovak_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_slovak_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -586,6 +662,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_spanish2_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_spanish2_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_spanish2_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -599,6 +679,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_roman_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_roman_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_roman_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -612,6 +696,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_persian_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_persian_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_persian_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -625,6 +713,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_esperanto_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_esperanto_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_esperanto_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -638,6 +730,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_hungarian_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_hungarian_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_hungarian_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -651,6 +747,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_sinhala_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_sinhala_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_sinhala_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -664,6 +764,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_german2_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_german2_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_german2_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -677,6 +781,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_croatian_mysql561_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_croatian_mysql561_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_croatian_mysql561_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -690,6 +798,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_unicode_520_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_unicode_520_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_unicode_520_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -703,6 +815,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_vietnamese_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_vietnamese_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_vietnamese_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -716,6 +832,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_croatian_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_croatian_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_croatian_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -729,6 +849,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_myanmar_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_myanmar_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_myanmar_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -742,6 +866,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_thai_520_w2, modify b varchar(50) charset utf8mb4 collate utf8mb4_thai_520_w2, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_thai_520_w2, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -755,6 +883,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_general_nopad_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_general_nopad_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_general_nopad_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -768,6 +900,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_nopad_bin, modify b varchar(50) charset utf8mb4 collate utf8mb4_nopad_bin, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_nopad_bin, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -781,6 +917,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_unicode_nopad_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_unicode_nopad_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_unicode_nopad_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -794,6 +934,10 @@ alter table tmp change a a varchar(50) charset utf8mb4 collate utf8mb4_unicode_520_nopad_ci, modify b varchar(50) charset utf8mb4 collate utf8mb4_unicode_520_nopad_ci, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table tmp +change a a varchar(50) charset utf8mb4 collate utf8mb4_unicode_520_nopad_ci, +algorithm=instant; check table tmp; Table Op Msg_type Msg_text test.tmp check status OK @@ -830,7 +974,7 @@ algorithm=instant; alter table tmp modify b varchar(50) charset utf8mb4 collate utf8mb4_vietnamese_ci, algorithm=instant; -ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY alter table tmp modify c varchar(50) charset utf8mb4 collate utf8mb4_vietnamese_ci, algorithm=instant; @@ -847,7 +991,7 @@ algorithm=instant; alter table tmp modify b varchar(50) charset utf8mb4 collate utf8mb4_vietnamese_ci, algorithm=instant; -ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY alter table tmp modify c varchar(50) charset utf8mb4 collate utf8mb4_vietnamese_ci, algorithm=instant; @@ -864,7 +1008,7 @@ algorithm=instant; alter table tmp modify b varchar(50) charset utf8mb4 collate utf8mb4_vietnamese_ci, algorithm=instant; -ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY alter table tmp modify c varchar(50) charset utf8mb4 collate utf8mb4_vietnamese_ci, algorithm=instant; @@ -881,7 +1025,7 @@ algorithm=instant; alter table tmp modify b varchar(50) charset utf8mb4 collate utf8mb4_vietnamese_ci, algorithm=instant; -ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY alter table tmp modify c varchar(50) charset utf8mb4 collate utf8mb4_vietnamese_ci, algorithm=instant; @@ -898,7 +1042,7 @@ algorithm=instant; alter table tmp modify b varchar(50) charset ascii collate ascii_bin, algorithm=instant; -ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY alter table tmp modify c varchar(50) charset ascii collate ascii_bin, algorithm=instant; @@ -915,7 +1059,7 @@ algorithm=instant; alter table tmp modify b varchar(50) charset utf8mb3 collate utf8mb3_lithuanian_ci, algorithm=instant; -ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY alter table tmp modify c varchar(50) charset utf8mb3 collate utf8mb3_lithuanian_ci, algorithm=instant; @@ -932,7 +1076,7 @@ algorithm=instant; alter table tmp modify b varchar(50) charset utf8mb4 collate utf8mb4_persian_ci, algorithm=instant; -ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY alter table tmp modify c varchar(50) charset utf8mb4 collate utf8mb4_persian_ci, algorithm=instant; @@ -949,7 +1093,7 @@ algorithm=instant; alter table tmp modify b varchar(50) charset utf8mb4 collate utf8mb4_german2_ci, algorithm=instant; -ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY alter table tmp modify c varchar(50) charset utf8mb4 collate utf8mb4_german2_ci, algorithm=instant; @@ -966,7 +1110,7 @@ algorithm=instant; alter table tmp modify b varchar(50) charset utf8mb3 collate utf8mb3_unicode_ci, algorithm=instant; -ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY alter table tmp modify c varchar(50) charset utf8mb3 collate utf8mb3_unicode_ci, algorithm=instant; @@ -983,7 +1127,7 @@ algorithm=instant; alter table tmp modify b varchar(50) charset latin1 collate latin1_general_ci, algorithm=instant; -ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY alter table tmp modify c varchar(50) charset latin1 collate latin1_general_ci, algorithm=instant; @@ -1000,7 +1144,7 @@ algorithm=instant; alter table tmp modify b varchar(50) charset utf16 collate utf16_german2_ci, algorithm=instant; -ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY alter table tmp modify c varchar(50) charset utf16 collate utf16_german2_ci, algorithm=instant; @@ -1887,8 +2031,11 @@ insert into t values alter table t modify a char(10) collate latin1_general_cs, algorithm=inplace; ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY alter table t modify b char(10) collate latin1_general_cs, algorithm=instant; -ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY alter table t modify b char(10) collate latin1_general_cs, algorithm=nocopy; +ERROR 0A000: ALGORITHM=NOCOPY is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table t modify b char(10) collate latin1_general_cs, +drop index b_key, algorithm=nocopy; check table t; Table Op Msg_type Msg_text test.t check status OK @@ -1908,8 +2055,11 @@ insert into t values alter table t modify a varchar(10) collate latin1_general_cs, algorithm=inplace; ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY alter table t modify b varchar(10) collate latin1_general_cs, algorithm=instant; -ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY alter table t modify b varchar(10) collate latin1_general_cs, algorithm=nocopy; +ERROR 0A000: ALGORITHM=NOCOPY is not supported. Reason: Collation change on an indexed column. Try ALGORITHM=COPY +alter table t modify b varchar(10) collate latin1_general_cs, +drop index b_key, algorithm=nocopy; check table t; Table Op Msg_type Msg_text test.t check status OK diff --git a/mysql-test/suite/innodb/t/change_column_collation.test b/mysql-test/suite/innodb/t/change_column_collation.test new file mode 100644 index 00000000000..1ba519535bd --- /dev/null +++ b/mysql-test/suite/innodb/t/change_column_collation.test @@ -0,0 +1,24 @@ +--source include/have_innodb.inc + +--echo # +--echo # MDEV-26294 Duplicate entries in unique index not detected when +--echo # changing collation with INPLACE algorithm +--echo # + +# Detect the duplicate entry after collation change of column + +SET NAMES utf8; +CREATE TABLE t1 ( + id INT PRIMARY KEY, + msg VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_swedish_ci UNIQUE +) ENGINE=INNODB; +INSERT INTO t1 VALUES (1, 'aaa'); +INSERT INTO t1 VALUES (2, 'ååå'); +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +ALTER TABLE t1 +MODIFY msg VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_unicode_ci, +ALGORITHM=NOCOPY; +ALTER TABLE t1 DROP INDEX msg, +MODIFY msg VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_unicode_ci, +ALGORITHM=NOCOPY; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/instant_alter_charset.test b/mysql-test/suite/innodb/t/instant_alter_charset.test index d64e30402ed..de60c24c0cd 100644 --- a/mysql-test/suite/innodb/t/instant_alter_charset.test +++ b/mysql-test/suite/innodb/t/instant_alter_charset.test @@ -227,9 +227,18 @@ create table key_part_bug ( a varchar(150) charset utf8mb3 unique key ) engine=innodb; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON alter table key_part_bug modify a varchar(150) charset utf8mb4, algorithm=instant; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +alter table key_part_bug + modify a varchar(150) charset utf8mb4, + algorithm=nocopy; +alter table key_part_bug + drop index a, + modify a varchar(150) charset utf8mb4, + algorithm=nocopy; drop table key_part_bug; @@ -347,10 +356,13 @@ check table t; alter table t modify c char(100) collate utf8mb4_general_ci, algorithm=instant; check table t; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON alter table t modify aa char(10) collate utf8mb4_general_ci, algorithm=instant; check table t; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON alter table t modify bb char(70) collate utf8mb4_general_ci, algorithm=instant; check table t; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON alter table t modify cc char(100) collate utf8mb4_general_ci, algorithm=instant; check table t; @@ -442,11 +454,16 @@ while ($counter <= $data_size) { insert into tmp values ('AAA', 'AAA'), ('bbb', 'bbb'); +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON eval alter table tmp change a a varchar(50) charset $to_charset collate $to_collate, modify b varchar(50) charset $to_charset collate $to_collate, algorithm=instant; + eval alter table tmp + change a a varchar(50) charset $to_charset collate $to_collate, + algorithm=instant; + check table tmp; drop table tmp; @@ -685,7 +702,10 @@ alter table t modify a char(10) collate latin1_general_cs, algorithm=inplace; --error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON alter table t modify b char(10) collate latin1_general_cs, algorithm=instant; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON alter table t modify b char(10) collate latin1_general_cs, algorithm=nocopy; +alter table t modify b char(10) collate latin1_general_cs, +drop index b_key, algorithm=nocopy; check table t; alter table t modify c char(10) collate latin1_general_cs, algorithm=instant; @@ -708,7 +728,10 @@ alter table t modify a varchar(10) collate latin1_general_cs, algorithm=inplace; --error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON alter table t modify b varchar(10) collate latin1_general_cs, algorithm=instant; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON alter table t modify b varchar(10) collate latin1_general_cs, algorithm=nocopy; +alter table t modify b varchar(10) collate latin1_general_cs, +drop index b_key, algorithm=nocopy; check table t; alter table t modify c varchar(10) collate latin1_general_cs, algorithm=instant; diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 480ca99c538..8c51f80f1d3 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2005, 2019, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2021, MariaDB Corporation. +Copyright (c) 2013, 2022, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -2310,7 +2310,16 @@ innodb_instant_alter_column_allowed_reason: if (new_field->field) { /* This is an existing column. */ - continue; + + if (new_field->field->charset() + == key_part->field->charset()) { + continue; + } + + ha_alter_info->unsupported_reason = + "Collation change on" + " an indexed column"; + DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); } /* This is an added column. */