From 088603f1dfc8cfe21441b251f4bade37033340bf Mon Sep 17 00:00:00 2001 From: crazycs Date: Tue, 14 May 2019 13:29:40 +0800 Subject: [PATCH] ddl: prohibit modification decimal precision to avoid inconsistency problem (#10433) --- ddl/column_test.go | 2 ++ ddl/ddl_api.go | 4 ++++ executor/admin_test.go | 10 ++++++++++ 3 files changed, 16 insertions(+) diff --git a/ddl/column_test.go b/ddl/column_test.go index c53a74424f43b..2ec1e2a5d3584 100644 --- a/ddl/column_test.go +++ b/ddl/column_test.go @@ -934,6 +934,8 @@ func (s *testColumnSuite) TestModifyColumn(c *C) { {"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}, + {"decimal(2,1)", "decimal(3,2)", errUnsupportedModifyColumn.GenWithStack("unsupported modify decimal column precision")}, + {"decimal(2,1)", "decimal(2,1)", nil}, } for _, tt := range tests { ftA := s.colDefStrToFieldType(c, tt.origin) diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index 73df8ba066690..ea1a6edabb6e0 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -2192,6 +2192,10 @@ func modifiableCharsetAndCollation(toCharset, toCollate, origCharset, origCollat // It returns true if the two types has the same Charset and Collation, the same sign, both are // integer types or string types, and new Flen and Decimal must be greater than or equal to origin. func modifiable(origin *types.FieldType, to *types.FieldType) error { + // The root cause is modifying decimal precision needs to rewrite binary representation of that decimal. + if origin.Tp == mysql.TypeNewDecimal && (to.Flen != origin.Flen || to.Decimal != origin.Decimal) { + return errUnsupportedModifyColumn.GenWithStack("unsupported modify decimal column precision") + } if to.Flen > 0 && to.Flen < origin.Flen { msg := fmt.Sprintf("length %d is less than origin %d", to.Flen, origin.Flen) return errUnsupportedModifyColumn.GenWithStackByArgs(msg) diff --git a/executor/admin_test.go b/executor/admin_test.go index 1d825cde657ab..f2317570e23b7 100644 --- a/executor/admin_test.go +++ b/executor/admin_test.go @@ -505,6 +505,16 @@ func (s *testSuite1) TestAdminCheckTable(c *C) { tk.MustExec(`alter table t1 add column b timestamp not null;`) tk.MustExec(`alter table t1 add index(b);`) tk.MustExec(`admin check table t1;`) + + // Test for index with change decimal precision. + tk.MustExec(`drop table if exists t1`) + tk.MustExec(`create table t1 (a decimal(2,1), index(a))`) + tk.MustExec(`insert into t1 set a='1.9'`) + _, err = tk.Exec(`alter table t1 modify column a decimal(3,2);`) + c.Assert(err, NotNil) + c.Assert(err.Error(), Equals, "[ddl:203]unsupported modify decimal column precision") + tk.MustExec(`delete from t1;`) + tk.MustExec(`admin check table t1;`) } func (s *testSuite1) TestAdminCheckPrimaryIndex(c *C) {