Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

executor: fix insert ignore invalid year #26097

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions executor/insert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,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",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This warning is different with MySQL-8.0.23, MySQL-5.7.33, TiDB-5.7.25-TiDB-v4.0.11. They all will produce this error (1264, "Out of range value for column 'y' at row 1").

show warnings;
+---------+------+--------------------------------------------+
| Level   | Code | Message                                    |
+---------+------+--------------------------------------------+
| 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 |
+---------+------+--------------------------------------------+

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed this bug, but if I modified it, there will be some test cases that fail to pass, we'd better raise a new issue separately to deal with this problem.

Copy link
Member

@mmyj mmyj Jul 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. Could you please help to create a bug issue and add a comment about it in this PR?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

"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`)
Expand Down
31 changes: 31 additions & 0 deletions executor/update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,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"
)

Expand Down Expand Up @@ -528,3 +529,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`))
}
2 changes: 2 additions & 0 deletions table/column.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) && types.ErrInvalidYear.Equal(err) {
casted.SetInt64(0)
}

err = sc.HandleTruncate(err)
Expand Down
10 changes: 10 additions & 0 deletions table/column_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down