Skip to content

Commit

Permalink
MDEV-22899 Assertion `field->col->is_binary() || field->prefix_len % …
Browse files Browse the repository at this point in the history
…field->col->mbmaxlen == 0' failed in dict_index_add_to_cache

is_part_of_a_key(): detect is TEXT field is a part of some key

ha_innobase::can_convert_blob(): now correctly detect whether our blob
is a part of some key. Previously the check didn't work in some cases.
  • Loading branch information
kevgs committed Jul 20, 2020
1 parent 4b959bd commit c4d5b6b
Show file tree
Hide file tree
Showing 3 changed files with 172 additions and 26 deletions.
63 changes: 63 additions & 0 deletions mysql-test/suite/innodb/r/instant_alter_charset.result
Original file line number Diff line number Diff line change
Expand Up @@ -1929,3 +1929,66 @@ KEY a_idx(a(1))
INSERT INTO t VALUES (1, 'something in the air');
ALTER TABLE t MODIFY a text CHARSET utf8mb4;
DROP TABLE t;
#
# MDEV-22899: Assertion `field->col->is_binary() || field->prefix_len % field->col->mbmaxlen == 0' failed in dict_index_add_to_cache
#
CREATE TABLE t1 (
a text CHARACTER SET utf8 DEFAULT NULL,
KEY a_key (a(1))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO t1 VALUES ();
ALTER TABLE t1 MODIFY a text DEFAULT NULL;
DROP TABLE t1;
CREATE TABLE t1 (
a text CHARACTER SET utf8 DEFAULT NULL,
b int,
KEY a_key (b, a(1))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO t1 VALUES ();
ALTER TABLE t1 MODIFY a text DEFAULT NULL;
DROP TABLE t1;
CREATE TABLE t1 (
a char(200) CHARACTER SET utf8 DEFAULT NULL,
KEY a_key (a(1))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO t1 VALUES ();
ALTER TABLE t1 MODIFY a text DEFAULT NULL;
DROP TABLE t1;
CREATE TABLE t1 (
a char(200) CHARACTER SET utf8 DEFAULT NULL,
b int,
KEY a_key (b, a(1))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO t1 VALUES ();
ALTER TABLE t1 MODIFY a text DEFAULT NULL;
DROP TABLE t1;
CREATE TABLE t1 (
a varchar(200) CHARACTER SET utf8 DEFAULT NULL,
KEY a_key (a(1))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO t1 VALUES ();
ALTER TABLE t1 MODIFY a text DEFAULT NULL;
DROP TABLE t1;
CREATE TABLE t1 (
a varchar(200) CHARACTER SET utf8 DEFAULT NULL,
b int,
KEY a_key (b, a(1))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO t1 VALUES ();
ALTER TABLE t1 MODIFY a text DEFAULT NULL;
DROP TABLE t1;
CREATE TABLE t1 (
a varchar(2000) CHARACTER SET utf8 DEFAULT NULL,
KEY a_key (a(1))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO t1 VALUES ();
ALTER TABLE t1 MODIFY a text DEFAULT NULL;
DROP TABLE t1;
CREATE TABLE t1 (
a varchar(2000) CHARACTER SET utf8 DEFAULT NULL,
b int,
KEY a_key (b, a(1))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO t1 VALUES ();
ALTER TABLE t1 MODIFY a text DEFAULT NULL;
DROP TABLE t1;
73 changes: 73 additions & 0 deletions mysql-test/suite/innodb/t/instant_alter_charset.test
Original file line number Diff line number Diff line change
Expand Up @@ -730,3 +730,76 @@ INSERT INTO t VALUES (1, 'something in the air');
ALTER TABLE t MODIFY a text CHARSET utf8mb4;

DROP TABLE t;


--echo #
--echo # MDEV-22899: Assertion `field->col->is_binary() || field->prefix_len % field->col->mbmaxlen == 0' failed in dict_index_add_to_cache
--echo #

CREATE TABLE t1 (
a text CHARACTER SET utf8 DEFAULT NULL,
KEY a_key (a(1))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO t1 VALUES ();
ALTER TABLE t1 MODIFY a text DEFAULT NULL;
DROP TABLE t1;

CREATE TABLE t1 (
a text CHARACTER SET utf8 DEFAULT NULL,
b int,
KEY a_key (b, a(1))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO t1 VALUES ();
ALTER TABLE t1 MODIFY a text DEFAULT NULL;
DROP TABLE t1;

CREATE TABLE t1 (
a char(200) CHARACTER SET utf8 DEFAULT NULL,
KEY a_key (a(1))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO t1 VALUES ();
ALTER TABLE t1 MODIFY a text DEFAULT NULL;
DROP TABLE t1;

CREATE TABLE t1 (
a char(200) CHARACTER SET utf8 DEFAULT NULL,
b int,
KEY a_key (b, a(1))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO t1 VALUES ();
ALTER TABLE t1 MODIFY a text DEFAULT NULL;
DROP TABLE t1;

CREATE TABLE t1 (
a varchar(200) CHARACTER SET utf8 DEFAULT NULL,
KEY a_key (a(1))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO t1 VALUES ();
ALTER TABLE t1 MODIFY a text DEFAULT NULL;
DROP TABLE t1;

CREATE TABLE t1 (
a varchar(200) CHARACTER SET utf8 DEFAULT NULL,
b int,
KEY a_key (b, a(1))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO t1 VALUES ();
ALTER TABLE t1 MODIFY a text DEFAULT NULL;
DROP TABLE t1;

CREATE TABLE t1 (
a varchar(2000) CHARACTER SET utf8 DEFAULT NULL,
KEY a_key (a(1))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO t1 VALUES ();
ALTER TABLE t1 MODIFY a text DEFAULT NULL;
DROP TABLE t1;

CREATE TABLE t1 (
a varchar(2000) CHARACTER SET utf8 DEFAULT NULL,
b int,
KEY a_key (b, a(1))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO t1 VALUES ();
ALTER TABLE t1 MODIFY a text DEFAULT NULL;
DROP TABLE t1;
62 changes: 36 additions & 26 deletions storage/innobase/handler/ha_innodb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21074,39 +21074,49 @@ ha_innobase::can_convert_varstring(const Field_varstring* field,
return true;
}

bool
ha_innobase::can_convert_blob(const Field_blob* field,
const Column_definition& new_type) const
static bool is_part_of_a_key(const Field_blob *field)
{
if (new_type.type_handler() != field->type_handler()) {
return false;
}
const TABLE_SHARE *s= field->table->s;

if (!new_type.compression_method() != !field->compression_method()) {
return false;
}
for (uint i= 0; i < s->keys; i++)
{
const KEY &key= s->key_info[i];
for (uint j= 0; j < key.user_defined_key_parts; j++)
{
const KEY_PART_INFO &info= key.key_part[j];
if (info.field->field_index == field->field_index)
return true;
}
}

if (new_type.pack_length != field->pack_length()) {
return false;
}
return false;
}

if (new_type.charset != field->charset()) {
Charset field_cs(field->charset());
if (!field_cs.encoding_allows_reinterpret_as(
new_type.charset)) {
return false;
}
bool ha_innobase::can_convert_blob(const Field_blob *field,
const Column_definition &new_type) const
{
if (new_type.type_handler() != field->type_handler())
return false;

if (!field_cs.eq_collation_specific_names(new_type.charset)) {
bool is_part_of_a_key
= !field->part_of_key.is_clear_all();
return !is_part_of_a_key;
}
if (!new_type.compression_method() != !field->compression_method())
return false;

return true;
}
if (new_type.pack_length != field->pack_length())
return false;

return true;
if (new_type.charset != field->charset())
{
Charset field_cs(field->charset());
if (!field_cs.encoding_allows_reinterpret_as(new_type.charset))
return false;

if (!field_cs.eq_collation_specific_names(new_type.charset))
return !is_part_of_a_key(field);

return true;
}

return true;
}

Compare_keys ha_innobase::compare_key_parts(
Expand Down

0 comments on commit c4d5b6b

Please sign in to comment.