From a285332c5db699f9fef44104c81ff631d7c13a8a Mon Sep 17 00:00:00 2001 From: hanchuanchuan Date: Fri, 20 Mar 2020 20:46:48 +0800 Subject: [PATCH] =?UTF-8?q?update:=20=E4=BC=98=E5=8C=96=E5=88=97=E7=9A=84?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E9=9B=86=E5=92=8C=E6=8E=92=E5=BA=8F=E8=A7=84?= =?UTF-8?q?=E5=88=99=E5=AE=A1=E6=A0=B8=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- session/errors.go | 4 +- session/session_inception.go | 22 +++++++-- session/session_inception_test.go | 76 ++++++++++++++++++++++--------- 3 files changed, 75 insertions(+), 27 deletions(-) diff --git a/session/errors.go b/session/errors.go index 4b560bc6e..8284aad0e 100644 --- a/session/errors.go +++ b/session/errors.go @@ -307,7 +307,7 @@ var ErrorsDefault = map[ErrorCode]string{ ER_WRONG_ARGUMENTS: "Incorrect arguments to %s.", ER_SET_DATA_TYPE_INT_BIGINT: "Set auto-increment data type to int or bigint.", ER_TIMESTAMP_DEFAULT: "Set default value for timestamp column '%s'.", - ER_CHARSET_ON_COLUMN: "Not Allowed set charset for column '%s.%s'.", + ER_CHARSET_ON_COLUMN: "Not Allowed set charset or collation for column '%s.%s'.", ER_AUTO_INCR_ID_WARNING: "Auto increment column '%s' is meaningful? it's dangerous!", ER_ALTER_TABLE_ONCE: "Merge the alter statement for table '%s' to ONE.", ER_BLOB_CANT_HAVE_DEFAULT: "BLOB, TEXT, GEOMETRY or JSON column '%s' can't have a default value.", @@ -477,7 +477,7 @@ var ErrorsChinese = map[ErrorCode]string{ ER_WRONG_ARGUMENTS: "Incorrect arguments to %s.", ER_SET_DATA_TYPE_INT_BIGINT: "自增列需要设置为int或bigint类型.", ER_TIMESTAMP_DEFAULT: "请设置timestamp列 '%s' 的默认值.", - ER_CHARSET_ON_COLUMN: "表 '%s' 列 '%s' 禁止设置字符集!", + ER_CHARSET_ON_COLUMN: "表 '%s' 列 '%s' 禁止设置字符集或排序规则!", ER_AUTO_INCR_ID_WARNING: "自增列('%s')建议命名为'ID'.", ER_ALTER_TABLE_ONCE: "表 '%s' 的多个alter操作请合并成一个.", ER_BLOB_CANT_HAVE_DEFAULT: "BLOB,TEXT,GEOMETRY或JSON列 '%s' 禁止设置默认值.", diff --git a/session/session_inception.go b/session/session_inception.go index 9afa51c90..4324fdae8 100644 --- a/session/session_inception.go +++ b/session/session_inception.go @@ -3895,6 +3895,7 @@ func (s *session) checkAlterTable(node *ast.AlterTableStmt, sql string) { } for i, alter := range node.Specs { + switch alter.Tp { case ast.AlterTableOption: if len(alter.Options) == 0 { @@ -4578,7 +4579,11 @@ func (s *session) mysqlCheckField(t *TableInfo, field *ast.ColumnDef) { case ast.ColumnOptionGenerated: hasGenerated = true case ast.ColumnOptionCollate: - s.AppendErrorNo(ER_CHARSET_ON_COLUMN, tableName, field.Name.Name) + if s.Inc.EnableColumnCharset { + s.checkCollation(op.StrValue) + } else { + s.AppendErrorNo(ER_CHARSET_ON_COLUMN, tableName, field.Name.Name) + } } } } @@ -4641,9 +4646,20 @@ func (s *session) mysqlCheckField(t *TableInfo, field *ast.ColumnDef) { if !notNullFlag && !hasGenerated { s.AppendErrorNo(ER_NOT_ALLOWED_NULLABLE, field.Name.Name, tableName) } + } - if field.Tp.Charset != "" || field.Tp.Collate != "" { - if field.Tp.Charset != "binary" { + // 审核所有指定了charset或collate的字段 + if field.Tp.Charset != "" || field.Tp.Collate != "" { + if field.Tp.Charset != "" && field.Tp.Charset != "binary" { + if s.Inc.EnableColumnCharset { + s.checkCharset(field.Tp.Charset) + } else { + s.AppendErrorNo(ER_CHARSET_ON_COLUMN, tableName, field.Name.Name) + } + } else if field.Tp.Collate != "" && field.Tp.Collate != "binary" { + if s.Inc.EnableColumnCharset { + s.checkCollation(field.Tp.Collate) + } else { s.AppendErrorNo(ER_CHARSET_ON_COLUMN, tableName, field.Name.Name) } } diff --git a/session/session_inception_test.go b/session/session_inception_test.go index cf63fc8f2..d31ac0985 100644 --- a/session/session_inception_test.go +++ b/session/session_inception_test.go @@ -125,7 +125,10 @@ func (s *testSessionIncSuite) testSQLError(c *C, sql string, errors ...*session. allErrors := []string{} for _, row := range res.Rows()[1:] { if v, ok := row[4].(string); ok { - allErrors = append(allErrors, strings.TrimSpace(v)) + v = strings.TrimSpace(v) + if v != "" { + allErrors = append(allErrors, v) + } } } @@ -134,7 +137,7 @@ func (s *testSessionIncSuite) testSQLError(c *C, sql string, errors ...*session. errMsgs = append(errMsgs, e.Error()) } - c.Assert(len(errMsgs), Equals, len(allErrors), Commentf("%v", res.Rows())) + c.Assert(len(errMsgs), Equals, len(allErrors), Commentf("%v", allErrors)) for index, err := range allErrors { c.Assert(err, Equals, errMsgs[index], Commentf("%v", res.Rows())) @@ -927,16 +930,12 @@ func (s *testSessionIncSuite) TestAlterTableAddColumn(c *C) { session.NewErr(session.ER_CHAR_TO_VARCHAR_LEN, "c1")) // 字符集 - res = s.runCheck(`drop table if exists t1;create table t1(id int); - alter table t1 add column c1 varchar(20) character set utf8; - alter table t1 add column c2 varchar(20) COLLATE utf8_bin;`) - row = res.Rows()[int(s.tk.Se.AffectedRows())-2] - c.Assert(row[2], Equals, "1") - c.Assert(row[4], Equals, "Not Allowed set charset for column 't1.c1'.") - - row = res.Rows()[int(s.tk.Se.AffectedRows())-1] - c.Assert(row[2], Equals, "1") - c.Assert(row[4], Equals, "Not Allowed set charset for column 't1.c2'.") + sql = `drop table if exists t1;create table t1(id int); + alter table t1 add column c1 varchar(20) character set utf8; + alter table t1 add column c2 varchar(20) COLLATE utf8_bin;` + s.testSQLError(c, sql, + session.NewErr(session.ER_CHARSET_ON_COLUMN, "t1", "c1"), + session.NewErr(session.ER_CHARSET_ON_COLUMN, "t1", "c2")) // 关键字 config.GetGlobalConfig().Inc.EnableIdentiferKeyword = false @@ -1128,21 +1127,17 @@ func (s *testSessionIncSuite) TestAlterTableModifyColumn(c *C) { session.NewErr(session.ER_CHAR_TO_VARCHAR_LEN, "c1")) // 字符集 - res = s.runCheck(`create table t1(id int,c1 varchar(20)); + sql = `create table t1(id int,c1 varchar(20)); alter table t1 modify column c1 varchar(20) character set utf8; - alter table t1 modify column c1 varchar(20) COLLATE utf8_bin;`) - row := res.Rows()[int(s.tk.Se.AffectedRows())-2] - c.Assert(row[2], Equals, "1") - c.Assert(row[4], Equals, "Not Allowed set charset for column 't1.c1'.") - - row = res.Rows()[int(s.tk.Se.AffectedRows())-1] - c.Assert(row[2], Equals, "1") - c.Assert(row[4], Equals, "Not Allowed set charset for column 't1.c1'.") + alter table t1 modify column c1 varchar(20) COLLATE utf8_bin;` + s.testSQLError(c, sql, + session.NewErr(session.ER_CHARSET_ON_COLUMN, "t1", "c1"), + session.NewErr(session.ER_CHARSET_ON_COLUMN, "t1", "c1")) // 列注释 config.GetGlobalConfig().Inc.CheckColumnComment = true res = s.runCheck("create table t1(id int,c1 varchar(10));alter table t1 modify column c1 varchar(20);") - row = res.Rows()[int(s.tk.Se.AffectedRows())-1] + row := res.Rows()[int(s.tk.Se.AffectedRows())-1] c.Assert(row[2], Equals, "1") c.Assert(row[4], Equals, "Column 'c1' in table 't1' have no comments.") @@ -2291,6 +2286,43 @@ func (s *testSessionIncSuite) TestAlterTable(c *C) { alter table t1 drop column c4; ` s.testErrorCode(c, sql) + // 列字符集&排序规则 + config.GetGlobalConfig().Inc.EnableColumnCharset = false + sql = `drop table if exists t1; + create table t1(id int primary key); + alter table t1 add column c4 varchar(22) charset utf8;` + s.testErrorCode(c, sql, + session.NewErr(session.ER_CHARSET_ON_COLUMN, "t1", "c4")) + + sql = `drop table if exists t1; + create table t1(id int primary key); + alter table t1 add column c4 varchar(22) collate utf8_bin;` + s.testErrorCode(c, sql, + session.NewErr(session.ER_CHARSET_ON_COLUMN, "t1", "c4")) + + sql = `drop table if exists t1; + create table t1(id int primary key); + alter table t1 add column c4 varchar(22) charset utf8 collate utf8_bin;` + s.testErrorCode(c, sql, + session.NewErr(session.ER_CHARSET_ON_COLUMN, "t1", "c4"), + session.NewErr(session.ER_CHARSET_ON_COLUMN, "t1", "c4")) + + config.GetGlobalConfig().Inc.EnableColumnCharset = true + config.GetGlobalConfig().Inc.SupportCharset = "utf8mb4" + sql = `drop table if exists t1; + create table t1(id int primary key); + alter table t1 add column c4 varchar(22) charset utf8 collate utf8_bin;` + s.testErrorCode(c, sql, + session.NewErr(session.ErrCharsetNotSupport, "utf8mb4")) + + config.GetGlobalConfig().Inc.SupportCharset = "utf8" + config.GetGlobalConfig().Inc.SupportCollation = "utf8_bin" + sql = `drop table if exists t1; + create table t1(id int primary key); + alter table t1 add column c4 varchar(22) charset utf8 collate utf8mb4_bin;` + s.testErrorCode(c, sql, + session.NewErr(session.ErrCollationNotSupport, "utf8_bin")) + } func (s *testSessionIncSuite) TestCreateTablePrimaryKey(c *C) {