Skip to content

Commit ea9dbef

Browse files
author
Aditya A
committed
Bug#20755615 CREATING INDEX ON A RENAMED COLUMN WITH CASE CRASH .FRM
FILE PROBLEM In 5.5 when doing doing a rename of a column ,we ignore the case between old and new column names while comparing them,so if the change is just the case then we don't even mark the field FIELD_IS_RENAMED ,we just update the frm file ,but don't recreate the table as is the norm when alter is used.This leads to inconsistency in the innodb data dictionary which causes index creation to fail. FIX According to the documentation any innodb column rename should trigger rebuild of the table. Therefore for innodb tables we will do a strcmp() between the column names and if there is case change in column name we will trigger a rebuild.
1 parent 86375f7 commit ea9dbef

File tree

3 files changed

+52
-4
lines changed

3 files changed

+52
-4
lines changed

mysql-test/r/alter_table.result

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,3 +1488,20 @@ CREATE TABLE help_topic (dummy int) ENGINE=innodb;
14881488
ERROR HY000: Storage engine 'InnoDB' does not support system tables. [mysql.help_topic]
14891489
use test;
14901490
# End of Bug#11815557
1491+
#
1492+
# Bug#20755615 CREATING INDEX ON A RENAMED
1493+
# COLUMN WITH CASE CRASH .FRM FILE
1494+
#
1495+
CREATE TABLE t1 (D INT) ENGINE=innodb;
1496+
INSERT INTO t1 VALUES (10);
1497+
ALTER TABLE t1 MODIFY COLUMN d INT;
1498+
ALTER TABLE t1 ADD INDEX (d);
1499+
DROP TABLE t1;
1500+
CREATE TABLE t1 (`�` int) ENGINE=innodb;
1501+
INSERT INTO t1 VALUES (10);
1502+
ALTER TABLE t1 CHANGE `�` `�` INT;
1503+
ALTER TABLE t1 ADD INDEX (`�`);
1504+
SELECT * FROM t1;
1505+
1506+
10
1507+
DROP TABLE t1;

mysql-test/t/alter_table.test

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1261,3 +1261,22 @@ CREATE TABLE time_zone (dummy int) ENGINE=merge;
12611261
CREATE TABLE help_topic (dummy int) ENGINE=innodb;
12621262
use test;
12631263
--echo # End of Bug#11815557
1264+
1265+
--echo #
1266+
--echo # Bug#20755615 CREATING INDEX ON A RENAMED
1267+
--echo # COLUMN WITH CASE CRASH .FRM FILE
1268+
--echo #
1269+
1270+
CREATE TABLE t1 (D INT) ENGINE=innodb;
1271+
INSERT INTO t1 VALUES (10);
1272+
ALTER TABLE t1 MODIFY COLUMN d INT;
1273+
ALTER TABLE t1 ADD INDEX (d);
1274+
DROP TABLE t1;
1275+
1276+
CREATE TABLE t1 (`�` int) ENGINE=innodb;
1277+
INSERT INTO t1 VALUES (10);
1278+
ALTER TABLE t1 CHANGE `�` `�` INT;
1279+
ALTER TABLE t1 ADD INDEX (`�`);
1280+
SELECT * FROM t1;
1281+
DROP TABLE t1;
1282+

sql/sql_table.cc

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5048,10 +5048,22 @@ mysql_compare_tables(TABLE *table,
50485048

50495049
/* Check if field was renamed */
50505050
field->flags&= ~FIELD_IS_RENAMED;
5051-
if (my_strcasecmp(system_charset_info,
5052-
field->field_name,
5053-
tmp_new_field->field_name))
5054-
field->flags|= FIELD_IS_RENAMED;
5051+
5052+
/*
5053+
InnoDB data dictionary is case sensitive so we should use string case
5054+
sensitive comparison between fields. Note: strcmp branch is to be
5055+
removed in future when we fix it in InnoDB.
5056+
*/
5057+
if ((table->s->db_type())->db_type == DB_TYPE_INNODB &&
5058+
strcmp(field->field_name,tmp_new_field->field_name))
5059+
field->flags|= FIELD_IS_RENAMED;
5060+
else
5061+
{
5062+
if (my_strcasecmp(system_charset_info,
5063+
field->field_name,
5064+
tmp_new_field->field_name))
5065+
field->flags|= FIELD_IS_RENAMED;
5066+
}
50555067

50565068
/* Evaluate changes bitmap and send to check_if_incompatible_data() */
50575069
if (!(tmp= field->is_equal(tmp_new_field)))

0 commit comments

Comments
 (0)