Skip to content

Commit

Permalink
ddl: support altering the other charset to utf8 or utf8mb4 (pingcap#8037
Browse files Browse the repository at this point in the history
)
  • Loading branch information
winkyao authored and iamzhoug37 committed Dec 13, 2018
1 parent d71ff3a commit d1749b6
Show file tree
Hide file tree
Showing 10 changed files with 311 additions and 14 deletions.
2 changes: 1 addition & 1 deletion ddl/column_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -915,7 +915,7 @@ func (s *testColumnSuite) TestModifyColumn(c *C) {
{"int", "int unsigned", errUnsupportedModifyColumn.GenWithStackByArgs("length 10 is less than origin 11")},
{"varchar(10)", "text", nil},
{"varbinary(10)", "blob", nil},
{"text", "blob", errUnsupportedModifyColumn.GenWithStackByArgs("charset binary not match origin utf8mb4")},
{"text", "blob", errUnsupportedModifyCharset.GenWithStackByArgs("charset from utf8mb4 to binary")},
{"varchar(10)", "varchar(8)", errUnsupportedModifyColumn.GenWithStackByArgs("length 8 is less than origin 10")},
{"varchar(10)", "varchar(11)", nil},
{"varchar(10) character set utf8 collate utf8_bin", "varchar(10) character set utf8", nil},
Expand Down
2 changes: 1 addition & 1 deletion ddl/db_change_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ func (s *testStateChangeSuite) TestAppendEnum(c *C) {
c.Assert(err.Error(), Equals, "[ddl:203]unsupported modify column the number of enum column's elements is less than the original: 2")
failAlterTableSQL2 := "alter table t change c2 c2 int default 0"
_, err = s.se.Execute(context.Background(), failAlterTableSQL2)
c.Assert(err.Error(), Equals, "[ddl:203]unsupported modify column charset binary not match origin utf8mb4")
c.Assert(err.Error(), Equals, "[ddl:210]unsupported modify charset from utf8mb4 to binary")
alterTableSQL := "alter table t change c2 c2 enum('N','Y','A') DEFAULT 'A'"
_, err = s.se.Execute(context.Background(), alterTableSQL)
c.Assert(err, IsNil)
Expand Down
50 changes: 50 additions & 0 deletions ddl/db_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,56 @@ func (s *testIntegrationSuite) TestEndIncluded(c *C) {
tk.MustExec("admin check table t")
}

func (s *testIntegrationSuite) TestChangingCharsetToUtf8(c *C) {
tk := testkit.NewTestKit(c, s.store)

tk.MustExec("USE test")
tk.MustExec("create table t(a char(10) charset latin1)")
tk.MustExec("alter table t modify column a char(10) charset latin1")
tk.MustExec("alter table t modify column a char(10) charset utf8")
tk.MustExec("alter table t modify column a char(10) charset utf8mb4")
rs, err := tk.Exec("alter table t modify column a char(10) charset utf8mb4 collate utf8bin")
if rs != nil {
rs.Close()
}
c.Assert(err, NotNil)
tk.MustExec("alter table t modify column a char(10) charset utf8mb4 collate utf8mb4_bin")
rs, err = tk.Exec("alter table t modify column a char(10) charset utf8 collate utf8_bin")
if rs != nil {
rs.Close()
}

c.Assert(err, NotNil)
tk.MustExec("alter table t modify column a char(10) charset utf8mb4 collate utf8mb4_general_ci")
}

func (s *testIntegrationSuite) TestChangingTableCharset(c *C) {
tk := testkit.NewTestKit(c, s.store)

tk.MustExec("USE test")
tk.MustExec("create table t(a char(10)) charset latin1 collate latin1_bin")
rs, err := tk.Exec("alter table t charset gbk")
if rs != nil {
rs.Close()
}
c.Assert(err.Error(), Equals, "Unknown charset gbk")
tk.MustExec("alter table t charset utf8")
tk.MustExec("alter table t charset utf8 collate utf8_bin")
rs, err = tk.Exec("alter table t charset utf8 collate latin1_bin")
if rs != nil {
rs.Close()
}
c.Assert(err, NotNil)
tk.MustExec("alter table t charset utf8mb4")
tk.MustExec("alter table t charset utf8mb4 collate utf8mb4_bin")

rs, err = tk.Exec("alter table t charset utf8 collate utf8_bin")
if rs != nil {
rs.Close()
}
c.Assert(err, NotNil)
}

func (s *testIntegrationSuite) TestCaseInsensitiveCharsetAndCollate(c *C) {
tk := testkit.NewTestKit(c, s.store)

Expand Down
93 changes: 93 additions & 0 deletions ddl/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
. "github.com/pingcap/check"
"github.com/pingcap/errors"
"github.com/pingcap/parser/ast"
"github.com/pingcap/parser/charset"
"github.com/pingcap/parser/model"
"github.com/pingcap/parser/mysql"
tmysql "github.com/pingcap/parser/mysql"
Expand Down Expand Up @@ -3831,6 +3832,98 @@ func testPartitionAddIndex(tk *testkit.TestKit, c *C) {
tk.MustExec("drop table partition_add_idx")
}

func (s *testDBSuite) TestAlterTableCharset(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("create database test_charset")
defer tk.MustExec("drop database test_charset")
tk.MustExec("use test_charset")
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a int) charset latin1")
ctx := tk.Se.(sessionctx.Context)
is := domain.GetDomain(ctx).InfoSchema()
t, err := is.TableByName(model.NewCIStr("test_charset"), model.NewCIStr("t"))
c.Assert(err, IsNil)
c.Assert(t.Meta().Charset, Equals, "latin1")
defCollate, err := charset.GetDefaultCollation("latin1")
c.Assert(err, IsNil)
c.Assert(t.Meta().Collate, Equals, defCollate)

tk.MustExec("alter table t charset utf8")
is = domain.GetDomain(ctx).InfoSchema()
t, err = is.TableByName(model.NewCIStr("test_charset"), model.NewCIStr("t"))
c.Assert(t.Meta().Charset, Equals, "utf8")
defCollate, err = charset.GetDefaultCollation("utf8")
c.Assert(err, IsNil)
c.Assert(t.Meta().Collate, Equals, defCollate)

tk.MustExec("alter table t charset utf8mb4 collate utf8mb4_general_ci")
is = domain.GetDomain(ctx).InfoSchema()
t, err = is.TableByName(model.NewCIStr("test_charset"), model.NewCIStr("t"))
c.Assert(t.Meta().Charset, Equals, "utf8mb4")
c.Assert(t.Meta().Collate, Equals, "utf8mb4_general_ci")

rs, err := tk.Exec("alter table t charset utf8")
if rs != nil {
rs.Close()
}

c.Assert(err.Error(), Equals, "[ddl:210]unsupported modify charset from utf8mb4 to utf8")
}

func (s *testDBSuite) TestAlterColumnCharset(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("create database test_charset")
defer tk.MustExec("drop database test_charset")
tk.MustExec("use test_charset")
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a char(10) charset latin1)")
ctx := tk.Se.(sessionctx.Context)
is := domain.GetDomain(ctx).InfoSchema()
t, err := is.TableByName(model.NewCIStr("test_charset"), model.NewCIStr("t"))
c.Assert(err, IsNil)
col := model.FindColumnInfo(t.Meta().Columns, "a")
c.Assert(col, NotNil)
c.Assert(col.Charset, Equals, "latin1")
defCollate, err := charset.GetDefaultCollation("latin1")
c.Assert(err, IsNil)
c.Assert(col.Collate, Equals, defCollate)

tk.MustExec("alter table t modify column a char(10) charset utf8")
is = domain.GetDomain(ctx).InfoSchema()
t, err = is.TableByName(model.NewCIStr("test_charset"), model.NewCIStr("t"))
c.Assert(err, IsNil)
col = model.FindColumnInfo(t.Meta().Columns, "a")
c.Assert(col, NotNil)
c.Assert(col.Charset, Equals, "utf8")
defCollate, err = charset.GetDefaultCollation("utf8")
c.Assert(err, IsNil)
c.Assert(col.Collate, Equals, defCollate)

tk.MustExec("alter table t modify column a char(10) charset utf8 collate utf8_general_ci")
is = domain.GetDomain(ctx).InfoSchema()
t, err = is.TableByName(model.NewCIStr("test_charset"), model.NewCIStr("t"))
c.Assert(err, IsNil)
col = model.FindColumnInfo(t.Meta().Columns, "a")
c.Assert(col, NotNil)
c.Assert(col.Charset, Equals, "utf8")
c.Assert(col.Collate, Equals, "utf8_general_ci")

tk.MustExec("alter table t modify column a char(10) charset utf8mb4 collate utf8mb4_general_ci")
is = domain.GetDomain(ctx).InfoSchema()
t, err = is.TableByName(model.NewCIStr("test_charset"), model.NewCIStr("t"))
c.Assert(err, IsNil)
col = model.FindColumnInfo(t.Meta().Columns, "a")
c.Assert(col, NotNil)
c.Assert(col.Charset, Equals, "utf8mb4")
c.Assert(col.Collate, Equals, "utf8mb4_general_ci")

rs, err := tk.Exec("alter table t modify column a char(10) charset utf8")
if rs != nil {
rs.Close()
}
c.Assert(err.Error(), Equals, "[ddl:210]unsupported modify charset from utf8mb4 to utf8")
}

func (s *testDBSuite) TestDropSchemaWithPartitionTable(c *C) {
s.tk = testkit.NewTestKit(c, s.store)
s.tk.MustExec("drop database if exists test_db_with_partition")
Expand Down
10 changes: 6 additions & 4 deletions ddl/ddl.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,11 @@ var (
errInvalidStoreVer = terror.ClassDDL.New(codeInvalidStoreVer, "invalid storage current version")

// We don't support dropping column with index covered now.
errCantDropColWithIndex = terror.ClassDDL.New(codeCantDropColWithIndex, "can't drop column with index")
errUnsupportedAddColumn = terror.ClassDDL.New(codeUnsupportedAddColumn, "unsupported add column")
errUnsupportedModifyColumn = terror.ClassDDL.New(codeUnsupportedModifyColumn, "unsupported modify column %s")
errUnsupportedPKHandle = terror.ClassDDL.New(codeUnsupportedDropPKHandle,
errCantDropColWithIndex = terror.ClassDDL.New(codeCantDropColWithIndex, "can't drop column with index")
errUnsupportedAddColumn = terror.ClassDDL.New(codeUnsupportedAddColumn, "unsupported add column")
errUnsupportedModifyColumn = terror.ClassDDL.New(codeUnsupportedModifyColumn, "unsupported modify column %s")
errUnsupportedModifyCharset = terror.ClassDDL.New(codeUnsupportedModifyCharset, "unsupported modify %s")
errUnsupportedPKHandle = terror.ClassDDL.New(codeUnsupportedDropPKHandle,
"unsupported drop integer primary key")
errUnsupportedCharset = terror.ClassDDL.New(codeUnsupportedCharset, "unsupported charset %s collate %s")

Expand Down Expand Up @@ -587,6 +588,7 @@ const (
codeUnsupportedShardRowIDBits = 207
codeUnsupportedAddPartition = 208
codeUnsupportedCoalescePartition = 209
codeUnsupportedModifyCharset = 210

codeFileNotFound = 1017
codeErrorOnRename = 1025
Expand Down
Loading

0 comments on commit d1749b6

Please sign in to comment.