Skip to content

Commit b598f6e

Browse files
authored
ddl: check index key length when convert charset (pingcap#56964) (pingcap#57929)
close pingcap#56930
1 parent 232f278 commit b598f6e

File tree

3 files changed

+52
-0
lines changed

3 files changed

+52
-0
lines changed

pkg/ddl/ddl_api.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6558,6 +6558,10 @@ func checkAlterTableCharset(tblInfo *model.TableInfo, dbInfo *model.DBInfo, toCh
65586558
return doNothing, nil
65596559
}
65606560

6561+
if err = checkIndexLengthWithNewCharset(tblInfo, toCharset, toCollate); err != nil {
6562+
return doNothing, err
6563+
}
6564+
65616565
for _, col := range tblInfo.Columns {
65626566
if col.GetType() == mysql.TypeVarchar {
65636567
if err = types.IsVarcharTooBigFieldLength(col.GetFlen(), col.Name.O, toCharset); err != nil {
@@ -6581,6 +6585,30 @@ func checkAlterTableCharset(tblInfo *model.TableInfo, dbInfo *model.DBInfo, toCh
65816585
return doNothing, nil
65826586
}
65836587

6588+
func checkIndexLengthWithNewCharset(tblInfo *model.TableInfo, toCharset, toCollate string) error {
6589+
// Copy all columns and replace the charset and collate.
6590+
columns := make([]*model.ColumnInfo, 0, len(tblInfo.Columns))
6591+
for _, col := range tblInfo.Columns {
6592+
newCol := col.Clone()
6593+
if field_types.HasCharset(&newCol.FieldType) {
6594+
newCol.SetCharset(toCharset)
6595+
newCol.SetCollate(toCollate)
6596+
} else {
6597+
newCol.SetCharset(charset.CharsetBin)
6598+
newCol.SetCollate(charset.CharsetBin)
6599+
}
6600+
columns = append(columns, newCol)
6601+
}
6602+
6603+
for _, indexInfo := range tblInfo.Indices {
6604+
err := checkIndexPrefixLength(columns, indexInfo.Columns)
6605+
if err != nil {
6606+
return err
6607+
}
6608+
}
6609+
return nil
6610+
}
6611+
65846612
// RenameIndex renames an index.
65856613
// In TiDB, indexes are case-insensitive (so index 'a' and 'A" are considered the same index),
65866614
// but index names are case-sensitive (we can rename index 'a' to 'A')

tests/integrationtest/r/session/common.result

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,18 @@ create table t (a blob(10000), b timestamp, index idx(a(3069), b));
137137
Error 1071 (42000): Specified key was too long (3073 bytes); max key length is 3072 bytes
138138
create table t (a blob(10000), b timestamp, index idx(a(3068), b));
139139
drop table if exists t;
140+
create table posts (id int auto_increment primary key, title varchar(500) character set utf8, subtitle varchar(500) character set utf8, unique key(title, subtitle));
141+
alter table posts convert to character set utf8mb4;
142+
Error 1071 (42000): Specified key was too long (4000 bytes); max key length is 3072 bytes
143+
drop table if exists posts;
144+
create table t(a varchar(1000) character set utf8, primary key(a));
145+
alter table t convert to character set utf8mb4;
146+
Error 1071 (42000): Specified key was too long (4000 bytes); max key length is 3072 bytes
147+
drop table if exists t;
148+
create table t(a varchar(1000) character set utf8, key(a));
149+
alter table t convert to character set utf8mb4;
150+
Error 1071 (42000): Specified key was too long (4000 bytes); max key length is 3072 bytes
151+
drop table if exists t;
140152
drop table if exists t1;
141153
create table t1(id int );
142154
insert into t1 values (1);

tests/integrationtest/t/session/common.test

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,18 @@ drop table if exists t;
140140
create table t (a blob(10000), b timestamp, index idx(a(3069), b));
141141
create table t (a blob(10000), b timestamp, index idx(a(3068), b));
142142
drop table if exists t;
143+
create table posts (id int auto_increment primary key, title varchar(500) character set utf8, subtitle varchar(500) character set utf8, unique key(title, subtitle));
144+
-- error 1071
145+
alter table posts convert to character set utf8mb4;
146+
drop table if exists posts;
147+
create table t(a varchar(1000) character set utf8, primary key(a));
148+
-- error 1071
149+
alter table t convert to character set utf8mb4;
150+
drop table if exists t;
151+
create table t(a varchar(1000) character set utf8, key(a));
152+
-- error 1071
153+
alter table t convert to character set utf8mb4;
154+
drop table if exists t;
143155

144156
# TestMultiStmts
145157
drop table if exists t1; create table t1(id int ); insert into t1 values (1);

0 commit comments

Comments
 (0)