Skip to content

Commit

Permalink
cherry pick pingcap#19806 to release-3.0
Browse files Browse the repository at this point in the history
Signed-off-by: ti-srebot <ti-srebot@pingcap.com>
  • Loading branch information
xiongjiwei authored and ti-srebot committed Sep 17, 2020
1 parent d23d8bd commit 817a983
Show file tree
Hide file tree
Showing 2 changed files with 249 additions and 1 deletion.
34 changes: 33 additions & 1 deletion ddl/ddl_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -2452,20 +2452,40 @@ func modifiable(origin *types.FieldType, to *types.FieldType) error {
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 {
<<<<<<< HEAD
msg := fmt.Sprintf("cannot modify enum type column's to type %s", 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))
return errUnsupportedModifyColumn.GenWithStackByArgs(msg)
=======
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 %s column's elements is less than the original: %d", typeVar, len(origin.Elems))
return "", errUnsupportedModifyColumn.GenWithStackByArgs(msg)
>>>>>>> 73e03c7... ddl: check constraint when alter enum/set type column (#19806)
}
for index, originElem := range origin.Elems {
toElem := to.Elems[index]
if originElem != toElem {
<<<<<<< HEAD
msg := fmt.Sprintf("cannot modify enum column value %s to %s", originElem, toElem)
return errUnsupportedModifyColumn.GenWithStackByArgs(msg)
=======
msg := fmt.Sprintf("cannot modify %s column value %s to %s", typeVar, originElem, toElem)
return "", errUnsupportedModifyColumn.GenWithStackByArgs(msg)
>>>>>>> 73e03c7... ddl: check constraint when alter enum/set type column (#19806)
}
}
case mysql.TypeNewDecimal:
Expand Down Expand Up @@ -2688,7 +2708,19 @@ func (d *ddl) getModifiableColumnJob(ctx sessionctx.Context, ident ast.Ident, or
return nil, errors.Trace(err)
}

<<<<<<< HEAD
if err = modifiable(&col.FieldType, &newCol.FieldType); err != nil {
=======
if err = checkColumnValueConstraint(newCol, newCol.Collate); err != nil {
return nil, errors.Trace(err)
}

if err = checkModifyTypes(ctx, &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."
err = errUnsupportedModifyCollation.GenWithStack(colErrMsg, col.Name.L, col.Collate, newCol.Collate)
}
>>>>>>> 73e03c7... ddl: check constraint when alter enum/set type column (#19806)
return nil, errors.Trace(err)
}

Expand Down
216 changes: 216 additions & 0 deletions expression/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5144,3 +5144,219 @@ func (s *testIntegrationSuite) TestIssue18850(c *C) {
tk.MustExec("insert into t1 values (1, 'A');")
tk.MustQuery("select /*+ HASH_JOIN(t, t1) */ * from t join t1 on t.b = t1.b1;").Check(testkit.Rows("1 A 1 A"))
}
<<<<<<< HEAD
=======

func (s *testIntegrationSerialSuite) TestNullValueRange(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a int, b int, index(a))")
tk.MustExec("insert into t values (null, 0), (null, 1), (10, 11), (10, 12)")
tk.MustQuery("select * from t use index(a) where a is null order by b").Check(testkit.Rows("<nil> 0", "<nil> 1"))
tk.MustQuery("select * from t use index(a) where a<=>null order by b").Check(testkit.Rows("<nil> 0", "<nil> 1"))
tk.MustQuery("select * from t use index(a) where a<=>10 order by b").Check(testkit.Rows("10 11", "10 12"))

tk.MustExec("drop table if exists t1")
tk.MustExec("create table t1(a int, b int, c int, unique key(a, b, c))")
tk.MustExec("insert into t1 values (1, null, 1), (1, null, 2), (1, null, 3), (1, null, 4)")
tk.MustExec("insert into t1 values (1, 1, 1), (1, 2, 2), (1, 3, 33), (1, 4, 44)")
tk.MustQuery("select c from t1 where a=1 and b<=>null and c>2 order by c").Check(testkit.Rows("3", "4"))
tk.MustQuery("select c from t1 where a=1 and b is null and c>2 order by c").Check(testkit.Rows("3", "4"))
tk.MustQuery("select c from t1 where a=1 and b is not null and c>2 order by c").Check(testkit.Rows("33", "44"))
}

func (s *testIntegrationSerialSuite) TestIssue18652(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("DROP TABLE IF EXISTS t1")
tk.MustExec("CREATE TABLE t1 ( `pk` int not null primary key auto_increment, `col_smallint_key_signed` smallint , key (`col_smallint_key_signed`))")
tk.MustExec("INSERT INTO `t1` VALUES (1,0),(2,NULL),(3,NULL),(4,0),(5,0),(6,NULL),(7,NULL),(8,0),(9,0),(10,0)")
tk.MustQuery("SELECT * FROM t1 WHERE ( LOG( `col_smallint_key_signed`, -8297584758403770424 ) ) DIV 1").Check(testkit.Rows())
}

func (s *testIntegrationSerialSuite) TestIssue18662(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 varchar(10) collate utf8mb4_bin, b varchar(10) collate utf8mb4_general_ci);")
tk.MustExec("insert into t (a, b) values ('a', 'A');")
tk.MustQuery("select * from t where field('A', a collate utf8mb4_general_ci, b) > 1;").Check(testkit.Rows())
tk.MustQuery("select * from t where field('A', a, b collate utf8mb4_general_ci) > 1;").Check(testkit.Rows())
tk.MustQuery("select * from t where field('A' collate utf8mb4_general_ci, a, b) > 1;").Check(testkit.Rows())
tk.MustQuery("select * from t where field('A', a, b) > 1;").Check(testkit.Rows("a A"))
}

func (s *testIntegrationSerialSuite) TestIssue19045(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t, t1, t2")
tk.MustExec(`CREATE TABLE t (
id int(11) NOT NULL AUTO_INCREMENT,
a char(10) DEFAULT NULL,
PRIMARY KEY (id)
);`)
tk.MustExec(`CREATE TABLE t1 (
id int(11) NOT NULL AUTO_INCREMENT,
a char(10) DEFAULT NULL,
b char(10) DEFAULT NULL,
c char(10) DEFAULT NULL,
PRIMARY KEY (id)
);`)
tk.MustExec(`CREATE TABLE t2 (
id int(11) NOT NULL AUTO_INCREMENT,
a char(10) DEFAULT NULL,
b char(10) DEFAULT NULL,
PRIMARY KEY (id),
UNIQUE KEY b (b)
);`)
tk.MustExec(`insert into t1(a,b,c) values('hs4_0004', "04", "101"), ('a01', "01", "101"),('a011', "02", "101");`)
tk.MustExec(`insert into t2(a,b) values("02","03");`)
tk.MustExec(`insert into t(a) values('101'),('101');`)
tk.MustQuery(`select ( SELECT t1.a FROM t1, t2 WHERE t1.b = t2.a AND t2.b = '03' AND t1.c = a.a) invode from t a ;`).Check(testkit.Rows("a011", "a011"))
}

func (s *testIntegrationSerialSuite) TestIssue19116(c *C) {
collate.SetNewCollationEnabledForTest(true)
defer collate.SetNewCollationEnabledForTest(false)

tk := testkit.NewTestKit(c, s.store)
tk.MustExec("set names utf8mb4 collate utf8mb4_general_ci;")
tk.MustQuery("select collation(concat(1 collate `binary`));").Check(testkit.Rows("binary"))
tk.MustQuery("select coercibility(concat(1 collate `binary`));").Check(testkit.Rows("0"))
tk.MustQuery("select collation(concat(NULL,NULL));").Check(testkit.Rows("binary"))
tk.MustQuery("select coercibility(concat(NULL,NULL));").Check(testkit.Rows("6"))
tk.MustQuery("select collation(concat(1,1));").Check(testkit.Rows("utf8mb4_general_ci"))
tk.MustQuery("select coercibility(concat(1,1));").Check(testkit.Rows("4"))
tk.MustQuery("select collation(1);").Check(testkit.Rows("binary"))
tk.MustQuery("select coercibility(1);").Check(testkit.Rows("5"))
tk.MustQuery("select coercibility(1=1);").Check(testkit.Rows("5"))
}

func (s *testIntegrationSerialSuite) TestIssue19315(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t")
tk.MustExec("drop table if exists t1")
tk.MustExec("CREATE TABLE `t` (`a` bit(10) DEFAULT NULL,`b` int(11) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")
tk.MustExec("INSERT INTO `t` VALUES (_binary '\\0',1),(_binary '\\0',2),(_binary '\\0',5),(_binary '\\0',4),(_binary '\\0',2),(_binary '\\0 ',4)")
tk.MustExec("CREATE TABLE `t1` (`a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")
tk.MustExec("INSERT INTO `t1` VALUES (1,1),(1,5),(2,3),(2,4),(3,3)")
err := tk.QueryToErr("select * from t where t.b > (select min(t1.b) from t1 where t1.a > t.a)")
c.Assert(err, IsNil)
}

func (s *testIntegrationSerialSuite) TestIssue18674(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustQuery("select -1.0 % -1.0").Check(testkit.Rows("0.0"))
tk.MustExec("use test")
tk.MustExec("drop table if exists t1")
tk.MustExec("create table t1(`pk` int primary key,`col_float_key_signed` float ,key (`col_float_key_signed`))")
tk.MustExec("insert into t1 values (0, null), (1, 0), (2, -0), (3, 1), (-1,-1)")
tk.MustQuery("select * from t1 where ( `col_float_key_signed` % `col_float_key_signed`) IS FALSE").Sort().Check(testkit.Rows("-1 -1", "3 1"))
tk.MustQuery("select `col_float_key_signed` , `col_float_key_signed` % `col_float_key_signed` from t1").Sort().Check(testkit.Rows(
"-1 -0", "0 <nil>", "0 <nil>", "1 0", "<nil> <nil>"))
tk.MustQuery("select `col_float_key_signed` , (`col_float_key_signed` % `col_float_key_signed`) IS FALSE from t1").Sort().Check(testkit.Rows(
"-1 1", "0 0", "0 0", "1 1", "<nil> 0"))
}

func (s *testIntegrationSerialSuite) TestIssue17063(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 char, b char) collate utf8mb4_general_ci;")
tk.MustExec(`insert into t values('a', 'b');`)
tk.MustExec(`insert into t values('a', 'B');`)
tk.MustQuery(`select * from t where if(a='x', a, b) = 'b';`).Check(testkit.Rows("a b", "a B"))
tk.MustQuery(`select collation(if(a='x', a, b)) from t;`).Check(testkit.Rows("utf8mb4_general_ci", "utf8mb4_general_ci"))
tk.MustQuery(`select coercibility(if(a='x', a, b)) from t;`).Check(testkit.Rows("2", "2"))
tk.MustQuery(`select collation(lag(b, 1, 'B') over w) from t window w as (order by b);`).Check(testkit.Rows("utf8mb4_general_ci", "utf8mb4_general_ci"))
tk.MustQuery(`select coercibility(lag(b, 1, 'B') over w) from t window w as (order by b);`).Check(testkit.Rows("2", "2"))
}

func (s *testIntegrationSuite) TestIssue19504(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t1;")
tk.MustExec("create table t1 (c_int int, primary key (c_int));")
tk.MustExec("insert into t1 values (1), (2), (3);")
tk.MustExec("drop table if exists t2;")
tk.MustExec("create table t2 (c_int int, primary key (c_int));")
tk.MustExec("insert into t2 values (1);")
tk.MustQuery("select (select count(c_int) from t2 where c_int = t1.c_int) c1, (select count(1) from t2 where c_int = t1.c_int) c2 from t1;").
Check(testkit.Rows("1 1", "0 0", "0 0"))
}

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)

tk := testkit.NewTestKit(c, s.store)
tk.MustExec(`use test;`)
tk.MustExec(`drop table if exists t;`)
tk.MustExec(`create table t(a enum('a ', 'b\t', ' c '), b set('a ', 'b\t', ' c '));`)
result := tk.MustQuery("show create table t").Rows()[0][1]
c.Assert(result, Matches, `(?s).*enum\('a','b ',' c'\).*set\('a','b ',' c'\).*`)
tk.MustExec(`alter table t change a aa enum('a ', 'b\t', ' c ');`)
result = tk.MustQuery("show create table t").Rows()[0][1]
c.Assert(result, Matches, `(?s).*enum\('a','b ',' c'\).*set\('a','b ',' c'\).*`)
}

func (s *testIntegrationSuite) TestIssue19596(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t;")
tk.MustExec("create table t (a int) partition by range(a) (PARTITION p0 VALUES LESS THAN (10));")
tk.MustGetErrMsg("alter table t add partition (partition p1 values less than (a));", "[expression:1054]Unknown column 'a' in 'expression'")
tk.MustQuery("select * from t;")
tk.MustExec("drop table if exists t;")
tk.MustGetErrMsg("create table t (a int) partition by range(a) (PARTITION p0 VALUES LESS THAN (a));", "[expression:1054]Unknown column 'a' in 'expression'")
}

func (s *testIntegrationSuite) TestIssue17476(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("DROP TABLE IF EXISTS `table_float`;")
tk.MustExec("DROP TABLE IF EXISTS `table_int_float_varchar`;")
tk.MustExec("CREATE TABLE `table_float` (`id_1` int(16) NOT NULL AUTO_INCREMENT,`col_float_1` float DEFAULT NULL,PRIMARY KEY (`id_1`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin AUTO_INCREMENT=97635;")
tk.MustExec("CREATE TABLE `table_int_float_varchar` " +
"(`id_6` int(16) NOT NULL AUTO_INCREMENT," +
"`col_int_6` int(16) DEFAULT NULL,`col_float_6` float DEFAULT NULL," +
"`col_varchar_6` varchar(511) DEFAULT NULL,PRIMARY KEY (`id_6`)," +
"KEY `vhyen` (`id_6`,`col_int_6`,`col_float_6`,`col_varchar_6`(1))," +
"KEY `zzylq` (`id_6`,`col_int_6`,`col_float_6`,`col_varchar_6`(1))) " +
"ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin AUTO_INCREMENT=90818;")

tk.MustExec("INSERT INTO `table_float` VALUES (1,NULL),(2,0.1),(3,0),(4,-0.1),(5,-0.1),(6,NULL),(7,0.5),(8,0),(9,0),(10,NULL),(11,1),(12,1.5),(13,NULL),(14,NULL);")
tk.MustExec("INSERT INTO `table_int_float_varchar` VALUES (1,0,0.1,'true'),(2,-1,1.5,'2020-02-02 02:02:00'),(3,NULL,1.5,NULL),(4,65535,0.1,'true'),(5,NULL,0.1,'1'),(6,-1,1.5,'2020-02-02 02:02:00'),(7,-1,NULL,''),(8,NULL,-0.1,NULL),(9,NULL,-0.1,'1'),(10,-1,NULL,''),(11,NULL,1.5,'false'),(12,-1,0,NULL),(13,0,-0.1,NULL),(14,-1,NULL,'-0'),(15,65535,-1,'1'),(16,NULL,0.5,NULL),(17,-1,NULL,NULL);")
tk.MustQuery(`select count(*) from table_float
JOIN table_int_float_varchar AS tmp3 ON (tmp3.col_varchar_6 AND NULL)
IS NULL WHERE col_int_6=0;`).Check(testkit.Rows("14"))
tk.MustQuery(`SELECT count(*) FROM (table_float JOIN table_int_float_varchar AS tmp3 ON (tmp3.col_varchar_6 AND NULL) IS NULL);`).Check(testkit.Rows("154"))
tk.MustQuery(`SELECT * FROM (table_int_float_varchar AS tmp3) WHERE (col_varchar_6 AND NULL) IS NULL AND col_int_6=0;`).Check(testkit.Rows("13 0 -0.1 <nil>"))
}
>>>>>>> 73e03c7... ddl: check constraint when alter enum/set type column (#19806)

0 comments on commit 817a983

Please sign in to comment.