From 2a758efe3e5899b045f0c1c39bd288c7d5e41f70 Mon Sep 17 00:00:00 2001 From: ti-srebot <66930949+ti-srebot@users.noreply.github.com> Date: Sat, 3 Oct 2020 21:35:39 +0800 Subject: [PATCH] ddl: check constraint when alter enum/set type column (#19806) (#20046) --- ddl/ddl_api.go | 18 ++++++++++++++---- expression/integration_test.go | 20 +++++++++++++++++++- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index 0da443b5c99ce..2c0cdd2411f5b 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -2734,19 +2734,25 @@ func CheckModifyTypeCompatible(origin *types.FieldType, to *types.FieldType) err default: return errUnsupportedModifyColumn.GenWithStackByArgs(unsupportedMsg) } - case mysql.TypeEnum: + case mysql.TypeEnum, mysql.TypeSet: + var typeVar string + if origin.Tp == mysql.TypeEnum { + typeVar = "enum" + } else { + typeVar = "set" + } if origin.Tp != to.Tp { - msg := fmt.Sprintf("cannot modify enum type column's to type %s", to.String()) + msg := fmt.Sprintf("cannot modify %s type column's to type %s", typeVar, to.String()) return errUnsupportedModifyColumn.GenWithStackByArgs(msg) } if len(to.Elems) < len(origin.Elems) { - msg := fmt.Sprintf("the number of enum column's elements is less than the original: %d", len(origin.Elems)) + msg := fmt.Sprintf("the number of %s column's elements is less than the original: %d", typeVar, len(origin.Elems)) return errUnsupportedModifyColumn.GenWithStackByArgs(msg) } for index, originElem := range origin.Elems { toElem := to.Elems[index] if originElem != toElem { - msg := fmt.Sprintf("cannot modify enum column value %s to %s", originElem, toElem) + msg := fmt.Sprintf("cannot modify %s column value %s to %s", typeVar, originElem, toElem) return errUnsupportedModifyColumn.GenWithStackByArgs(msg) } } @@ -2999,6 +3005,10 @@ func (d *ddl) getModifiableColumnJob(ctx sessionctx.Context, ident ast.Ident, or return nil, errors.Trace(err) } + if err = checkColumnValueConstraint(newCol, newCol.Collate); err != nil { + return nil, errors.Trace(err) + } + if err = checkModifyTypes(&col.FieldType, &newCol.FieldType, isColumnWithIndex(col.Name.L, t.Meta().Indices)); err != nil { if strings.Contains(err.Error(), "Unsupported modifying collation") { colErrMsg := "Unsupported modifying collation of column '%s' from '%s' to '%s' when index is defined on it." diff --git a/expression/integration_test.go b/expression/integration_test.go index 7c552226a5202..d24c10d0fcff0 100755 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -6951,7 +6951,25 @@ func (s *testIntegrationSuite) TestIssue19504(c *C) { Check(testkit.Rows("1 1", "0 0", "0 0")) } -func (s *testIntegrationSerialSuite) TestIssue17891(c *C) { +func (s *testIntegrationSerialSuite) TestIssue19804(c *C) { + collate.SetNewCollationEnabledForTest(true) + defer collate.SetNewCollationEnabledForTest(false) + + tk := testkit.NewTestKit(c, s.store) + tk.MustExec(`use test;`) + tk.MustExec(`drop table if exists t;`) + tk.MustExec(`create table t(a set('a', 'b', 'c'));`) + tk.MustGetErrMsg("alter table t change a a set('a', 'b', 'c', 'c');", "[types:1291]Column 'a' has duplicated value 'c' in SET") + tk.MustExec(`drop table if exists t;`) + tk.MustExec(`create table t(a enum('a', 'b', 'c'));`) + tk.MustGetErrMsg("alter table t change a a enum('a', 'b', 'c', 'c');", "[types:1291]Column 'a' has duplicated value 'c' in ENUM") + tk.MustExec(`drop table if exists t;`) + tk.MustExec(`create table t(a set('a', 'b', 'c'));`) + tk.MustExec(`alter table t change a a set('a', 'b', 'c', 'd');`) + tk.MustGetErrMsg(`alter table t change a a set('a', 'b', 'c', 'e', 'f');`, "[ddl:8200]Unsupported modify column: cannot modify set column value d to e") +} + +func (s *testIntegrationSerialSuite) TestIssue18949(c *C) { collate.SetNewCollationEnabledForTest(true) defer collate.SetNewCollationEnabledForTest(false)