Fix for bug #28125: ERROR 2013 when adding index.

Problem: we may break a multibyte char sequence using a key 
reduced to maximum allowed length for a storage engine
(that leads to failed assertion in the innodb code, 
see also #17530). 

Fix: align truncated key length to multibyte char boundary.
parent 261acdbb
...@@ -418,7 +418,7 @@ DROP TABLE t1,t2; ...@@ -418,7 +418,7 @@ DROP TABLE t1,t2;
create table t1(f1 varchar(800) binary not null, key(f1)) engine = innodb create table t1(f1 varchar(800) binary not null, key(f1)) engine = innodb
character set utf8 collate utf8_general_ci; character set utf8 collate utf8_general_ci;
Warnings: Warnings:
Warning 1071 Specified key was too long; max key length is 765 bytes Warning 1071 Specified key was too long; max key length is 767 bytes
insert into t1 values('aaa'); insert into t1 values('aaa');
drop table t1; drop table t1;
CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c FLOAT, KEY b(b)) ENGINE = INNODB; CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c FLOAT, KEY b(b)) ENGINE = INNODB;
...@@ -735,4 +735,16 @@ COUNT(*) ...@@ -735,4 +735,16 @@ COUNT(*)
3072 3072
set @@sort_buffer_size=default; set @@sort_buffer_size=default;
DROP TABLE t1,t2; DROP TABLE t1,t2;
create table t1(a text) engine=innodb default charset=utf8;
insert into t1 values('aaa');
alter table t1 add index(a(1024));
Warnings:
Warning 1071 Specified key was too long; max key length is 767 bytes
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` text,
KEY `a` (`a`(255))
) ENGINE=InnoDB DEFAULT CHARSET=utf8
drop table t1;
End of 5.0 tests End of 5.0 tests
...@@ -741,4 +741,13 @@ set @@sort_buffer_size=default; ...@@ -741,4 +741,13 @@ set @@sort_buffer_size=default;
DROP TABLE t1,t2; DROP TABLE t1,t2;
#
# Bug #28125: ERROR 2013 when adding index.
#
create table t1(a text) engine=innodb default charset=utf8;
insert into t1 values('aaa');
alter table t1 add index(a(1024));
show create table t1;
drop table t1;
--echo End of 5.0 tests --echo End of 5.0 tests
...@@ -1357,6 +1357,8 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, ...@@ -1357,6 +1357,8 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
length); length);
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TOO_LONG_KEY, warn_buff); ER_TOO_LONG_KEY, warn_buff);
/* Align key length to multibyte char boundary */
length-= length % sql_field->charset->mbmaxlen;
} }
else else
{ {
...@@ -1387,8 +1389,6 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, ...@@ -1387,8 +1389,6 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
if (length > file->max_key_part_length() && key->type != Key::FULLTEXT) if (length > file->max_key_part_length() && key->type != Key::FULLTEXT)
{ {
length= file->max_key_part_length(); length= file->max_key_part_length();
/* Align key length to multibyte char boundary */
length-= length % sql_field->charset->mbmaxlen;
if (key->type == Key::MULTIPLE) if (key->type == Key::MULTIPLE)
{ {
/* not a critical problem */ /* not a critical problem */
...@@ -1397,6 +1397,8 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, ...@@ -1397,6 +1397,8 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
length); length);
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TOO_LONG_KEY, warn_buff); ER_TOO_LONG_KEY, warn_buff);
/* Align key length to multibyte char boundary */
length-= length % sql_field->charset->mbmaxlen;
} }
else else
{ {
......
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