From 4a8d083515da4fc7d02f8788a0a396ed459fe940 Mon Sep 17 00:00:00 2001 From: bb7133 Date: Thu, 4 Jul 2019 17:04:17 +0800 Subject: [PATCH] ddl: allow more charset/collation modifications for database/table (#10958) --- ddl/db_integration_test.go | 31 +++++++++++++++++++------------ ddl/ddl_api.go | 6 ++++-- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/ddl/db_integration_test.go b/ddl/db_integration_test.go index 35297e8327731..f272116f30be0 100644 --- a/ddl/db_integration_test.go +++ b/ddl/db_integration_test.go @@ -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;") @@ -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")) @@ -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") @@ -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;") @@ -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") } diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index 8f7a4f04b8b24..9b4d3cde8b127 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -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 }