Created
April 11, 2019 14:57
-
-
Save kevgs/efc2294fde83063dbd69945f6ce57c01 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/mysql-test/suite/innodb/r/instant_alter_charset.result b/mysql-test/suite/innodb/r/instant_alter_charset.result | |
index 268848f31ec..53814c4712b 100644 | |
--- a/mysql-test/suite/innodb/r/instant_alter_charset.result | |
+++ b/mysql-test/suite/innodb/r/instant_alter_charset.result | |
@@ -259,6 +259,52 @@ alter table boundary_255 | |
modify c varchar(300) charset utf8mb3, | |
algorithm=instant; | |
drop table boundary_255; | |
+create table t ( | |
+a char(10) collate utf8mb3_general_ci, | |
+b char(70) collate utf8mb3_general_ci, | |
+c char(100) collate utf8mb3_general_ci, | |
+aa char(10) collate utf8mb3_general_ci unique, | |
+bb char(70) collate utf8mb3_general_ci unique, | |
+cc char(100) collate utf8mb3_general_ci unique, | |
+d char(10) collate utf8mb3_general_ci, | |
+dd char(10) collate utf8mb3_general_ci unique | |
+) engine=innodb; | |
+insert into t values | |
+(repeat('a', 10), repeat('a', 70), repeat('a', 100), | |
+repeat('a', 10), repeat('a', 70), repeat('a', 100), | |
+repeat('a', 10), repeat('a', 10) | |
+); | |
+alter table t modify a char(10) collate utf8mb4_general_ci, algorithm=instant; | |
+check table t; | |
+Table Op Msg_type Msg_text | |
+test.t check status OK | |
+alter table t modify b char(70) collate utf8mb4_general_ci, algorithm=instant; | |
+check table t; | |
+Table Op Msg_type Msg_text | |
+test.t check status OK | |
+alter table t modify c char(100) collate utf8mb4_general_ci, algorithm=instant; | |
+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; | |
+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; | |
+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; | |
+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: Cannot change column type INPLACE. Try ALGORITHM=COPY | |
+select * from t; | |
+a b c aa bb cc d dd | |
+aaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaa aaaaaaaaaa | |
+drop table t; | |
create table fully_compatible ( | |
id int auto_increment unique key, | |
from_charset char(255), | |
@@ -1488,7 +1534,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: Cannot change column type INPLACE. Try ALGORITHM=COPY | |
+ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY | |
alter table tmp | |
modify c varchar(50) charset ascii collate ascii_bin, | |
algorithm=instant; | |
@@ -1505,7 +1551,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: Cannot change column type INPLACE. Try ALGORITHM=COPY | |
+ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY | |
alter table tmp | |
modify c varchar(50) charset utf8mb3 collate utf8mb3_lithuanian_ci, | |
algorithm=instant; | |
@@ -1522,7 +1568,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: Cannot change column type INPLACE. Try ALGORITHM=COPY | |
+ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY | |
alter table tmp | |
modify c varchar(50) charset utf8mb4 collate utf8mb4_persian_ci, | |
algorithm=instant; | |
@@ -1556,7 +1602,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: Cannot change column type INPLACE. Try ALGORITHM=COPY | |
+ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY | |
alter table tmp | |
modify c varchar(50) charset utf8mb3 collate utf8mb3_unicode_ci, | |
algorithm=instant; | |
@@ -1573,7 +1619,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: Cannot change column type INPLACE. Try ALGORITHM=COPY | |
+ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY | |
alter table tmp | |
modify c varchar(50) charset latin1 collate latin1_general_ci, | |
algorithm=instant; | |
@@ -1658,7 +1704,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: Cannot change column type INPLACE. Try ALGORITHM=COPY | |
+ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY | |
alter table tmp | |
modify c varchar(50) charset utf16 collate utf16_german2_ci, | |
algorithm=instant; | |
@@ -1810,3 +1856,45 @@ algorithm=instant; | |
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY | |
drop table tmp; | |
drop table fully_incompatible; | |
+create table t ( | |
+a char(10) collate latin1_general_ci primary key, | |
+b char(10) collate latin1_general_ci, | |
+c char(10) collate latin1_general_ci, | |
+unique key b_key(b) | |
+) engine=innodb; | |
+insert into t values | |
+('aaa', 'aaa', 'aaa'), ('ccc', 'ccc', 'ccc'), ('bbb', 'bbb', 'bbb'); | |
+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 INPLACE. 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 | |
+alter table t modify b char(10) collate latin1_general_cs, algorithm=nocopy; | |
+check table t; | |
+Table Op Msg_type Msg_text | |
+test.t check status OK | |
+alter table t modify c char(10) collate latin1_general_cs, algorithm=instant; | |
+check table t; | |
+Table Op Msg_type Msg_text | |
+test.t check status OK | |
+drop table t; | |
+create table t ( | |
+a varchar(10) collate latin1_general_ci primary key, | |
+b varchar(10) collate latin1_general_ci, | |
+c varchar(10) collate latin1_general_ci, | |
+unique key b_key(b) | |
+) engine=innodb; | |
+insert into t values | |
+('aaa', 'aaa', 'aaa'), ('ccc', 'ccc', 'ccc'), ('bbb', 'bbb', 'bbb'); | |
+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 INPLACE. 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 | |
+alter table t modify b varchar(10) collate latin1_general_cs, algorithm=nocopy; | |
+check table t; | |
+Table Op Msg_type Msg_text | |
+test.t check status OK | |
+alter table t modify c varchar(10) collate latin1_general_cs, algorithm=instant; | |
+check table t; | |
+Table Op Msg_type Msg_text | |
+test.t check status OK | |
+drop table t; | |
diff --git a/mysql-test/suite/innodb/t/instant_alter_charset.test b/mysql-test/suite/innodb/t/instant_alter_charset.test | |
index 82ab9f9eb94..c67f2921330 100644 | |
--- a/mysql-test/suite/innodb/t/instant_alter_charset.test | |
+++ b/mysql-test/suite/innodb/t/instant_alter_charset.test | |
@@ -297,6 +297,67 @@ alter table boundary_255 | |
drop table boundary_255; | |
+ | |
+create table t ( | |
+ a char(10) collate utf8mb3_general_ci, | |
+ b char(70) collate utf8mb3_general_ci, | |
+ c char(100) collate utf8mb3_general_ci, | |
+ | |
+ aa char(10) collate utf8mb3_general_ci unique, | |
+ bb char(70) collate utf8mb3_general_ci unique, | |
+ cc char(100) collate utf8mb3_general_ci unique, | |
+ | |
+ d char(10) collate utf8mb3_general_ci, | |
+ dd char(10) collate utf8mb3_general_ci unique | |
+) engine=innodb; | |
+insert into t values | |
+ (repeat('a', 10), repeat('a', 70), repeat('a', 100), | |
+ repeat('a', 10), repeat('a', 70), repeat('a', 100), | |
+ repeat('a', 10), repeat('a', 10) | |
+); | |
+if ($row_format != 'redundant') { | |
+alter table t modify a char(10) collate utf8mb4_general_ci, algorithm=instant; | |
+check table t; | |
+alter table t modify b char(70) collate utf8mb4_general_ci, algorithm=instant; | |
+check table t; | |
+alter table t modify c char(100) collate utf8mb4_general_ci, algorithm=instant; | |
+check table t; | |
+ | |
+alter table t modify aa char(10) collate utf8mb4_general_ci, algorithm=instant; | |
+check table t; | |
+alter table t modify bb char(70) collate utf8mb4_general_ci, algorithm=instant; | |
+check table t; | |
+alter table t modify cc char(100) collate utf8mb4_general_ci, algorithm=instant; | |
+check table t; | |
+ | |
+alter table t modify d char(10) collate utf8mb4_spanish_ci, algorithm=instant; | |
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON | |
+alter table t modify dd char(10) collate utf8mb4_spanish_ci, algorithm=instant; | |
+} | |
+if ($row_format == 'redundant') { | |
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON | |
+alter table t modify a char(10) collate utf8mb4_general_ci, algorithm=instant; | |
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON | |
+alter table t modify b char(70) collate utf8mb4_general_ci, algorithm=instant; | |
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON | |
+alter table t modify c char(100) collate utf8mb4_general_ci, algorithm=instant; | |
+ | |
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON | |
+alter table t modify aa char(10) collate utf8mb4_general_ci, algorithm=instant; | |
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON | |
+alter table t modify bb char(70) collate utf8mb4_general_ci, algorithm=instant; | |
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON | |
+alter table t modify cc char(100) collate utf8mb4_general_ci, algorithm=instant; | |
+ | |
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON | |
+alter table t modify d char(10) collate utf8mb4_spanish_ci, algorithm=instant; | |
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON | |
+alter table t modify dd char(10) collate utf8mb4_spanish_ci, algorithm=instant; | |
+} | |
+select * from t; | |
+drop table t; | |
+ | |
+ | |
create table fully_compatible ( | |
id int auto_increment unique key, | |
from_charset char(255), | |
@@ -536,3 +597,50 @@ while ($counter <= $data_size) { | |
} | |
drop table fully_incompatible; | |
+ | |
+ | |
+create table t ( | |
+ a char(10) collate latin1_general_ci primary key, | |
+ b char(10) collate latin1_general_ci, | |
+ c char(10) collate latin1_general_ci, | |
+ unique key b_key(b) | |
+) engine=innodb; | |
+ | |
+insert into t values | |
+ ('aaa', 'aaa', 'aaa'), ('ccc', 'ccc', 'ccc'), ('bbb', 'bbb', 'bbb'); | |
+ | |
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON | |
+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; | |
+alter table t modify b char(10) collate latin1_general_cs, algorithm=nocopy; | |
+check table t; | |
+ | |
+alter table t modify c char(10) collate latin1_general_cs, algorithm=instant; | |
+check table t; | |
+ | |
+drop table t; | |
+ | |
+create table t ( | |
+ a varchar(10) collate latin1_general_ci primary key, | |
+ b varchar(10) collate latin1_general_ci, | |
+ c varchar(10) collate latin1_general_ci, | |
+ unique key b_key(b) | |
+) engine=innodb; | |
+ | |
+insert into t values | |
+ ('aaa', 'aaa', 'aaa'), ('ccc', 'ccc', 'ccc'), ('bbb', 'bbb', 'bbb'); | |
+ | |
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON | |
+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; | |
+alter table t modify b varchar(10) collate latin1_general_cs, algorithm=nocopy; | |
+check table t; | |
+ | |
+alter table t modify c varchar(10) collate latin1_general_cs, algorithm=instant; | |
+check table t; | |
+ | |
+drop table t; | |
diff --git a/sql/field.cc b/sql/field.cc | |
index 4a93464b2e8..ef47b761c98 100644 | |
--- a/sql/field.cc | |
+++ b/sql/field.cc | |
@@ -7074,26 +7074,82 @@ uint Field::is_equal(Create_field *new_field) | |
return new_field->type_handler() == type_handler(); | |
} | |
+static bool same_charset_but_not_collate(const CHARSET_INFO *a, | |
+ const CHARSET_INFO *b) | |
+{ | |
+ return !strcmp(a->csname, b->csname) && strcmp(a->name, b->name); | |
+} | |
+ | |
+static bool have_different_collate(const CHARSET_INFO *a, const CHARSET_INFO *b) | |
+{ | |
+ return strcmp(a->name + strlen(a->csname), b->name + strlen(b->csname)); | |
+} | |
+ | |
+static bool part_of_a_primary_key(const Field *field) { | |
+ const TABLE_SHARE *s= field->table->s; | |
+ | |
+ if (s->primary_key == MAX_KEY) | |
+ return false; | |
+ | |
+ return field->part_of_key.is_set(s->primary_key); | |
+} | |
uint Field_str::is_equal(Create_field *new_field) | |
{ | |
if (new_field->type_handler() != type_handler()) | |
return IS_EQUAL_NO; | |
- if (new_field->length < max_display_length()) | |
- return IS_EQUAL_NO; | |
if (new_field->char_length < char_length()) | |
return IS_EQUAL_NO; | |
- const bool part_of_a_key= !new_field->field->part_of_key.is_clear_all(); | |
- if (!Type_handler::Charsets_are_compatible(field_charset, new_field->charset, | |
- part_of_a_key)) | |
- return IS_EQUAL_NO; | |
+ if (new_field->length != max_display_length()) | |
+ { | |
+ if (table->file->ha_table_flags() & HA_EXTENDED_TYPES_CONVERSION) | |
+ return IS_EQUAL_NO; | |
- if (new_field->length == max_display_length()) | |
- return new_field->charset == field_charset | |
- ? IS_EQUAL_YES : IS_EQUAL_PACK_LENGTH; | |
+ if (strcmp(field_charset->csname, MY_UTF8MB3) || | |
+ strcmp(new_field->charset->csname, MY_UTF8MB4)) | |
+ { | |
+ return IS_EQUAL_NO; | |
+ } | |
- return IS_EQUAL_NO; | |
+ const bool same_collate= | |
+ !strcmp(field_charset->name + strlen(field_charset->csname), | |
+ new_field->charset->name + strlen(new_field->charset->csname)); | |
+ | |
+ const bool part_of_a_key= !new_field->field->part_of_key.is_clear_all(); | |
+ | |
+ if (part_of_a_key && !same_collate) | |
+ return IS_EQUAL_NO; | |
+ | |
+ return IS_EQUAL_PACK_LENGTH; | |
+ } | |
+ | |
+ if (new_field->charset != field_charset) | |
+ { | |
+ if (part_of_a_primary_key(new_field->field) && | |
+ have_different_collate(new_field->charset, field_charset)) | |
+ { | |
+ return IS_EQUAL_NO; | |
+ } | |
+ | |
+ const bool part_of_a_key= !new_field->field->part_of_key.is_clear_all(); | |
+ | |
+ if (Type_handler::Charsets_are_compatible(field_charset, new_field->charset, | |
+ part_of_a_key)) | |
+ { | |
+ return IS_EQUAL_PACK_LENGTH; | |
+ } | |
+ | |
+ if (part_of_a_key && | |
+ same_charset_but_not_collate(new_field->charset, field_charset)) | |
+ { | |
+ return IS_EQUAL_BUT_COLLATE; | |
+ } | |
+ | |
+ return IS_EQUAL_NO; | |
+ } | |
+ | |
+ return IS_EQUAL_YES; | |
} | |
@@ -7927,6 +7983,19 @@ Field *Field_varstring::new_key_field(MEM_ROOT *root, TABLE *new_table, | |
return res; | |
} | |
+// This check is InnoDB specific. ROW_FORMAT=REDUNDANT always allows such | |
+// enlargement. But other row formats can do this only for particular current | |
+// and new lengths. This is because InnoDB stores VARCHAR length in one or two | |
+// bytes. | |
+static bool supports_such_enlargement(const Field_varstring *varchar, | |
+ Create_field *new_field) | |
+{ | |
+ return varchar->field_length <= 127 || new_field->length <= 255 || | |
+ varchar->field_length > 255 || | |
+ (varchar->table->file->ha_table_flags() & | |
+ HA_EXTENDED_TYPES_CONVERSION); | |
+} | |
+ | |
uint Field_varstring::is_equal(Create_field *new_field) | |
{ | |
if (new_field->length < field_length) | |
@@ -7935,26 +8004,46 @@ uint Field_varstring::is_equal(Create_field *new_field) | |
return IS_EQUAL_NO; | |
if (!new_field->compression_method() != !compression_method()) | |
return IS_EQUAL_NO; | |
+ if (new_field->type_handler() != type_handler()) | |
+ return IS_EQUAL_NO; | |
+ | |
+ if (new_field->charset != field_charset) | |
+ { | |
+ if (part_of_a_primary_key(new_field->field) && | |
+ have_different_collate(new_field->charset, field_charset)) | |
+ { | |
+ return IS_EQUAL_NO; | |
+ } | |
+ | |
+ const bool part_of_a_key= !new_field->field->part_of_key.is_clear_all(); | |
+ | |
+ if (Type_handler::Charsets_are_compatible(field_charset, new_field->charset, | |
+ part_of_a_key)) | |
+ { | |
+ if (!supports_such_enlargement(this, new_field)) | |
+ return IS_EQUAL_NO; | |
+ | |
+ return IS_EQUAL_PACK_LENGTH; | |
+ } | |
+ | |
+ if (part_of_a_key && | |
+ same_charset_but_not_collate(new_field->charset, field_charset)) | |
+ { | |
+ return IS_EQUAL_BUT_COLLATE; | |
+ } | |
- bool part_of_a_key= !new_field->field->part_of_key.is_clear_all(); | |
- if (!Type_handler::Charsets_are_compatible(field_charset, new_field->charset, | |
- part_of_a_key)) | |
return IS_EQUAL_NO; | |
+ } | |
- const Type_handler *new_type_handler= new_field->type_handler(); | |
- if (new_type_handler == type_handler()) | |
+ if (new_field->length != field_length) | |
{ | |
- if (new_field->length == field_length) | |
- return new_field->charset == field_charset | |
- ? IS_EQUAL_YES : IS_EQUAL_PACK_LENGTH; | |
- if (field_length <= 127 || | |
- new_field->length <= 255 || | |
- field_length > 255 || | |
- (table->file->ha_table_flags() & HA_EXTENDED_TYPES_CONVERSION)) | |
- return IS_EQUAL_PACK_LENGTH; // VARCHAR, longer length | |
+ if (!supports_such_enlargement(this, new_field)) | |
+ return IS_EQUAL_NO; | |
+ | |
+ return IS_EQUAL_PACK_LENGTH; // VARCHAR, longer length | |
} | |
- return IS_EQUAL_NO; | |
+ return IS_EQUAL_YES; | |
} | |
diff --git a/sql/sql_priv.h b/sql/sql_priv.h | |
index 4332a6961d9..ba301ff767f 100644 | |
--- a/sql/sql_priv.h | |
+++ b/sql/sql_priv.h | |
@@ -354,6 +354,10 @@ | |
data dictionary without changing table rows | |
*/ | |
#define IS_EQUAL_PACK_LENGTH 2 | |
+/** | |
+ Tests fields are equal in any aspect but a COLLATE | |
+*/ | |
+#define IS_EQUAL_BUT_COLLATE 3 | |
enum enum_parsing_place | |
{ | |
diff --git a/sql/sql_table.cc b/sql/sql_table.cc | |
index 28c67f0e59a..73ebb1a04ca 100644 | |
--- a/sql/sql_table.cc | |
+++ b/sql/sql_table.cc | |
@@ -6559,16 +6559,18 @@ Compare_keys compare_keys_but_name(const KEY *table_key, const KEY *new_key, | |
((Field_varstring *) old_field)->length_bytes); | |
} | |
+ uint is_equal= key_part->field->is_equal(new_field); | |
if (key_part->length == old_field_len && | |
- key_part->length < new_part->length && | |
- (key_part->field->is_equal((Create_field *) new_field) == | |
- IS_EQUAL_PACK_LENGTH)) | |
+ key_part->length < new_part->length && is_equal == IS_EQUAL_PACK_LENGTH) | |
{ | |
result= Compare_keys::EqualButKeyPartLength; | |
} | |
else if (key_part->length != new_part->length) | |
return Compare_keys::NotEqual; | |
+ if (is_equal == IS_EQUAL_BUT_COLLATE) | |
+ return Compare_keys::NotEqual; | |
+ | |
/* | |
For prefix keys KEY_PART_INFO::field points to cloned Field | |
object with adjusted length. So below we have to check field | |
@@ -6783,6 +6785,8 @@ static bool fill_alter_inplace_info(THD *thd, TABLE *table, bool varchar, | |
*/ | |
ha_alter_info->handler_flags|= ALTER_COLUMN_EQUAL_PACK_LENGTH; | |
break; | |
+ case IS_EQUAL_BUT_COLLATE: | |
+ break; | |
default: | |
DBUG_ASSERT(0); | |
/* Safety. */ | |
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc | |
index ad8d065de90..11376116cfa 100644 | |
--- a/storage/innobase/handler/handler0alter.cc | |
+++ b/storage/innobase/handler/handler0alter.cc | |
@@ -8955,13 +8955,20 @@ innobase_rename_or_enlarge_column_try( | |
#ifdef UNIV_DEBUG | |
switch (mtype) { | |
+ case DATA_MYSQL: | |
+ if (!(prtype & DATA_BINARY_TYPE) || user_table->not_redundant() | |
+ || col->mbminlen != col->mbmaxlen) { | |
+ /* NOTE: we could allow this when !(prtype & | |
+ DATA_BINARY_TYPE) and ROW_FORMAT is not REDUNDANT and | |
+ mbminlen<mbmaxlen. That is, we treat a UTF-8 CHAR(n) | |
+ column somewhat like a VARCHAR. */ | |
+ ut_ad(col->mbminlen <= col->mbmaxlen); | |
+ break; | |
+ } | |
+ /* fall through */ | |
case DATA_FIXBINARY: | |
case DATA_CHAR: | |
- case DATA_MYSQL: | |
- /* NOTE: we could allow this when !(prtype & DATA_BINARY_TYPE) | |
- and ROW_FORMAT is not REDUNDANT and mbminlen<mbmaxlen. | |
- That is, we treat a UTF-8 CHAR(n) column somewhat like | |
- a VARCHAR. */ | |
+ ut_ad(col->mbminlen <= col->mbmaxlen); | |
ut_ad(col->len == len); | |
break; | |
case DATA_BINARY: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment