From c8d8900dac317104aa72f3a929e5048d1742a092 Mon Sep 17 00:00:00 2001 From: b41sh Date: Sat, 10 Jul 2021 08:09:48 +0800 Subject: [PATCH 1/6] fix invalid year --- executor/insert_test.go | 5 +++++ table/column.go | 2 ++ 2 files changed, 7 insertions(+) diff --git a/executor/insert_test.go b/executor/insert_test.go index 166972dd268cb..23055c7c0387a 100644 --- a/executor/insert_test.go +++ b/executor/insert_test.go @@ -336,6 +336,11 @@ func (s *testSuite3) TestInsertWrongValueForField(c *C) { tk.MustExec(`create table t (a year);`) _, err = tk.Exec(`insert into t values(2156);`) c.Assert(err.Error(), Equals, `[types:8033]invalid year`) + + _, err = tk.Exec(`insert ignore into t values(1900);`) + c.Assert(err, IsNil) + tk.MustQuery("show warnings;").Check(testutil.RowsWithSep("|", "Warning|8033|invalid year")) + tk.MustQuery(`select * from t;`).Check(testkit.Rows(`0000`)) } func (s *testSuite3) TestInsertValueForCastDecimalField(c *C) { diff --git a/table/column.go b/table/column.go index 59e499e190231..7bbd9d50e010a 100644 --- a/table/column.go +++ b/table/column.go @@ -265,6 +265,8 @@ func CastValue(ctx sessionctx.Context, val types.Datum, col *model.ColumnInfo, r if innCasted, exit, innErr := handleZeroDatetime(ctx, col, casted, val.GetString(), types.ErrWrongValue.Equal(err)); exit { return innCasted, innErr } + } else if (sc.InInsertStmt || sc.InUpdateStmt) && err != nil && col.FieldType.Tp == mysql.TypeYear { + casted.SetInt64(0) } err = sc.HandleTruncate(err) From debf16db139097a9985a251f0eee9ce1ec24d914 Mon Sep 17 00:00:00 2001 From: b41sh Date: Sat, 10 Jul 2021 17:31:00 +0800 Subject: [PATCH 2/6] fix test --- executor/insert_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/executor/insert_test.go b/executor/insert_test.go index 23055c7c0387a..8a72fd17df4bd 100644 --- a/executor/insert_test.go +++ b/executor/insert_test.go @@ -340,7 +340,7 @@ func (s *testSuite3) TestInsertWrongValueForField(c *C) { _, err = tk.Exec(`insert ignore into t values(1900);`) c.Assert(err, IsNil) tk.MustQuery("show warnings;").Check(testutil.RowsWithSep("|", "Warning|8033|invalid year")) - tk.MustQuery(`select * from t;`).Check(testkit.Rows(`0000`)) + tk.MustQuery(`select * from t;`).Check(testkit.Rows(`0`)) } func (s *testSuite3) TestInsertValueForCastDecimalField(c *C) { From e344fad4e83d846db19f85d26dbc7661ae8da8f0 Mon Sep 17 00:00:00 2001 From: b41sh Date: Mon, 12 Jul 2021 11:21:14 +0800 Subject: [PATCH 3/6] optimize --- table/column.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/table/column.go b/table/column.go index 7bbd9d50e010a..525b8232c6712 100644 --- a/table/column.go +++ b/table/column.go @@ -265,7 +265,7 @@ func CastValue(ctx sessionctx.Context, val types.Datum, col *model.ColumnInfo, r if innCasted, exit, innErr := handleZeroDatetime(ctx, col, casted, val.GetString(), types.ErrWrongValue.Equal(err)); exit { return innCasted, innErr } - } else if (sc.InInsertStmt || sc.InUpdateStmt) && err != nil && col.FieldType.Tp == mysql.TypeYear { + } else if (sc.InInsertStmt || sc.InUpdateStmt) && types.ErrInvalidYear.Equal(err) { casted.SetInt64(0) } From 19582943e85b983ae3dc84e9f49f970c6a3c3da6 Mon Sep 17 00:00:00 2001 From: b41sh Date: Thu, 15 Jul 2021 20:46:14 +0800 Subject: [PATCH 4/6] add test --- executor/insert_common.go | 2 +- executor/insert_test.go | 40 +++++++++++++++++++++++++++++++++------ executor/update.go | 12 +++++++++--- executor/update_test.go | 32 +++++++++++++++++++++++++++++++ table/column.go | 6 +++++- table/column_test.go | 10 ++++++++++ 6 files changed, 91 insertions(+), 11 deletions(-) diff --git a/executor/insert_common.go b/executor/insert_common.go index 70345de2058d3..7c88223caa38f 100644 --- a/executor/insert_common.go +++ b/executor/insert_common.go @@ -297,7 +297,7 @@ func (e *InsertValues) handleErr(col *table.Column, val *types.Datum, rowIdx int if types.ErrDataTooLong.Equal(err) { err = resetErrDataTooLong(colName, rowIdx+1, err) - } else if types.ErrOverflow.Equal(err) { + } else if types.ErrOverflow.Equal(err) || types.ErrInvalidYear.Equal(err) { err = types.ErrWarnDataOutOfRange.GenWithStackByArgs(colName, rowIdx+1) } else if types.ErrTruncated.Equal(err) { err = types.ErrTruncated.GenWithStackByArgs(colName, rowIdx+1) diff --git a/executor/insert_test.go b/executor/insert_test.go index 8a72fd17df4bd..77d825ce7248a 100644 --- a/executor/insert_test.go +++ b/executor/insert_test.go @@ -335,12 +335,7 @@ func (s *testSuite3) TestInsertWrongValueForField(c *C) { tk.MustExec(`drop table if exists t;`) tk.MustExec(`create table t (a year);`) _, err = tk.Exec(`insert into t values(2156);`) - c.Assert(err.Error(), Equals, `[types:8033]invalid year`) - - _, err = tk.Exec(`insert ignore into t values(1900);`) - c.Assert(err, IsNil) - tk.MustQuery("show warnings;").Check(testutil.RowsWithSep("|", "Warning|8033|invalid year")) - tk.MustQuery(`select * from t;`).Check(testkit.Rows(`0`)) + c.Assert(err.Error(), Equals, `[types:1264]Out of range value for column 'a' at row 1`) } func (s *testSuite3) TestInsertValueForCastDecimalField(c *C) { @@ -485,6 +480,39 @@ func (s *testSuite3) TestInsertZeroYear(c *C) { )) } +func (s *testSuite3) TestInsertInvalidYear(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec(`drop table if exists t1;`) + tk.MustExec(`create table t1(y YEAR);`) + + tk.MustExec(`set sql_mode = 'STRICT_TRANS_TABLES';`) + _, err := tk.Exec(`insert into t1 values(1900), (2156), ("1900"), ("2156");`) + c.Assert(err, NotNil) + c.Assert(strings.Contains(err.Error(), "Out of range value for column 'y' at row 1"), IsTrue, Commentf("%v", err)) + + _, err = tk.Exec(`insert ignore into t1 values(1900), (2156), ("1900"), ("2156");`) + c.Assert(err, IsNil) + tk.MustQuery("show warnings;").Check(testutil.RowsWithSep("|", + "Warning|1264|Out of range value for column 'y' at row 1", + "Warning|1264|Out of range value for column 'y' at row 2", + "Warning|1264|Out of range value for column 'y' at row 3", + "Warning|1264|Out of range value for column 'y' at row 4", + )) + tk.MustQuery(`select * from t1;`).Check(testkit.Rows(`0`, `0`, `0`, `0`)) + + tk.MustExec(`set sql_mode = '';`) + _, err = tk.Exec(`insert into t1 values(1900), (2156), ("1900"), ("2156");`) + c.Assert(err, IsNil) + tk.MustQuery("show warnings;").Check(testutil.RowsWithSep("|", + "Warning|1264|Out of range value for column 'y' at row 1", + "Warning|1264|Out of range value for column 'y' at row 2", + "Warning|1264|Out of range value for column 'y' at row 3", + "Warning|1264|Out of range value for column 'y' at row 4", + )) + tk.MustQuery(`select * from t1;`).Check(testkit.Rows(`0`, `0`, `0`, `0`, `0`, `0`, `0`, `0`)) +} + func (s *testSuiteP1) TestAllowInvalidDates(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec(`use test`) diff --git a/executor/update.go b/executor/update.go index 6bf07e5d21b92..f506368aa7d07 100644 --- a/executor/update.go +++ b/executor/update.go @@ -314,11 +314,17 @@ func (e *UpdateExec) handleErr(colName model.CIStr, rowIdx int, err error) error } if types.ErrDataTooLong.Equal(err) { - return resetErrDataTooLong(colName.O, rowIdx+1, err) + err = resetErrDataTooLong(colName.O, rowIdx+1, err) } - if types.ErrOverflow.Equal(err) { - return types.ErrWarnDataOutOfRange.GenWithStackByArgs(colName.O, rowIdx+1) + if types.ErrOverflow.Equal(err) || types.ErrInvalidYear.Equal(err) { + err = types.ErrWarnDataOutOfRange.GenWithStackByArgs(colName.O, rowIdx+1) + } + + if e.ctx.GetSessionVars().StmtCtx.DupKeyAsWarning { + sc := e.ctx.GetSessionVars().StmtCtx + sc.AppendWarning(err) + err = nil } return err diff --git a/executor/update_test.go b/executor/update_test.go index 49a980ec01676..5a573cc6037ce 100644 --- a/executor/update_test.go +++ b/executor/update_test.go @@ -16,6 +16,7 @@ package executor_test import ( "flag" "fmt" + "strings" . "github.com/pingcap/check" "github.com/pingcap/parser" @@ -26,6 +27,7 @@ import ( "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/store/mockstore" "github.com/pingcap/tidb/util/testkit" + "github.com/pingcap/tidb/util/testutil" "github.com/tikv/client-go/v2/testutils" ) @@ -528,3 +530,33 @@ func (s *testSuite11) TestIssue23553(c *C) { tk.MustExec(`insert into tt values('1',0),('1',0),('1',0)`) tk.MustExec(`update tt a inner join (select m0 from tt where status!=1 group by m0 having count(*)>1) b on a.m0=b.m0 set a.status=1`) } + +func (s *testSuite3) TestUpdateInvalidYear(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec(`drop table if exists t1;`) + tk.MustExec(`create table t1(y YEAR);`) + + _, err := tk.Exec(`insert into t1 values(1901), (2155);`) + c.Assert(err, IsNil) + + tk.MustExec(`set sql_mode = 'STRICT_TRANS_TABLES';`) + _, err = tk.Exec(`update t1 set y=1900;`) + c.Assert(strings.Contains(err.Error(), "Out of range value for column 'y' at row 1"), IsTrue, Commentf("%v", err)) + _, err = tk.Exec(`update ignore t1 set y=1900;`) + c.Assert(err, IsNil) + tk.MustQuery("show warnings;").Check(testutil.RowsWithSep("|", + "Warning|1264|Out of range value for column 'y' at row 1", + "Warning|1264|Out of range value for column 'y' at row 1", + )) + tk.MustQuery(`select * from t1;`).Check(testkit.Rows(`0`, `0`)) + + tk.MustExec(`set sql_mode = '';`) + _, err = tk.Exec(`update ignore t1 set y=1900;`) + c.Assert(err, IsNil) + tk.MustQuery("show warnings;").Check(testutil.RowsWithSep("|", + "Warning|1264|Out of range value for column 'y' at row 1", + "Warning|1264|Out of range value for column 'y' at row 1", + )) + tk.MustQuery(`select * from t1;`).Check(testkit.Rows(`0`, `0`)) +} diff --git a/table/column.go b/table/column.go index 525b8232c6712..1144df6af0aa5 100644 --- a/table/column.go +++ b/table/column.go @@ -253,6 +253,7 @@ func CastValue(ctx sessionctx.Context, val types.Datum, col *model.ColumnInfo, r if returnErr && err != nil { return casted, err } + ignoreTruncate := false if err != nil && types.ErrTruncated.Equal(err) && col.Tp != mysql.TypeSet && col.Tp != mysql.TypeEnum { str, err1 := val.ToString() if err1 != nil { @@ -267,9 +268,12 @@ func CastValue(ctx sessionctx.Context, val types.Datum, col *model.ColumnInfo, r } } else if (sc.InInsertStmt || sc.InUpdateStmt) && types.ErrInvalidYear.Equal(err) { casted.SetInt64(0) + ignoreTruncate = true } - err = sc.HandleTruncate(err) + if !ignoreTruncate { + err = sc.HandleTruncate(err) + } if forceIgnoreTruncate { err = nil diff --git a/table/column_test.go b/table/column_test.go index 5f1646c807f6d..edb186f25bd47 100644 --- a/table/column_test.go +++ b/table/column_test.go @@ -301,6 +301,16 @@ func (t *testTableSuite) TestCastValue(c *C) { colInfoS.Charset = charset.CharsetASCII _, err = CastValue(ctx, types.NewDatum([]byte{0x32, 0xf0}), &colInfoS, false, true) c.Assert(err, IsNil) + + colInfoY := model.ColumnInfo{ + FieldType: *types.NewFieldType(mysql.TypeYear), + State: model.StatePublic, + } + _, err = CastValue(ctx, types.NewDatum("2156"), &colInfoY, false, false) + c.Assert(err, NotNil) + + _, err = CastValue(ctx, types.NewDatum("2155"), &colInfoY, false, false) + c.Assert(err, IsNil) } func (t *testTableSuite) TestGetDefaultValue(c *C) { From ee078760824bc31f75a6af66fea7106f4c78a55d Mon Sep 17 00:00:00 2001 From: b41sh Date: Fri, 16 Jul 2021 00:27:00 +0800 Subject: [PATCH 5/6] fix test --- executor/insert_test.go | 16 ++++++++-------- executor/update.go | 2 +- executor/update_test.go | 8 ++++---- table/column.go | 6 +----- 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/executor/insert_test.go b/executor/insert_test.go index 77d825ce7248a..63a99ad30fcc6 100644 --- a/executor/insert_test.go +++ b/executor/insert_test.go @@ -494,10 +494,10 @@ func (s *testSuite3) TestInsertInvalidYear(c *C) { _, err = tk.Exec(`insert ignore into t1 values(1900), (2156), ("1900"), ("2156");`) c.Assert(err, IsNil) tk.MustQuery("show warnings;").Check(testutil.RowsWithSep("|", - "Warning|1264|Out of range value for column 'y' at row 1", - "Warning|1264|Out of range value for column 'y' at row 2", - "Warning|1264|Out of range value for column 'y' at row 3", - "Warning|1264|Out of range value for column 'y' at row 4", + "Warning|8033|invalid year", + "Warning|8033|invalid year", + "Warning|8033|invalid year", + "Warning|8033|invalid year", )) tk.MustQuery(`select * from t1;`).Check(testkit.Rows(`0`, `0`, `0`, `0`)) @@ -505,10 +505,10 @@ func (s *testSuite3) TestInsertInvalidYear(c *C) { _, err = tk.Exec(`insert into t1 values(1900), (2156), ("1900"), ("2156");`) c.Assert(err, IsNil) tk.MustQuery("show warnings;").Check(testutil.RowsWithSep("|", - "Warning|1264|Out of range value for column 'y' at row 1", - "Warning|1264|Out of range value for column 'y' at row 2", - "Warning|1264|Out of range value for column 'y' at row 3", - "Warning|1264|Out of range value for column 'y' at row 4", + "Warning|8033|invalid year", + "Warning|8033|invalid year", + "Warning|8033|invalid year", + "Warning|8033|invalid year", )) tk.MustQuery(`select * from t1;`).Check(testkit.Rows(`0`, `0`, `0`, `0`, `0`, `0`, `0`, `0`)) } diff --git a/executor/update.go b/executor/update.go index f506368aa7d07..1ac3c73fb754e 100644 --- a/executor/update.go +++ b/executor/update.go @@ -321,7 +321,7 @@ func (e *UpdateExec) handleErr(colName model.CIStr, rowIdx int, err error) error err = types.ErrWarnDataOutOfRange.GenWithStackByArgs(colName.O, rowIdx+1) } - if e.ctx.GetSessionVars().StmtCtx.DupKeyAsWarning { + if e.ctx.GetSessionVars().StmtCtx.TruncateAsWarning { sc := e.ctx.GetSessionVars().StmtCtx sc.AppendWarning(err) err = nil diff --git a/executor/update_test.go b/executor/update_test.go index 5a573cc6037ce..19a429b4d8b3d 100644 --- a/executor/update_test.go +++ b/executor/update_test.go @@ -546,8 +546,8 @@ func (s *testSuite3) TestUpdateInvalidYear(c *C) { _, err = tk.Exec(`update ignore t1 set y=1900;`) c.Assert(err, IsNil) tk.MustQuery("show warnings;").Check(testutil.RowsWithSep("|", - "Warning|1264|Out of range value for column 'y' at row 1", - "Warning|1264|Out of range value for column 'y' at row 1", + "Warning|8033|invalid year", + "Warning|8033|invalid year", )) tk.MustQuery(`select * from t1;`).Check(testkit.Rows(`0`, `0`)) @@ -555,8 +555,8 @@ func (s *testSuite3) TestUpdateInvalidYear(c *C) { _, err = tk.Exec(`update ignore t1 set y=1900;`) c.Assert(err, IsNil) tk.MustQuery("show warnings;").Check(testutil.RowsWithSep("|", - "Warning|1264|Out of range value for column 'y' at row 1", - "Warning|1264|Out of range value for column 'y' at row 1", + "Warning|8033|invalid year", + "Warning|8033|invalid year", )) tk.MustQuery(`select * from t1;`).Check(testkit.Rows(`0`, `0`)) } diff --git a/table/column.go b/table/column.go index 1144df6af0aa5..525b8232c6712 100644 --- a/table/column.go +++ b/table/column.go @@ -253,7 +253,6 @@ func CastValue(ctx sessionctx.Context, val types.Datum, col *model.ColumnInfo, r if returnErr && err != nil { return casted, err } - ignoreTruncate := false if err != nil && types.ErrTruncated.Equal(err) && col.Tp != mysql.TypeSet && col.Tp != mysql.TypeEnum { str, err1 := val.ToString() if err1 != nil { @@ -268,12 +267,9 @@ func CastValue(ctx sessionctx.Context, val types.Datum, col *model.ColumnInfo, r } } else if (sc.InInsertStmt || sc.InUpdateStmt) && types.ErrInvalidYear.Equal(err) { casted.SetInt64(0) - ignoreTruncate = true } - if !ignoreTruncate { - err = sc.HandleTruncate(err) - } + err = sc.HandleTruncate(err) if forceIgnoreTruncate { err = nil From c0107b2ea600e2993dcdb3999e2e3f92d27d3fbb Mon Sep 17 00:00:00 2001 From: b41sh Date: Fri, 16 Jul 2021 11:23:35 +0800 Subject: [PATCH 6/6] fix test --- executor/insert_common.go | 2 +- executor/insert_test.go | 5 ++--- executor/update.go | 12 +++--------- executor/update_test.go | 3 +-- 4 files changed, 7 insertions(+), 15 deletions(-) diff --git a/executor/insert_common.go b/executor/insert_common.go index 7c88223caa38f..70345de2058d3 100644 --- a/executor/insert_common.go +++ b/executor/insert_common.go @@ -297,7 +297,7 @@ func (e *InsertValues) handleErr(col *table.Column, val *types.Datum, rowIdx int if types.ErrDataTooLong.Equal(err) { err = resetErrDataTooLong(colName, rowIdx+1, err) - } else if types.ErrOverflow.Equal(err) || types.ErrInvalidYear.Equal(err) { + } else if types.ErrOverflow.Equal(err) { err = types.ErrWarnDataOutOfRange.GenWithStackByArgs(colName, rowIdx+1) } else if types.ErrTruncated.Equal(err) { err = types.ErrTruncated.GenWithStackByArgs(colName, rowIdx+1) diff --git a/executor/insert_test.go b/executor/insert_test.go index 63a99ad30fcc6..0ceb148b246af 100644 --- a/executor/insert_test.go +++ b/executor/insert_test.go @@ -335,7 +335,7 @@ func (s *testSuite3) TestInsertWrongValueForField(c *C) { tk.MustExec(`drop table if exists t;`) tk.MustExec(`create table t (a year);`) _, err = tk.Exec(`insert into t values(2156);`) - c.Assert(err.Error(), Equals, `[types:1264]Out of range value for column 'a' at row 1`) + c.Assert(err.Error(), Equals, `[types:8033]invalid year`) } func (s *testSuite3) TestInsertValueForCastDecimalField(c *C) { @@ -488,8 +488,7 @@ func (s *testSuite3) TestInsertInvalidYear(c *C) { tk.MustExec(`set sql_mode = 'STRICT_TRANS_TABLES';`) _, err := tk.Exec(`insert into t1 values(1900), (2156), ("1900"), ("2156");`) - c.Assert(err, NotNil) - c.Assert(strings.Contains(err.Error(), "Out of range value for column 'y' at row 1"), IsTrue, Commentf("%v", err)) + c.Assert(err.Error(), Equals, `[types:8033]invalid year`) _, err = tk.Exec(`insert ignore into t1 values(1900), (2156), ("1900"), ("2156");`) c.Assert(err, IsNil) diff --git a/executor/update.go b/executor/update.go index 1ac3c73fb754e..6bf07e5d21b92 100644 --- a/executor/update.go +++ b/executor/update.go @@ -314,17 +314,11 @@ func (e *UpdateExec) handleErr(colName model.CIStr, rowIdx int, err error) error } if types.ErrDataTooLong.Equal(err) { - err = resetErrDataTooLong(colName.O, rowIdx+1, err) + return resetErrDataTooLong(colName.O, rowIdx+1, err) } - if types.ErrOverflow.Equal(err) || types.ErrInvalidYear.Equal(err) { - err = types.ErrWarnDataOutOfRange.GenWithStackByArgs(colName.O, rowIdx+1) - } - - if e.ctx.GetSessionVars().StmtCtx.TruncateAsWarning { - sc := e.ctx.GetSessionVars().StmtCtx - sc.AppendWarning(err) - err = nil + if types.ErrOverflow.Equal(err) { + return types.ErrWarnDataOutOfRange.GenWithStackByArgs(colName.O, rowIdx+1) } return err diff --git a/executor/update_test.go b/executor/update_test.go index 19a429b4d8b3d..f13b521ccc910 100644 --- a/executor/update_test.go +++ b/executor/update_test.go @@ -16,7 +16,6 @@ package executor_test import ( "flag" "fmt" - "strings" . "github.com/pingcap/check" "github.com/pingcap/parser" @@ -542,7 +541,7 @@ func (s *testSuite3) TestUpdateInvalidYear(c *C) { tk.MustExec(`set sql_mode = 'STRICT_TRANS_TABLES';`) _, err = tk.Exec(`update t1 set y=1900;`) - c.Assert(strings.Contains(err.Error(), "Out of range value for column 'y' at row 1"), IsTrue, Commentf("%v", err)) + c.Assert(err.Error(), Equals, `[types:8033]invalid year`) _, err = tk.Exec(`update ignore t1 set y=1900;`) c.Assert(err, IsNil) tk.MustQuery("show warnings;").Check(testutil.RowsWithSep("|",