From db7e6c59ad31832ace1b70e4c716d5b83637c3ca Mon Sep 17 00:00:00 2001 From: HuaiyuXu <391585975@qq.com> Date: Tue, 20 Mar 2018 19:02:32 +0800 Subject: [PATCH] *: check float/double display width and scale (#6098) --- mysql/const.go | 8 ++------ parser/parser.y | 2 +- plan/preprocess.go | 11 +++++++---- plan/preprocess_test.go | 11 +++++++---- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/mysql/const.go b/mysql/const.go index 5f3b84f8be4c7..7a37e3e0c2871 100644 --- a/mysql/const.go +++ b/mysql/const.go @@ -227,6 +227,8 @@ const ( MaxIntWidth = 20 MaxRealWidth = 23 + MaxFloatingTypeScale = 30 + MaxFloatingTypeWidth = 255 MaxDecimalScale = 30 MaxDecimalWidth = 65 MaxDateWidth = 10 // YYYY-MM-DD. @@ -244,12 +246,6 @@ const ( MaxFieldVarCharLength = 65535 ) -// MySQL precision. -const ( - PrecisionForDouble = 53 - PrecisionForFloat = 24 -) - // MaxTypeSetMembers is the number of set members. const MaxTypeSetMembers = 64 diff --git a/parser/parser.y b/parser/parser.y index 6fbda5acd5e2b..a865fcb660013 100644 --- a/parser/parser.y +++ b/parser/parser.y @@ -5532,7 +5532,7 @@ NumericType: x := types.NewFieldType($1.(byte)) x.Flen = fopt.Flen if x.Tp == mysql.TypeFloat { - if x.Flen > mysql.PrecisionForFloat { + if x.Flen > 24 { x.Tp = mysql.TypeDouble } } diff --git a/plan/preprocess.go b/plan/preprocess.go index a6305beb4ad33..c3069e1cc1779 100644 --- a/plan/preprocess.go +++ b/plan/preprocess.go @@ -408,9 +408,12 @@ func checkColumn(colDef *ast.ColumnDef) error { if tp.Flen != types.UnspecifiedLength && tp.Flen > maxFlen { return types.ErrTooBigFieldLength.Gen("Column length too big for column '%s' (max = %d); use BLOB or TEXT instead", colDef.Name.Name.O, maxFlen) } - case mysql.TypeDouble: - if tp.Flen != types.UnspecifiedLength && tp.Flen > mysql.PrecisionForDouble { - return types.ErrWrongFieldSpec.Gen("Incorrect column specifier for column '%s'", colDef.Name.Name.O) + case mysql.TypeFloat, mysql.TypeDouble: + if tp.Decimal > mysql.MaxFloatingTypeScale { + return types.ErrTooBigScale.GenByArgs(tp.Decimal, colDef.Name.Name.O, mysql.MaxFloatingTypeScale) + } + if tp.Flen > mysql.MaxFloatingTypeWidth { + return types.ErrTooBigPrecision.GenByArgs(tp.Flen, colDef.Name.Name.O, mysql.MaxFloatingTypeWidth) } case mysql.TypeSet: if len(tp.Elems) > mysql.MaxTypeSetMembers { @@ -436,7 +439,7 @@ func checkColumn(colDef *ast.ColumnDef) error { return nil } -// isNowSymFunc checks whether defaul value is a NOW() builtin function. +// isNowSymFunc checks whether default value is a NOW() builtin function. func isDefaultValNowSymFunc(expr ast.ExprNode) bool { if funcCall, ok := expr.(*ast.FuncCallExpr); ok { // Default value NOW() is transformed to CURRENT_TIMESTAMP() in parser. diff --git a/plan/preprocess_test.go b/plan/preprocess_test.go index bedbd4ceda27e..e6ff75012d473 100644 --- a/plan/preprocess_test.go +++ b/plan/preprocess_test.go @@ -97,10 +97,6 @@ func (s *testValidatorSuite) TestValidator(c *C) { errors.New("[types:1439]Display width out of range for column 'c' (max = 4294967295)")}, {"alter table t add column c float(4294967296)", true, errors.New("[types:1439]Display width out of range for column 'c' (max = 4294967295)")}, - {"create table t (c float(54))", true, - errors.New("[types:1063]Incorrect column specifier for column 'c'")}, - {"alter table t add column c float(54)", true, - errors.New("[types:1063]Incorrect column specifier for column 'c'")}, {"create table t (set65 set ('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50','51','52','53','54','55','56','57','58','59','60','61','62','63','64','65'))", true, errors.New("[types:1097]Too many strings for column set65 and SET")}, {"alter table t add column set65 set ('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50','51','52','53','54','55','56','57','58','59','60','61','62','63','64','65')", true, @@ -172,6 +168,13 @@ func (s *testValidatorSuite) TestValidator(c *C) { {"alter table t modify column a DECIMAL(66,30);", false, types.ErrTooBigPrecision}, {"alter table t modify column a DECIMAL(65,31);", false, types.ErrTooBigScale}, {"alter table t modify column a DECIMAL(65,30);", true, nil}, + + {"CREATE TABLE t (a float(255, 30))", true, nil}, + {"CREATE TABLE t (a double(255, 30))", true, nil}, + {"CREATE TABLE t (a float(256, 30))", false, types.ErrTooBigPrecision}, + {"CREATE TABLE t (a float(255, 31))", false, types.ErrTooBigScale}, + {"CREATE TABLE t (a double(256, 30))", false, types.ErrTooBigPrecision}, + {"CREATE TABLE t (a double(255, 31))", false, types.ErrTooBigScale}, } store, dom, err := newStoreWithBootstrap()