From 44dd0bcf8a0040ef1b003a20b1a0edf565d04b32 Mon Sep 17 00:00:00 2001 From: crazycs520 Date: Tue, 14 May 2019 20:26: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 0da79df1c9087..e5e649559d0fa 100644 --- a/ddl/column_test.go +++ b/ddl/column_test.go @@ -935,6 +935,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 8d30544a5c2bd..7d79e415cb349 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -1670,6 +1670,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 b3da8719c2a6e..ac5210e74a0b7 100644 --- a/executor/admin_test.go +++ b/executor/admin_test.go @@ -515,6 +515,16 @@ func (s *testSuite) 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 *testSuite) TestAdminCheckPrimaryIndex(c *C) {