Skip to content

Commit

Permalink
Merge pull request #165 from hanchuanchuan/update-numeric-display-width
Browse files Browse the repository at this point in the history
update: 完善数值类型的显示宽度审核 (#162)
  • Loading branch information
hanchuanchuan committed Mar 6, 2020
2 parents bc41cdd + eb769b6 commit 59e822c
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 24 deletions.
4 changes: 1 addition & 3 deletions parser/parser.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions parser/parser.y
Expand Up @@ -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
}
Expand Down
8 changes: 5 additions & 3 deletions session/session_inception.go
Expand Up @@ -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)
Expand Down Expand Up @@ -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) &&
Expand Down
23 changes: 23 additions & 0 deletions session/session_inception_exec_test.go
Expand Up @@ -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)

}
33 changes: 33 additions & 0 deletions session/session_inception_test.go
Expand Up @@ -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"))

}
38 changes: 23 additions & 15 deletions session/tidb_check.go
Expand Up @@ -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 {
Expand All @@ -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.
Expand All @@ -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
Expand All @@ -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 {
Expand All @@ -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.
Expand Down

0 comments on commit 59e822c

Please sign in to comment.