diff --git a/executor/insert_test.go b/executor/insert_test.go index 23fd0ba99cba8..43a24a43ca1ff 100644 --- a/executor/insert_test.go +++ b/executor/insert_test.go @@ -493,6 +493,38 @@ 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.Error(), Equals, `[types:8033]invalid year`) + + _, err = tk.Exec(`insert ignore into t1 values(1900), (2156), ("1900"), ("2156");`) + c.Assert(err, IsNil) + tk.MustQuery("show warnings;").Check(testutil.RowsWithSep("|", + "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`)) + + 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|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`)) +} + func (s *testSuiteP1) TestAllowInvalidDates(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec(`use test`) diff --git a/executor/update_test.go b/executor/update_test.go index 683fe7455574a..677016714d393 100644 --- a/executor/update_test.go +++ b/executor/update_test.go @@ -27,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" ) @@ -529,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(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("|", + "Warning|8033|invalid year", + "Warning|8033|invalid year", + )) + 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|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 69068c492e7d8..6a92ba7c0e8c2 100644 --- a/table/column.go +++ b/table/column.go @@ -305,6 +305,8 @@ func CastValue(ctx sessionctx.Context, val types.Datum, col *model.ColumnInfo, r if innCasted, exit, innErr := handleZeroDatetime(ctx, col, casted, str, types.ErrWrongValue.Equal(err)); exit { return innCasted, innErr } + } else if (sc.InInsertStmt || sc.InUpdateStmt) && types.ErrInvalidYear.Equal(err) { + casted.SetInt64(0) } err = sc.HandleTruncate(err) diff --git a/table/column_test.go b/table/column_test.go index e4de47e913e20..a070b27ff6557 100644 --- a/table/column_test.go +++ b/table/column_test.go @@ -309,6 +309,16 @@ func TestCastValue(t *testing.T) { colInfoS.Charset = charset.CharsetASCII _, err = CastValue(ctx, types.NewDatum([]byte{0x32, 0xf0}), &colInfoS, false, true) require.NoError(t, err) + + colInfoY := model.ColumnInfo{ + FieldType: *types.NewFieldType(mysql.TypeYear), + State: model.StatePublic, + } + _, err = CastValue(ctx, types.NewDatum("2156"), &colInfoY, false, false) + require.Error(t, err) + + _, err = CastValue(ctx, types.NewDatum("2155"), &colInfoY, false, false) + require.NoError(t, err) } func TestGetDefaultValue(t *testing.T) {