Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ddl: allow more charset/collation modifications for database/table (#10958) #11085

Merged
merged 4 commits into from
Jul 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 19 additions & 12 deletions ddl/db_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,17 +319,17 @@ func (s *testIntegrationSuite) TestChangingTableCharset(c *C) {
tk.MustExec("drop table t;")
tk.MustExec("create table t(a varchar(10)) charset utf8")
tk.MustExec("alter table t convert to charset utf8mb4;")
checkCharset := func() {
checkCharset := func(chs, coll string) {
tbl := testGetTableByName(c, tk.Se, "test", "t")
c.Assert(tbl, NotNil)
c.Assert(tbl.Meta().Charset, Equals, charset.CharsetUTF8MB4)
c.Assert(tbl.Meta().Collate, Equals, charset.CollationUTF8MB4)
c.Assert(tbl.Meta().Charset, Equals, chs)
c.Assert(tbl.Meta().Collate, Equals, coll)
for _, col := range tbl.Meta().Columns {
c.Assert(col.Charset, Equals, charset.CharsetUTF8MB4)
c.Assert(col.Collate, Equals, charset.CollationUTF8MB4)
c.Assert(col.Charset, Equals, chs)
c.Assert(col.Collate, Equals, coll)
}
}
checkCharset()
checkCharset(charset.CharsetUTF8MB4, charset.CollationUTF8MB4)

// Test when column charset can not convert to the target charset.
tk.MustExec("drop table t;")
Expand All @@ -338,11 +338,16 @@ func (s *testIntegrationSuite) TestChangingTableCharset(c *C) {
c.Assert(err, NotNil)
c.Assert(err.Error(), Equals, "[ddl:210]unsupported modify charset from ascii to utf8mb4")

tk.MustExec("drop table t;")
tk.MustExec("create table t(a varchar(10) character set utf8) charset utf8")
tk.MustExec("alter table t convert to charset utf8 collate utf8_general_ci;")
checkCharset(charset.CharsetUTF8, "utf8_general_ci")

// Test when table charset is equal to target charset but column charset is not equal.
tk.MustExec("drop table t;")
tk.MustExec("create table t(a varchar(10) character set utf8) charset utf8mb4")
tk.MustExec("alter table t convert to charset utf8mb4;")
checkCharset()
tk.MustExec("alter table t convert to charset utf8mb4 collate utf8mb4_general_ci;")
checkCharset(charset.CharsetUTF8MB4, "utf8mb4_general_ci")

// Mock table info with charset is "". Old TiDB maybe create table with charset is "".
db, ok := domain.GetDomain(tk.Se).InfoSchema().SchemaByName(model.NewCIStr("test"))
Expand Down Expand Up @@ -375,7 +380,7 @@ func (s *testIntegrationSuite) TestChangingTableCharset(c *C) {
c.Assert(tbl.Meta().Collate, Equals, "")
// Test when table charset is "", this for compatibility.
tk.MustExec("alter table t convert to charset utf8mb4;")
checkCharset()
checkCharset(charset.CharsetUTF8MB4, charset.CollationUTF8MB4)

// Test when column charset is "".
tbl = testGetTableByName(c, tk.Se, "test", "t")
Expand All @@ -390,7 +395,7 @@ func (s *testIntegrationSuite) TestChangingTableCharset(c *C) {
c.Assert(tbl.Meta().Columns[0].Charset, Equals, "")
c.Assert(tbl.Meta().Columns[0].Collate, Equals, "")
tk.MustExec("alter table t convert to charset utf8mb4;")
checkCharset()
checkCharset(charset.CharsetUTF8MB4, charset.CollationUTF8MB4)

tk.MustExec("drop table t")
tk.MustExec("create table t (a blob) character set utf8;")
Expand Down Expand Up @@ -743,10 +748,12 @@ func (s *testIntegrationSuite) TestChangingDBCharset(c *C) {
_, err := tk.Exec(fc.stmt)
c.Assert(err.Error(), Equals, fc.errMsg, Commentf("%v", fc.stmt))
}
tk.MustExec("ALTER SCHEMA CHARACTER SET = 'utf8' COLLATE = 'utf8_unicode_ci'")
verifyDBCharsetAndCollate("alterdb2", "utf8", "utf8_unicode_ci")

tk.MustExec("ALTER SCHEMA CHARACTER SET = 'utf8mb4'")
verifyDBCharsetAndCollate("alterdb2", "utf8mb4", "utf8mb4_bin")

_, err := tk.Exec("ALTER SCHEMA CHARACTER SET = 'utf8mb4' COLLATE = 'utf8mb4_general_ci'")
c.Assert(err.Error(), Equals, "[ddl:210]unsupported modify collate from utf8mb4_bin to utf8mb4_general_ci")
tk.MustExec("ALTER SCHEMA CHARACTER SET = 'utf8mb4' COLLATE = 'utf8mb4_general_ci'")
verifyDBCharsetAndCollate("alterdb2", "utf8mb4", "utf8mb4_general_ci")
}
6 changes: 4 additions & 2 deletions ddl/ddl_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -1759,8 +1759,10 @@ func modifiableCharsetAndCollation(toCharset, toCollate, origCharset, origCollat
if !charset.ValidCharsetAndCollation(toCharset, toCollate) {
return ErrUnknownCharacterSet.GenWithStack("Unknown character set: '%s', collation: '%s'", toCharset, toCollate)
}
if toCharset == charset.CharsetUTF8MB4 && origCharset == charset.CharsetUTF8 {
// TiDB only allow utf8 to be changed to utf8mb4.
if (origCharset == charset.CharsetUTF8 && toCharset == charset.CharsetUTF8MB4) ||
(origCharset == charset.CharsetUTF8 && toCharset == charset.CharsetUTF8) ||
(origCharset == charset.CharsetUTF8MB4 && toCharset == charset.CharsetUTF8MB4) {
// TiDB only allow utf8 to be changed to utf8mb4, or changing the collation when the charset is utf8/utf8mb4.
return nil
}

Expand Down