diff --git a/ddl/column_type_change_test.go b/ddl/column_type_change_test.go index f8a083697086a..ea9dc6c5b9926 100644 --- a/ddl/column_type_change_test.go +++ b/ddl/column_type_change_test.go @@ -1200,7 +1200,8 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromJsonToOthers(c *C) { i json, ui json, f64 json, - str json + str json, + nul json ) `) } @@ -1208,13 +1209,13 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromJsonToOthers(c *C) { // To numeric data types. // tinyint reset(tk) - tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')") + tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"', null)") // MySQL will get "ERROR 1366 (HY000) Incorrect integer value: '{"obj": 100}' for column 'obj' at row 1". tk.MustGetErrCode("alter table t modify obj tinyint", mysql.ErrTruncatedWrongValue) // MySQL will get "ERROR 1366 (HY000) Incorrect integer value: '[-1, 0, 1]' for column 'arr' at row 1". tk.MustGetErrCode("alter table t modify arr tinyint", mysql.ErrTruncatedWrongValue) // MySQL will get "ERROR 1366 (HY000) Incorrect integer value: 'null' for column 'nil' at row 1". - tk.MustExec("alter table t modify nil tinyint") + tk.MustGetErrCode("alter table t modify nil tinyint", mysql.ErrTruncatedWrongValue) // MySQL will get "ERROR 1366 (HY000) Incorrect integer value: 'true' for column 't' at row 1". tk.MustExec("alter table t modify t tinyint") // MySQL will get "ERROR 1366 (HY000) Incorrect integer value: 'false' for column 'f' at row 1". @@ -1224,17 +1225,18 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromJsonToOthers(c *C) { tk.MustGetErrCode("alter table t modify f64 tinyint", mysql.ErrDataOutOfRange) // MySQL will get "ERROR 1366 (HY000) Incorrect integer value: '"json string"' for column 'str' at row 1". tk.MustGetErrCode("alter table t modify str tinyint", mysql.ErrTruncatedWrongValue) - tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] 0 1 0 -22 22 323232323.32323235 \"json string\"")) + tk.MustExec("alter table t modify nul tinyint") + tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null 1 0 -22 22 323232323.32323235 \"json string\" ")) // int reset(tk) - tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')") + tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"', null)") // MySQL will get "ERROR 1366 (HY000) Incorrect integer value: '{"obj": 100}' for column 'obj' at row 1". tk.MustGetErrCode("alter table t modify obj int", mysql.ErrTruncatedWrongValue) // MySQL will get "ERROR 1366 (HY000) Incorrect integer value: '[-1, 0, 1]' for column 'arr' at row 1". tk.MustGetErrCode("alter table t modify arr int", mysql.ErrTruncatedWrongValue) // MySQL will get "ERROR 1366 (HY000) Incorrect integer value: 'null' for column 'nil' at row 1". - tk.MustExec("alter table t modify nil int") + tk.MustGetErrCode("alter table t modify nil int", mysql.ErrTruncatedWrongValue) // MySQL will get "ERROR 1366 (HY000) Incorrect integer value: 'true' for column 't' at row 1". tk.MustExec("alter table t modify t int") // MySQL will get "ERROR 1366 (HY000) Incorrect integer value: 'false' for column 'f' at row 1". @@ -1244,17 +1246,18 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromJsonToOthers(c *C) { tk.MustExec("alter table t modify f64 int") // MySQL will get "ERROR 1366 (HY000) Incorrect integer value: '"json string"' for column 'str' at row 1". tk.MustGetErrCode("alter table t modify str int", mysql.ErrTruncatedWrongValue) - tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] 0 1 0 -22 22 323232323 \"json string\"")) + tk.MustExec("alter table t modify nul int") + tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null 1 0 -22 22 323232323 \"json string\" ")) // bigint reset(tk) - tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')") + tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"', null)") // MySQL will get "ERROR 1366 (HY000) Incorrect integer value: '{"obj": 100}' for column 'obj' at row 1". tk.MustGetErrCode("alter table t modify obj bigint", mysql.ErrTruncatedWrongValue) // MySQL will get "ERROR 1366 (HY000) Incorrect integer value: '[-1, 0, 1]' for column 'arr' at row 1". tk.MustGetErrCode("alter table t modify arr bigint", mysql.ErrTruncatedWrongValue) // MySQL will get "ERROR 1366 (HY000) Incorrect integer value: 'null' for column 'nil' at row 1". - tk.MustExec("alter table t modify nil bigint") + tk.MustGetErrCode("alter table t modify nil bigint", mysql.ErrTruncatedWrongValue) // MySQL will get "ERROR 1366 (HY000) Incorrect integer value: 'true' for column 't' at row 1". tk.MustExec("alter table t modify t bigint") // MySQL will get "ERROR 1366 (HY000) Incorrect integer value: 'false' for column 'f' at row 1". @@ -1264,17 +1267,18 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromJsonToOthers(c *C) { tk.MustExec("alter table t modify f64 bigint") // MySQL will get "ERROR 1366 (HY000) Incorrect integer value: '"json string"' for column 'str' at row 1". tk.MustGetErrCode("alter table t modify str bigint", mysql.ErrTruncatedWrongValue) - tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] 0 1 0 -22 22 323232323 \"json string\"")) + tk.MustExec("alter table t modify nul bigint") + tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null 1 0 -22 22 323232323 \"json string\" ")) // unsigned bigint reset(tk) - tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')") + tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"', null)") // MySQL will get "ERROR 1366 (HY000) Incorrect integer value: '{"obj": 100}' for column 'obj' at row 1". tk.MustGetErrCode("alter table t modify obj bigint unsigned", mysql.ErrTruncatedWrongValue) // MySQL will get "ERROR 1366 (HY000) Incorrect integer value: '[-1, 0, 1]' for column 'arr' at row 1". tk.MustGetErrCode("alter table t modify arr bigint unsigned", mysql.ErrTruncatedWrongValue) // MySQL will get "ERROR 1366 (HY000) Incorrect integer value: 'null' for column 'nil' at row 1". - tk.MustExec("alter table t modify nil bigint unsigned") + tk.MustGetErrCode("alter table t modify nil bigint unsigned", mysql.ErrTruncatedWrongValue) // MySQL will get "ERROR 1366 (HY000) Incorrect integer value: 'true' for column 't' at row 1". tk.MustExec("alter table t modify t bigint unsigned") // MySQL will get "ERROR 1366 (HY000) Incorrect integer value: 'false' for column 'f' at row 1". @@ -1285,11 +1289,12 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromJsonToOthers(c *C) { tk.MustExec("alter table t modify f64 bigint unsigned") // MySQL will get "ERROR 1366 (HY000) Incorrect integer value: '"json string"' for column 'str' at row 1". tk.MustGetErrCode("alter table t modify str bigint unsigned", mysql.ErrTruncatedWrongValue) - tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] 0 1 0 -22 22 323232323 \"json string\"")) + tk.MustExec("alter table t modify nul bigint unsigned") + tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null 1 0 -22 22 323232323 \"json string\" ")) // bit reset(tk) - tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')") + tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"', null)") tk.MustGetErrCode("alter table t modify obj bit", mysql.ErrUnsupportedDDLOperation) tk.MustGetErrCode("alter table t modify arr bit", mysql.ErrUnsupportedDDLOperation) tk.MustGetErrCode("alter table t modify nil bit", mysql.ErrUnsupportedDDLOperation) @@ -1299,17 +1304,18 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromJsonToOthers(c *C) { tk.MustGetErrCode("alter table t modify ui bit", mysql.ErrUnsupportedDDLOperation) tk.MustGetErrCode("alter table t modify f64 bit", mysql.ErrUnsupportedDDLOperation) tk.MustGetErrCode("alter table t modify str bit", mysql.ErrUnsupportedDDLOperation) - tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null true false -22 22 323232323.32323235 \"json string\"")) + tk.MustGetErrCode("alter table t modify nul bit", mysql.ErrUnsupportedDDLOperation) + tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null true false -22 22 323232323.32323235 \"json string\" ")) // decimal reset(tk) - tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')") + tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"', null)") // MySQL will get "ERROR 3156 (22001) Invalid JSON value for CAST to DECIMAL from column obj at row 1". tk.MustGetErrCode("alter table t modify obj decimal(20, 10)", mysql.ErrTruncatedWrongValue) // MySQL will get "ERROR 3156 (22001) Invalid JSON value for CAST to DECIMAL from column arr at row 1". tk.MustGetErrCode("alter table t modify arr decimal(20, 10)", mysql.ErrTruncatedWrongValue) // MySQL will get "ERROR 3156 (22001) Invalid JSON value for CAST to DECIMAL from column nil at row 1". - tk.MustExec("alter table t modify nil decimal(20, 10)") + tk.MustGetErrCode("alter table t modify nil decimal(20, 10)", mysql.ErrTruncatedWrongValue) tk.MustExec("alter table t modify t decimal(20, 10)") tk.MustExec("alter table t modify f decimal(20, 10)") tk.MustExec("alter table t modify i decimal(20, 10)") @@ -1317,17 +1323,18 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromJsonToOthers(c *C) { tk.MustExec("alter table t modify f64 decimal(20, 10)") // MySQL will get "ERROR 1366 (HY000): Incorrect DECIMAL value: '0' for column '' at row -1". tk.MustGetErrCode("alter table t modify str decimal(20, 10)", mysql.ErrBadNumber) - tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] 0.0000000000 1.0000000000 0.0000000000 -22.0000000000 22.0000000000 323232323.3232323500 \"json string\"")) + tk.MustExec("alter table t modify nul decimal(20, 10)") + tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null 1.0000000000 0.0000000000 -22.0000000000 22.0000000000 323232323.3232323500 \"json string\" ")) // double reset(tk) - tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')") + tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"', null)") // MySQL will get "ERROR 1265 (01000): Data truncated for column 'obj' at row 1". tk.MustGetErrCode("alter table t modify obj double", mysql.ErrTruncatedWrongValue) // MySQL will get "ERROR 1265 (01000): Data truncated for column 'arr' at row 1". tk.MustGetErrCode("alter table t modify arr double", mysql.ErrTruncatedWrongValue) // MySQL will get "ERROR 1265 (01000): Data truncated for column 'nil' at row 1". - tk.MustExec("alter table t modify nil double") + tk.MustGetErrCode("alter table t modify nil double", mysql.ErrTruncatedWrongValue) // MySQL will get "ERROR 1265 (01000): Data truncated for column 't' at row 1". tk.MustExec("alter table t modify t double") // MySQL will get "ERROR 1265 (01000): Data truncated for column 'f' at row 1". @@ -1337,12 +1344,13 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromJsonToOthers(c *C) { tk.MustExec("alter table t modify f64 double") // MySQL will get "ERROR 1265 (01000): Data truncated for column 'str' at row 1". tk.MustGetErrCode("alter table t modify str double", mysql.ErrTruncatedWrongValue) - tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] 0 1 0 -22 22 323232323.32323235 \"json string\"")) + tk.MustExec("alter table t modify nul double") + tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null 1 0 -22 22 323232323.32323235 \"json string\" ")) // To string data types. // char reset(tk) - tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')") + tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"', null)") tk.MustExec("alter table t modify obj char(20)") tk.MustExec("alter table t modify arr char(20)") tk.MustExec("alter table t modify nil char(20)") @@ -1352,11 +1360,12 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromJsonToOthers(c *C) { tk.MustExec("alter table t modify ui char(20)") tk.MustExec("alter table t modify f64 char(20)") tk.MustExec("alter table t modify str char(20)") - tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null true false -22 22 323232323.32323235 \"json string\"")) + tk.MustExec("alter table t modify nil char(20)") + tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null true false -22 22 323232323.32323235 \"json string\" ")) // varchar reset(tk) - tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')") + tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"', null)") tk.MustExec("alter table t modify obj varchar(20)") tk.MustExec("alter table t modify arr varchar(20)") tk.MustExec("alter table t modify nil varchar(20)") @@ -1366,11 +1375,12 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromJsonToOthers(c *C) { tk.MustExec("alter table t modify ui varchar(20)") tk.MustExec("alter table t modify f64 varchar(20)") tk.MustExec("alter table t modify str varchar(20)") - tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null true false -22 22 323232323.32323235 \"json string\"")) + tk.MustExec("alter table t modify nul varchar(20)") + tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null true false -22 22 323232323.32323235 \"json string\" ")) // binary reset(tk) - tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')") + tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"', null)") tk.MustExec("alter table t modify obj binary(20)") tk.MustExec("alter table t modify arr binary(20)") tk.MustExec("alter table t modify nil binary(20)") @@ -1380,6 +1390,7 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromJsonToOthers(c *C) { tk.MustExec("alter table t modify ui binary(20)") tk.MustExec("alter table t modify f64 binary(20)") tk.MustExec("alter table t modify str binary(20)") + tk.MustExec("alter table t modify nul binary(20)") tk.MustQuery("select * from t").Check(testkit.Rows( "{\"obj\": 100}\x00\x00\x00\x00\x00\x00\x00\x00 " + "[-1, 0, 1]\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 " + @@ -1389,10 +1400,10 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromJsonToOthers(c *C) { "-22\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 " + "22\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 " + "323232323.32323235\x00\x00 " + - "\"json string\"\x00\x00\x00\x00\x00\x00\x00")) + "\"json string\"\x00\x00\x00\x00\x00\x00\x00 ")) // varbinary reset(tk) - tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')") + tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"', null)") tk.MustExec("alter table t modify obj varbinary(20)") tk.MustExec("alter table t modify arr varbinary(20)") tk.MustExec("alter table t modify nil varbinary(20)") @@ -1402,11 +1413,12 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromJsonToOthers(c *C) { tk.MustExec("alter table t modify ui varbinary(20)") tk.MustExec("alter table t modify f64 varbinary(20)") tk.MustExec("alter table t modify str varbinary(20)") - tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null true false -22 22 323232323.32323235 \"json string\"")) + tk.MustExec("alter table t modify nul varbinary(20)") + tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null true false -22 22 323232323.32323235 \"json string\" ")) // blob reset(tk) - tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')") + tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"', null)") tk.MustExec("alter table t modify obj blob") tk.MustExec("alter table t modify arr blob") tk.MustExec("alter table t modify nil blob") @@ -1416,11 +1428,12 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromJsonToOthers(c *C) { tk.MustExec("alter table t modify ui blob") tk.MustExec("alter table t modify f64 blob") tk.MustExec("alter table t modify str blob") - tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null true false -22 22 323232323.32323235 \"json string\"")) + tk.MustExec("alter table t modify nul blob") + tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null true false -22 22 323232323.32323235 \"json string\" ")) // text reset(tk) - tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')") + tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"', null)") tk.MustExec("alter table t modify obj text") tk.MustExec("alter table t modify arr text") tk.MustExec("alter table t modify nil text") @@ -1430,11 +1443,12 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromJsonToOthers(c *C) { tk.MustExec("alter table t modify ui text") tk.MustExec("alter table t modify f64 text") tk.MustExec("alter table t modify str text") - tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null true false -22 22 323232323.32323235 \"json string\"")) + tk.MustExec("alter table t modify nul text") + tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null true false -22 22 323232323.32323235 \"json string\" ")) // enum reset(tk) - tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')") + tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"', null)") tk.MustGetErrCode("alter table t modify obj enum('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')", mysql.ErrUnsupportedDDLOperation) tk.MustGetErrCode("alter table t modify arr enum('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')", mysql.ErrUnsupportedDDLOperation) tk.MustGetErrCode("alter table t modify nil enum('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')", mysql.ErrUnsupportedDDLOperation) @@ -1444,11 +1458,12 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromJsonToOthers(c *C) { tk.MustGetErrCode("alter table t modify ui enum('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')", mysql.ErrUnsupportedDDLOperation) tk.MustGetErrCode("alter table t modify f64 enum('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')", mysql.ErrUnsupportedDDLOperation) tk.MustGetErrCode("alter table t modify str enum('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')", mysql.ErrUnsupportedDDLOperation) - tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null true false -22 22 323232323.32323235 \"json string\"")) + tk.MustGetErrCode("alter table t modify nul enum('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')", mysql.ErrUnsupportedDDLOperation) + tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null true false -22 22 323232323.32323235 \"json string\" ")) // set reset(tk) - tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')") + tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"', null)") tk.MustGetErrCode("alter table t modify obj set('{\"obj\": 100}', '[-1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')", mysql.ErrUnsupportedDDLOperation) tk.MustGetErrCode("alter table t modify arr set('{\"obj\": 100}', '[-1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')", mysql.ErrUnsupportedDDLOperation) tk.MustGetErrCode("alter table t modify nil set('{\"obj\": 100}', '[-1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')", mysql.ErrUnsupportedDDLOperation) @@ -1458,12 +1473,13 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromJsonToOthers(c *C) { tk.MustGetErrCode("alter table t modify ui set('{\"obj\": 100}', '[-1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')", mysql.ErrUnsupportedDDLOperation) tk.MustGetErrCode("alter table t modify f64 set('{\"obj\": 100}', '[-1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')", mysql.ErrUnsupportedDDLOperation) tk.MustGetErrCode("alter table t modify str set('{\"obj\": 100}', '[-1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')", mysql.ErrUnsupportedDDLOperation) - tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1] null true false -22 22 323232323.32323235 \"json string\"")) + tk.MustGetErrCode("alter table t modify nul set('{\"obj\": 100}', '[-1]', 'null', 'true', 'false', '-22', '22', '323232323.3232323232', '\"json string\"')", mysql.ErrUnsupportedDDLOperation) + tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1] null true false -22 22 323232323.32323235 \"json string\" ")) // To date and time data types. // datetime reset(tk) - tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '20200826173501', '20201123', '20200826173501.123456', '\"2020-08-26 17:35:01.123456\"')") + tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '20200826173501', '20201123', '20200826173501.123456', '\"2020-08-26 17:35:01.123456\"', null)") tk.MustGetErrCode("alter table t modify obj datetime", mysql.ErrTruncatedWrongValue) tk.MustGetErrCode("alter table t modify arr datetime", mysql.ErrTruncatedWrongValue) tk.MustGetErrCode("alter table t modify nil datetime", mysql.ErrTruncatedWrongValue) @@ -1474,11 +1490,12 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromJsonToOthers(c *C) { tk.MustExec("alter table t modify f64 datetime") // MySQL will get "ERROR 1292 (22007): Incorrect datetime value: '"2020-08-26 17:35:01.123456"' for column 'str' at row 1". tk.MustExec("alter table t modify str datetime") - tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null true false 2020-08-26 17:35:01 2020-11-23 00:00:00 2020-08-26 17:35:01 2020-08-26 17:35:01")) + tk.MustExec("alter table t modify nul datetime") + tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null true false 2020-08-26 17:35:01 2020-11-23 00:00:00 2020-08-26 17:35:01 2020-08-26 17:35:01 ")) // time reset(tk) - tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '200805', '1111', '200805.11', '\"19:35:41\"')") + tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '200805', '1111', '200805.11', '\"19:35:41\"', null)") // MySQL will get "ERROR 1366 (HY000): Incorrect time value: '{"obj": 100}' for column 'obj' at row 1". tk.MustGetErrCode("alter table t modify obj time", mysql.ErrTruncatedWrongValue) // MySQL will get "ERROR 1366 (HY000): Incorrect time value: '[-1, 0, 1]' for column 'arr' at row 11". @@ -1494,11 +1511,12 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromJsonToOthers(c *C) { tk.MustExec("alter table t modify f64 time") // MySQL will get "ERROR 1292 (22007): Incorrect time value: '"19:35:41"' for column 'str' at row 1". tk.MustExec("alter table t modify str time") - tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null true false 20:08:05 00:11:11 20:08:05 19:35:41")) + tk.MustExec("alter table t modify nul time") + tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null true false 20:08:05 00:11:11 20:08:05 19:35:41 ")) // date reset(tk) - tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '20200826173501', '20201123', '20200826173501.123456', '\"2020-08-26 17:35:01.123456\"')") + tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '20200826173501', '20201123', '20200826173501.123456', '\"2020-08-26 17:35:01.123456\"', null)") tk.MustGetErrCode("alter table t modify obj date", mysql.ErrTruncatedWrongValue) tk.MustGetErrCode("alter table t modify arr date", mysql.ErrTruncatedWrongValue) tk.MustGetErrCode("alter table t modify nil date", mysql.ErrTruncatedWrongValue) @@ -1509,11 +1527,12 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromJsonToOthers(c *C) { tk.MustExec("alter table t modify f64 date") // MySQL will get "ERROR 1292 (22007): Incorrect date value: '"2020-08-26 17:35:01.123456"' for column 'str' at row 1". tk.MustExec("alter table t modify str date") - tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null true false 2020-08-26 2020-11-23 2020-08-26 2020-08-26")) + tk.MustExec("alter table t modify nul date") + tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null true false 2020-08-26 2020-11-23 2020-08-26 2020-08-26 ")) // timestamp reset(tk) - tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '20200826173501', '20201123', '20200826173501.123456', '\"2020-08-26 17:35:01.123456\"')") + tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '20200826173501', '20201123', '20200826173501.123456', '\"2020-08-26 17:35:01.123456\"', null)") tk.MustGetErrCode("alter table t modify obj timestamp", mysql.ErrTruncatedWrongValue) tk.MustGetErrCode("alter table t modify arr timestamp", mysql.ErrTruncatedWrongValue) tk.MustGetErrCode("alter table t modify nil timestamp", mysql.ErrTruncatedWrongValue) @@ -1524,17 +1543,18 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromJsonToOthers(c *C) { tk.MustExec("alter table t modify f64 timestamp") // MySQL will get "ERROR 1292 (22007): Incorrect timestamptime value: '"2020-08-26 17:35:01.123456"' for column 'str' at row 1". tk.MustExec("alter table t modify str timestamp") - tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null true false 2020-08-26 17:35:01 2020-11-23 00:00:00 2020-08-26 17:35:01 2020-08-26 17:35:01")) + tk.MustExec("alter table t modify nul timestamp") + tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null true false 2020-08-26 17:35:01 2020-11-23 00:00:00 2020-08-26 17:35:01 2020-08-26 17:35:01 ")) // year reset(tk) - tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '2020', '91', '9', '\"2020\"')") + tk.MustExec("insert into t values ('{\"obj\": 100}', '[-1, 0, 1]', 'null', 'true', 'false', '2020', '91', '9', '\"2020\"', null)") // MySQL will get "ERROR 1366 (HY000): Incorrect integer value: '{"obj": 100}' for column 'obj' at row 1". tk.MustGetErrCode("alter table t modify obj year", mysql.ErrTruncatedWrongValue) // MySQL will get "ERROR 1366 (HY000): Incorrect integer value: '[-1, 0, 1]' for column 'arr' at row 11". tk.MustGetErrCode("alter table t modify arr year", mysql.ErrTruncatedWrongValue) // MySQL will get "ERROR 1366 (HY000): Incorrect integer value: 'null' for column 'nil' at row 1". - tk.MustExec("alter table t modify nil year") + tk.MustGetErrCode("alter table t modify nil year", mysql.ErrTruncatedWrongValue) // MySQL will get "ERROR 1366 (HY000): Incorrect integer value: 'true' for column 't' at row 1". tk.MustExec("alter table t modify t year") // MySQL will get "ERROR 1366 (HY000): Incorrect integer value: 'false' for column 'f' at row 1". @@ -1544,7 +1564,8 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromJsonToOthers(c *C) { tk.MustExec("alter table t modify f64 year") // MySQL will get "ERROR 1366 (HY000): Incorrect integer value: '"2020"' for column 'str' at row 1". tk.MustExec("alter table t modify str year") - tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] 0 2001 0 2020 1991 2009 2020")) + tk.MustExec("alter table t modify nul year") + tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null 2001 0 2020 1991 2009 2020 ")) } func (s *testColumnTypeChangeSuite) TestUpdateDataAfterChangeTimestampToDate(c *C) { diff --git a/executor/write_test.go b/executor/write_test.go index d30c1f19ba8d2..f68e94ccc98e7 100644 --- a/executor/write_test.go +++ b/executor/write_test.go @@ -2446,8 +2446,13 @@ func TestInsertCalculatedValue(t *testing.T) { tk.MustExec("drop table if exists t") tk.MustExec("create table t (a json not null, b int)") + // TODO: MySQL reports 3156 instead of ErrTruncatedWrongValueForField. + tk.MustGetErrCode("insert into t value (a,a->'$')", mysql.ErrTruncatedWrongValueForField) + + tk.MustExec("drop table if exists t") + tk.MustExec("create table t (a json not null, b varchar(10))") tk.MustExec("insert into t value (a,a->'$')") - tk.MustQuery("select * from t").Check(testkit.Rows("null 0")) + tk.MustQuery("select * from t").Check(testkit.Rows("null null")) tk.MustExec("drop table if exists t") tk.MustExec("create table t(a json, b int, c int as (a->'$.a'))") diff --git a/types/convert.go b/types/convert.go index 3a3c22919cc1c..95692e85b7675 100644 --- a/types/convert.go +++ b/types/convert.go @@ -556,8 +556,10 @@ func ConvertJSONToInt(sc *stmtctx.StatementContext, j json.BinaryJSON, unsigned return 0, sc.HandleTruncate(ErrTruncatedWrongVal.GenWithStackByArgs("INTEGER", j.String())) case json.TypeCodeLiteral: switch j.Value[0] { - case json.LiteralNil, json.LiteralFalse: + case json.LiteralFalse: return 0, nil + case json.LiteralNil: + return 0, sc.HandleTruncate(ErrTruncatedWrongVal.GenWithStackByArgs("INTEGER", j.String())) default: return 1, nil } @@ -614,8 +616,10 @@ func ConvertJSONToFloat(sc *stmtctx.StatementContext, j json.BinaryJSON) (float6 return 0, sc.HandleTruncate(ErrTruncatedWrongVal.GenWithStackByArgs("FLOAT", j.String())) case json.TypeCodeLiteral: switch j.Value[0] { - case json.LiteralNil, json.LiteralFalse: + case json.LiteralFalse: return 0, nil + case json.LiteralNil: + return 0, sc.HandleTruncate(ErrTruncatedWrongVal.GenWithStackByArgs("FLOAT", j.String())) default: return 1, nil } @@ -641,8 +645,10 @@ func ConvertJSONToDecimal(sc *stmtctx.StatementContext, j json.BinaryJSON) (*MyD err = ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", j.String()) case json.TypeCodeLiteral: switch j.Value[0] { - case json.LiteralNil, json.LiteralFalse: + case json.LiteralFalse: res = res.FromInt(0) + case json.LiteralNil: + err = ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", j.String()) default: res = res.FromInt(1) } diff --git a/types/convert_test.go b/types/convert_test.go index 2e5b3f1a1d91e..17312f1c2937b 100644 --- a/types/convert_test.go +++ b/types/convert_test.go @@ -991,76 +991,97 @@ func testConvertTimeTimeZone(t *testing.T, sc *stmtctx.StatementContext) { func TestConvertJSONToInt(t *testing.T) { t.Parallel() var tests = []struct { - In string - Out int64 + in string + out int64 + err bool }{ - {`{}`, 0}, - {`[]`, 0}, - {`3`, 3}, - {`-3`, -3}, - {`4.5`, 4}, - {`true`, 1}, - {`false`, 0}, - {`null`, 0}, - {`"hello"`, 0}, - {`"123hello"`, 123}, - {`"1234"`, 1234}, + {in: `{}`, err: true}, + {in: `[]`, err: true}, + {in: `3`, out: 3}, + {in: `-3`, out: -3}, + {in: `4.5`, out: 4}, + {in: `true`, out: 1}, + {in: `false`, out: 0}, + {in: `null`, err: true}, + {in: `"hello"`, err: true}, + {in: `"123hello"`, out: 123, err: true}, + {in: `"1234"`, out: 1234}, } for _, tt := range tests { - j, err := json.ParseBinaryFromString(tt.In) + j, err := json.ParseBinaryFromString(tt.in) require.NoError(t, err) - casted, _ := ConvertJSONToInt64(new(stmtctx.StatementContext), j, false) - require.Equal(t, tt.Out, casted) + casted, err := ConvertJSONToInt64(new(stmtctx.StatementContext), j, false) + if tt.err { + require.Error(t, err, tt) + } else { + require.NoError(t, err, tt) + } + require.Equal(t, tt.out, casted) } } func TestConvertJSONToFloat(t *testing.T) { t.Parallel() var tests = []struct { - In interface{} - Out float64 + in interface{} + out float64 ty json.TypeCode + err bool }{ - {make(map[string]interface{}), 0, json.TypeCodeObject}, - {make([]interface{}, 0), 0, json.TypeCodeArray}, - {int64(3), 3, json.TypeCodeInt64}, - {int64(-3), -3, json.TypeCodeInt64}, - {uint64(1 << 63), 1 << 63, json.TypeCodeUint64}, - {float64(4.5), 4.5, json.TypeCodeFloat64}, - {true, 1, json.TypeCodeLiteral}, - {false, 0, json.TypeCodeLiteral}, - {nil, 0, json.TypeCodeLiteral}, - {"hello", 0, json.TypeCodeString}, - {"123.456hello", 123.456, json.TypeCodeString}, - {"1234", 1234, json.TypeCodeString}, + {in: make(map[string]interface{}), ty: json.TypeCodeObject, err: true}, + {in: make([]interface{}, 0), ty: json.TypeCodeArray, err: true}, + {in: int64(3), out: 3, ty: json.TypeCodeInt64}, + {in: int64(-3), out: -3, ty: json.TypeCodeInt64}, + {in: uint64(1 << 63), out: 1 << 63, ty: json.TypeCodeUint64}, + {in: float64(4.5), out: 4.5, ty: json.TypeCodeFloat64}, + {in: true, out: 1, ty: json.TypeCodeLiteral}, + {in: false, out: 0, ty: json.TypeCodeLiteral}, + {in: nil, ty: json.TypeCodeLiteral, err: true}, + {in: "hello", ty: json.TypeCodeString, err: true}, + {in: "123.456hello", out: 123.456, ty: json.TypeCodeString, err: true}, + {in: "1234", out: 1234, ty: json.TypeCodeString}, } for _, tt := range tests { - j := json.CreateBinary(tt.In) + j := json.CreateBinary(tt.in) require.Equal(t, tt.ty, j.TypeCode) - casted, _ := ConvertJSONToFloat(new(stmtctx.StatementContext), j) - require.Equal(t, tt.Out, casted) + casted, err := ConvertJSONToFloat(new(stmtctx.StatementContext), j) + if tt.err { + require.Error(t, err, tt) + } else { + require.NoError(t, err, tt) + } + require.Equal(t, tt.out, casted) } } func TestConvertJSONToDecimal(t *testing.T) { t.Parallel() var tests = []struct { - In string - Out *MyDecimal + in string + out *MyDecimal + err bool }{ - {`3`, NewDecFromStringForTest("3")}, - {`-3`, NewDecFromStringForTest("-3")}, - {`4.5`, NewDecFromStringForTest("4.5")}, - {`"1234"`, NewDecFromStringForTest("1234")}, - {`"1234567890123456789012345678901234567890123456789012345"`, NewDecFromStringForTest("1234567890123456789012345678901234567890123456789012345")}, + {in: `3`, out: NewDecFromStringForTest("3")}, + {in: `-3`, out: NewDecFromStringForTest("-3")}, + {in: `4.5`, out: NewDecFromStringForTest("4.5")}, + {in: `"1234"`, out: NewDecFromStringForTest("1234")}, + {in: `"1234567890123456789012345678901234567890123456789012345"`, out: NewDecFromStringForTest("1234567890123456789012345678901234567890123456789012345")}, + {in: `true`, out: NewDecFromStringForTest("1")}, + {in: `false`, out: NewDecFromStringForTest("0")}, + {in: `null`, out: NewDecFromStringForTest("0"), err: true}, } for _, tt := range tests { - j, err := json.ParseBinaryFromString(tt.In) + j, err := json.ParseBinaryFromString(tt.in) require.NoError(t, err) casted, err := ConvertJSONToDecimal(new(stmtctx.StatementContext), j) - require.NoErrorf(t, err, "input: %v, casted: %v, out: %v, json: %#v", tt.In, casted, tt.Out, j) - require.Equalf(t, 0, casted.Compare(tt.Out), "input: %v, casted: %v, out: %v, json: %#v", tt.In, casted, tt.Out, j) + errMsg := fmt.Sprintf("input: %v, casted: %v, out: %v, json: %#v", tt.in, casted, tt.out, j) + if tt.err { + require.Error(t, err, errMsg) + } else { + require.NoError(t, err, errMsg) + } + require.Equalf(t, 0, casted.Compare(tt.out), "input: %v, casted: %v, out: %v, json: %#v", tt.in, casted, tt.out, j) } }