diff --git a/parser/parser.go b/parser/parser.go index ca34ddf4a..722a1aeee 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -11729,10 +11729,8 @@ yynewstate: { x := types.NewFieldType(yyS[yypt-1].item.(byte)) x.Flen = yyS[yypt-0].item.(int) - if x.Flen == types.UnspecifiedLength || x.Flen == 0 { + if x.Flen == types.UnspecifiedLength { x.Flen = 1 - } else if x.Flen > 64 { - yylex.AppendError(ErrTooBigDisplayWidth.GenWithStackByArgs(x.Flen)) } parser.yyVAL.item = x } diff --git a/parser/parser.y b/parser/parser.y index b85debce0..26107f97e 100644 --- a/parser/parser.y +++ b/parser/parser.y @@ -6779,10 +6779,8 @@ NumericType: { x := types.NewFieldType($1.(byte)) x.Flen = $2.(int) - if x.Flen == types.UnspecifiedLength || x.Flen == 0 { + if x.Flen == types.UnspecifiedLength { x.Flen = 1 - } else if x.Flen > 64 { - yylex.AppendError(ErrTooBigDisplayWidth.GenWithStackByArgs(x.Flen)) } $$ = x } diff --git a/session/session_inception.go b/session/session_inception.go index 9bf6a3773..e98d6e416 100644 --- a/session/session_inception.go +++ b/session/session_inception.go @@ -4655,9 +4655,10 @@ func (s *session) mysqlCheckField(t *TableInfo, field *ast.ColumnDef) { } } - if isIncorrectName(field.Name.Name.O) { - s.AppendErrorNo(ER_WRONG_COLUMN_NAME, field.Name.Name) - } + // if isIncorrectName(field.Name.Name.O) { + // s.AppendErrorNo(ER_WRONG_COLUMN_NAME, field.Name.Name) + // } + //text/blob/json 字段禁止设置NOT NULL if (types.IsTypeBlob(field.Tp.Tp) || field.Tp.Tp == mysql.TypeJSON) && notNullFlag { s.AppendErrorNo(ER_TEXT_NOT_NULLABLE_ERROR, field.Name.Name, tableName) @@ -4687,6 +4688,7 @@ func (s *session) mysqlCheckField(t *TableInfo, field *ast.ColumnDef) { s.AppendErrorNo(ER_WITH_DEFAULT_ADD_COLUMN, field.Name.Name.O, tableName) } + s.checkColumn(field) // if (thd->variables.sql_mode & MODE_NO_ZERO_DATE && // is_timestamp_type(field->sql_type) && !field->def && // (field->flags & NOT_NULL_FLAG) && diff --git a/session/session_inception_exec_test.go b/session/session_inception_exec_test.go index 0903b6013..9b05d8ea4 100644 --- a/session/session_inception_exec_test.go +++ b/session/session_inception_exec_test.go @@ -1329,3 +1329,26 @@ func (s *testSessionIncExecSuite) TestAlterTableGhost(c *C) { sql = "alter table t1 add column `c5` varchar(20) comment \"!@#$%^&*()_+[]{}\\|;:',.<>/?\"; -- 测试注释" s.testErrorCode(c, sql) } + +// TestDisplayWidth 测试列指定长度参数 +func (s *testSessionIncExecSuite) TestDisplayWidth(c *C) { + sql := "" + config.GetGlobalConfig().Inc.CheckColumnComment = false + config.GetGlobalConfig().Inc.CheckTableComment = false + config.GetGlobalConfig().Inc.EnableEnumSetBit = true + + s.mustRunExec(c, "drop table if exists t1;") + // 数据类型 警告 + sql = `create table t1(c1 bit(64), + c2 tinyint(255), + c3 smallint(255), + c4 mediumint(255), + c5 int(255), + c6 bigint(255) );` + s.testErrorCode(c, sql) + + // 数据类型 警告 + sql = `alter table t1 add column c11 tinyint(255);` + s.testErrorCode(c, sql) + +} diff --git a/session/session_inception_test.go b/session/session_inception_test.go index b6ca8fc63..848cb2c0c 100644 --- a/session/session_inception_test.go +++ b/session/session_inception_test.go @@ -2683,3 +2683,36 @@ func (s *testSessionIncSuite) TestGetAlterTablePostPart(c *C) { c.Assert(out, Equals, row.outGhost, Commentf("%v", row.sql)) } } + +// TestDisplayWidth 测试列指定长度参数 +func (s *testSessionIncSuite) TestDisplayWidth(c *C) { + sql := "" + config.GetGlobalConfig().Inc.CheckColumnComment = false + config.GetGlobalConfig().Inc.CheckTableComment = false + config.GetGlobalConfig().Inc.EnableEnumSetBit = true + + s.mustRunExec(c, "drop table if exists t1;") + // 数据类型 警告 + sql = `create table t1(c1 bit(100), + c2 tinyint(1000), + c3 smallint(1000), + c4 mediumint(1000), + c5 int(1000), + c6 bigint(1000) );` + s.testErrorCode(c, sql, + session.NewErrf("Too big display width for column '%s' (max = 64).", "c1"), + session.NewErrf("Too big display width for column '%s' (max = 255).", "c2"), + session.NewErrf("Too big display width for column '%s' (max = 255).", "c3"), + session.NewErrf("Too big display width for column '%s' (max = 255).", "c4"), + session.NewErrf("Too big display width for column '%s' (max = 255).", "c5"), + session.NewErrf("Too big display width for column '%s' (max = 255).", "c6"), + ) + + // 数据类型 警告 + sql = `create table t1(id int); + alter table t1 add column c1 tinyint(1000); + ` + s.testErrorCode(c, sql, + session.NewErrf("Too big display width for column '%s' (max = 255).", "c1")) + +} diff --git a/session/tidb_check.go b/session/tidb_check.go index a7add377f..35bb64e3c 100644 --- a/session/tidb_check.go +++ b/session/tidb_check.go @@ -275,9 +275,10 @@ func (s *session) checkCreateTableGrammar(stmt *ast.CreateTableStmt) { } countPrimaryKey := 0 for _, colDef := range stmt.Cols { - if err := s.checkColumn(colDef); err != nil { - s.AppendErrorMessage(err.Error()) - } + // 放在mysqlCheckField函数统一检查(create/alter) + // if err := s.checkColumn(colDef); err != nil { + // s.AppendErrorMessage(err.Error()) + // } countPrimaryKey += isPrimary(colDef.Options) } for _, constraint := range stmt.Constraints { @@ -303,11 +304,11 @@ func (s *session) checkColumn(colDef *ast.ColumnDef) error { // Check column name. cName := colDef.Name.Name.String() if isIncorrectName(cName) { - s.AppendErrorNo(ER_WRONG_COLUMN_NAME, colDef.Name.Name.O) + s.AppendErrorNo(ER_WRONG_COLUMN_NAME, cName) } // if isInvalidDefaultValue(colDef) { - // s.AppendErrorNo(ER_INVALID_DEFAULT, colDef.Name.Name.O) + // s.AppendErrorNo(ER_INVALID_DEFAULT, cName) // } // Check column type. @@ -316,13 +317,13 @@ func (s *session) checkColumn(colDef *ast.ColumnDef) error { return nil } if tp.Flen > math.MaxUint32 { - s.AppendErrorMessage(fmt.Sprintf("Display width out of range for column '%s' (max = %d)", colDef.Name.Name.O, math.MaxUint32)) + s.AppendErrorMessage(fmt.Sprintf("Display width out of range for column '%s' (max = %d)", cName, math.MaxUint32)) } switch tp.Tp { case mysql.TypeString: if tp.Flen != types.UnspecifiedLength && tp.Flen > mysql.MaxFieldCharLength { - s.AppendErrorMessage(fmt.Sprintf("Column length too big for column '%s' (max = %d); use BLOB or TEXT instead", colDef.Name.Name.O, mysql.MaxFieldCharLength)) + s.AppendErrorMessage(fmt.Sprintf("Column length too big for column '%s' (max = %d); use BLOB or TEXT instead", cName, mysql.MaxFieldCharLength)) } case mysql.TypeVarchar: maxFlen := mysql.MaxFieldVarCharLength @@ -339,19 +340,19 @@ func (s *session) checkColumn(colDef *ast.ColumnDef) error { } maxFlen /= desc.Maxlen if tp.Flen != types.UnspecifiedLength && tp.Flen > maxFlen { - s.AppendErrorMessage(fmt.Sprintf("Column length too big for column '%s' (max = %d); use BLOB or TEXT instead", colDef.Name.Name.O, maxFlen)) + s.AppendErrorMessage(fmt.Sprintf("Column length too big for column '%s' (max = %d); use BLOB or TEXT instead", cName, maxFlen)) } case mysql.TypeFloat, mysql.TypeDouble: if tp.Decimal > mysql.MaxFloatingTypeScale { - s.AppendErrorMessage(fmt.Sprintf("Too big scale %d specified for column '%-.192s'. Maximum is %d.", tp.Decimal, colDef.Name.Name.O, mysql.MaxFloatingTypeScale)) + s.AppendErrorMessage(fmt.Sprintf("Too big scale %d specified for column '%-.192s'. Maximum is %d.", tp.Decimal, cName, mysql.MaxFloatingTypeScale)) } if tp.Flen > mysql.MaxFloatingTypeWidth { - s.AppendErrorMessage(fmt.Sprintf("Too big precision %d specified for column '%-.192s'. Maximum is %d.", tp.Flen, colDef.Name.Name.O, mysql.MaxFloatingTypeWidth)) + s.AppendErrorMessage(fmt.Sprintf("Too big precision %d specified for column '%-.192s'. Maximum is %d.", tp.Flen, cName, mysql.MaxFloatingTypeWidth)) } case mysql.TypeSet: if len(tp.Elems) > mysql.MaxTypeSetMembers { - s.AppendErrorMessage(fmt.Sprintf("Too many strings for column %s and SET", colDef.Name.Name.O)) + s.AppendErrorMessage(fmt.Sprintf("Too many strings for column %s and SET", cName)) } // Check set elements. See https://dev.mysql.com/doc/refman/5.7/en/set.html . for _, str := range colDef.Tp.Elems { @@ -361,18 +362,25 @@ func (s *session) checkColumn(colDef *ast.ColumnDef) error { } case mysql.TypeNewDecimal: if tp.Decimal > mysql.MaxDecimalScale { - s.AppendErrorMessage(fmt.Sprintf("Too big scale %d specified for column '%-.192s'. Maximum is %d.", tp.Decimal, colDef.Name.Name.O, mysql.MaxDecimalScale)) + s.AppendErrorMessage(fmt.Sprintf("Too big scale %d specified for column '%-.192s'. Maximum is %d.", tp.Decimal, cName, mysql.MaxDecimalScale)) } if tp.Flen > mysql.MaxDecimalWidth { - s.AppendErrorMessage(fmt.Sprintf("Too big precision %d specified for column '%-.192s'. Maximum is %d.", tp.Flen, colDef.Name.Name.O, mysql.MaxDecimalWidth)) + s.AppendErrorMessage(fmt.Sprintf("Too big precision %d specified for column '%-.192s'. Maximum is %d.", tp.Flen, cName, mysql.MaxDecimalWidth)) } case mysql.TypeBit: if tp.Flen <= 0 { - s.AppendErrorMessage(fmt.Sprintf("Invalid size for column '%s'.", colDef.Name.Name.O)) + s.AppendErrorMessage(fmt.Sprintf("Invalid size for column '%s'.", cName)) } if tp.Flen > mysql.MaxBitDisplayWidth { - s.AppendErrorMessage(fmt.Sprintf("Too big display width for column '%s'.", colDef.Name.Name.O)) + s.AppendErrorMessage(fmt.Sprintf("Too big display width for column '%s' (max = %d).", + cName, mysql.MaxBitDisplayWidth)) + } + case mysql.TypeTiny, mysql.TypeInt24, mysql.TypeLong, + mysql.TypeShort, mysql.TypeLonglong: + if tp.Flen > mysql.MaxFloatingTypeWidth { + s.AppendErrorMessage(fmt.Sprintf("Too big display width for column '%-.192s' (max = %d).", + cName, mysql.MaxFloatingTypeWidth)) } default: // TODO: Add more types.