From 49dfc6bbca485559b243d2859516cef9f4b4803c Mon Sep 17 00:00:00 2001 From: Dousir9 <736191200@qq.com> Date: Mon, 12 Dec 2022 23:11:28 +0800 Subject: [PATCH 01/14] remove unnecessary checks during inserts Signed-off-by: Dousir9 <736191200@qq.com> --- executor/insert_common.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/executor/insert_common.go b/executor/insert_common.go index dbd4a5ae264cd..b6ef7ea1f34ce 100644 --- a/executor/insert_common.go +++ b/executor/insert_common.go @@ -744,11 +744,6 @@ func setDatumAutoIDAndCast(ctx sessionctx.Context, d *types.Datum, id int64, col d.SetAutoID(id, col.GetFlag()) var err error *d, err = table.CastValue(ctx, *d, col.ToInfo(), false, false) - if err == nil && d.GetInt64() < id { - // Auto ID is out of range, the truncated ID is possible to duplicate with an existing ID. - // To prevent updating unrelated rows in the REPLACE statement, it is better to throw an error. - return autoid.ErrAutoincReadFailed - } return err } From e9d0a6b25b5aaa328b3f0392e504bc577a8170b1 Mon Sep 17 00:00:00 2001 From: Dousir9 <736191200@qq.com> Date: Tue, 13 Dec 2022 11:25:11 +0800 Subject: [PATCH 02/14] add test case --- executor/write_test.go | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/executor/write_test.go b/executor/write_test.go index 32aa261c5518d..af17f47690cb5 100644 --- a/executor/write_test.go +++ b/executor/write_test.go @@ -592,6 +592,35 @@ commit;` tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1526 Table has no partition for value 3")) } +func TestIssue39847(t *testing.T) { + store := testkit.CreateMockStore(t) + var cfg kv.InjectionConfig + tk := testkit.NewTestKit(t, kv.NewInjectedStore(store, &cfg)) + tk.MustExec("use test") + testSQL := `drop table if exists t; + create table t (id smallint auto_increment primary key);` + tk.MustExec(testSQL) + + testSQL = `alter table t add column c1 int default 1;` + tk.MustExec(testSQL) + + testSQL = `insert ignore into t(id) values (194626268);` + tk.MustExec(testSQL) + require.Empty(t, tk.Session().LastMessage()) + + r := tk.MustQuery("select * from t;") + rowStr := fmt.Sprintf("%v %v", "32767", "1") + r.Check(testkit.Rows(rowStr)) + + tk.MustExec("insert ignore into t(id) values ('*') on duplicate key update c1 = 2;") + require.Equal(t, int64(2), int64(tk.Session().AffectedRows())) + require.Empty(t, tk.Session().LastMessage()) + + r = tk.MustQuery("select * from t;") + rowStr = fmt.Sprintf("%v %v", "32767", "2") + r.Check(testkit.Rows(rowStr)) +} + func TestInsertOnDup(t *testing.T) { store := testkit.CreateMockStore(t) var cfg kv.InjectionConfig From 9e820bbbbe4294f2beb9e339a82a3e3e512fc056 Mon Sep 17 00:00:00 2001 From: Dousir9 <736191200@qq.com> Date: Tue, 13 Dec 2022 17:33:51 +0800 Subject: [PATCH 03/14] add IgnoreTruncate and TruncateAsWarning support for autoid.ErrAutoincReadFailed --- executor/insert_common.go | 13 +++++++++++++ executor/insert_test.go | 3 ++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/executor/insert_common.go b/executor/insert_common.go index b6ef7ea1f34ce..eefbbb6d3e13c 100644 --- a/executor/insert_common.go +++ b/executor/insert_common.go @@ -744,6 +744,19 @@ func setDatumAutoIDAndCast(ctx sessionctx.Context, d *types.Datum, id int64, col d.SetAutoID(id, col.GetFlag()) var err error *d, err = table.CastValue(ctx, *d, col.ToInfo(), false, false) + if err == nil && d.GetInt64() < id { + // Auto ID is out of range, the truncated ID is possible to duplicate with an existing ID. + // To prevent updating unrelated rows in the REPLACE statement, it is better to throw an error. + sc := ctx.GetSessionVars().StmtCtx + if sc.IgnoreTruncate { + return nil + } + if sc.TruncateAsWarning { + sc.AppendWarning(autoid.ErrAutoincReadFailed) + return nil + } + return autoid.ErrAutoincReadFailed + } return err } diff --git a/executor/insert_test.go b/executor/insert_test.go index b55c3a63765e3..6ec85b44762fe 100644 --- a/executor/insert_test.go +++ b/executor/insert_test.go @@ -405,7 +405,8 @@ func TestInsertWrongValueForField(t *testing.T) { tk.MustQuery(`SHOW WARNINGS`).Check(testkit.Rows( `Warning 1366 Incorrect smallint value: '*' for column 'c0' at row 1`, `Warning 1690 constant 32768 overflows smallint`, - `Warning 1467 Failed to read auto-increment value from storage engine`)) + `Warning 1467 Failed to read auto-increment value from storage engine`, + `Warning 1062 Duplicate entry '32767' for key 't0.PRIMARY'`)) } func TestInsertValueForCastDecimalField(t *testing.T) { From be866ccc6642d78f729b14e47410edfd7eaf8b23 Mon Sep 17 00:00:00 2001 From: Dousir9 <736191200@qq.com> Date: Tue, 13 Dec 2022 23:44:14 +0800 Subject: [PATCH 04/14] Handling the special case of --- executor/insert_common.go | 11 ++++------- executor/insert_test.go | 1 - 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/executor/insert_common.go b/executor/insert_common.go index eefbbb6d3e13c..e37696398e960 100644 --- a/executor/insert_common.go +++ b/executor/insert_common.go @@ -32,6 +32,7 @@ import ( "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" + "github.com/pingcap/tidb/planner/core" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/sessiontxn" @@ -748,14 +749,10 @@ func setDatumAutoIDAndCast(ctx sessionctx.Context, d *types.Datum, id int64, col // Auto ID is out of range, the truncated ID is possible to duplicate with an existing ID. // To prevent updating unrelated rows in the REPLACE statement, it is better to throw an error. sc := ctx.GetSessionVars().StmtCtx - if sc.IgnoreTruncate { - return nil + var insertPlan *core.Insert = sc.GetPlan().(*core.Insert) + if insertPlan.IsReplace { + return autoid.ErrAutoincReadFailed } - if sc.TruncateAsWarning { - sc.AppendWarning(autoid.ErrAutoincReadFailed) - return nil - } - return autoid.ErrAutoincReadFailed } return err } diff --git a/executor/insert_test.go b/executor/insert_test.go index 6ec85b44762fe..7578438869bae 100644 --- a/executor/insert_test.go +++ b/executor/insert_test.go @@ -405,7 +405,6 @@ func TestInsertWrongValueForField(t *testing.T) { tk.MustQuery(`SHOW WARNINGS`).Check(testkit.Rows( `Warning 1366 Incorrect smallint value: '*' for column 'c0' at row 1`, `Warning 1690 constant 32768 overflows smallint`, - `Warning 1467 Failed to read auto-increment value from storage engine`, `Warning 1062 Duplicate entry '32767' for key 't0.PRIMARY'`)) } From 35417cf471bf60f207939b10ae0e931464fce92d Mon Sep 17 00:00:00 2001 From: Dousir9 <736191200@qq.com> Date: Tue, 20 Dec 2022 10:50:12 +0800 Subject: [PATCH 05/14] fixed a bug that returned an incorrect err --- executor/insert_common.go | 5 +++-- executor/insert_test.go | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/executor/insert_common.go b/executor/insert_common.go index e37696398e960..8cefae4f60060 100644 --- a/executor/insert_common.go +++ b/executor/insert_common.go @@ -750,9 +750,10 @@ func setDatumAutoIDAndCast(ctx sessionctx.Context, d *types.Datum, id int64, col // To prevent updating unrelated rows in the REPLACE statement, it is better to throw an error. sc := ctx.GetSessionVars().StmtCtx var insertPlan *core.Insert = sc.GetPlan().(*core.Insert) - if insertPlan.IsReplace { - return autoid.ErrAutoincReadFailed + if sc.TruncateAsWarning && len(insertPlan.OnDuplicate) > 0 { + return err } + return autoid.ErrAutoincReadFailed } return err } diff --git a/executor/insert_test.go b/executor/insert_test.go index 7578438869bae..b55c3a63765e3 100644 --- a/executor/insert_test.go +++ b/executor/insert_test.go @@ -405,7 +405,7 @@ func TestInsertWrongValueForField(t *testing.T) { tk.MustQuery(`SHOW WARNINGS`).Check(testkit.Rows( `Warning 1366 Incorrect smallint value: '*' for column 'c0' at row 1`, `Warning 1690 constant 32768 overflows smallint`, - `Warning 1062 Duplicate entry '32767' for key 't0.PRIMARY'`)) + `Warning 1467 Failed to read auto-increment value from storage engine`)) } func TestInsertValueForCastDecimalField(t *testing.T) { From a2bb7b1da5ffea48dedb0c4d354b9a5ebf8552a4 Mon Sep 17 00:00:00 2001 From: Dousir9 <736191200@qq.com> Date: Tue, 20 Dec 2022 13:16:30 +0800 Subject: [PATCH 06/14] test --- executor/insert_common.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/executor/insert_common.go b/executor/insert_common.go index 8cefae4f60060..9f40a15b4459d 100644 --- a/executor/insert_common.go +++ b/executor/insert_common.go @@ -32,7 +32,6 @@ import ( "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" - "github.com/pingcap/tidb/planner/core" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/sessiontxn" @@ -748,11 +747,11 @@ func setDatumAutoIDAndCast(ctx sessionctx.Context, d *types.Datum, id int64, col if err == nil && d.GetInt64() < id { // Auto ID is out of range, the truncated ID is possible to duplicate with an existing ID. // To prevent updating unrelated rows in the REPLACE statement, it is better to throw an error. - sc := ctx.GetSessionVars().StmtCtx - var insertPlan *core.Insert = sc.GetPlan().(*core.Insert) - if sc.TruncateAsWarning && len(insertPlan.OnDuplicate) > 0 { - return err - } + // sc := ctx.GetSessionVars().StmtCtx + // var insertPlan *core.Insert = sc.GetPlan().(*core.Insert) + // if sc.TruncateAsWarning && len(insertPlan.OnDuplicate) > 0 { + // return err + // } return autoid.ErrAutoincReadFailed } return err From d64e083fdd980dfceb105ba1cfd922d0b855dbf2 Mon Sep 17 00:00:00 2001 From: Dousir9 <736191200@qq.com> Date: Tue, 20 Dec 2022 13:51:09 +0800 Subject: [PATCH 07/14] test --- executor/write_test.go | 56 +++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/executor/write_test.go b/executor/write_test.go index af17f47690cb5..19c7fee15ee06 100644 --- a/executor/write_test.go +++ b/executor/write_test.go @@ -592,34 +592,34 @@ commit;` tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1526 Table has no partition for value 3")) } -func TestIssue39847(t *testing.T) { - store := testkit.CreateMockStore(t) - var cfg kv.InjectionConfig - tk := testkit.NewTestKit(t, kv.NewInjectedStore(store, &cfg)) - tk.MustExec("use test") - testSQL := `drop table if exists t; - create table t (id smallint auto_increment primary key);` - tk.MustExec(testSQL) - - testSQL = `alter table t add column c1 int default 1;` - tk.MustExec(testSQL) - - testSQL = `insert ignore into t(id) values (194626268);` - tk.MustExec(testSQL) - require.Empty(t, tk.Session().LastMessage()) - - r := tk.MustQuery("select * from t;") - rowStr := fmt.Sprintf("%v %v", "32767", "1") - r.Check(testkit.Rows(rowStr)) - - tk.MustExec("insert ignore into t(id) values ('*') on duplicate key update c1 = 2;") - require.Equal(t, int64(2), int64(tk.Session().AffectedRows())) - require.Empty(t, tk.Session().LastMessage()) - - r = tk.MustQuery("select * from t;") - rowStr = fmt.Sprintf("%v %v", "32767", "2") - r.Check(testkit.Rows(rowStr)) -} +// func TestIssue39847(t *testing.T) { +// store := testkit.CreateMockStore(t) +// var cfg kv.InjectionConfig +// tk := testkit.NewTestKit(t, kv.NewInjectedStore(store, &cfg)) +// tk.MustExec("use test") +// testSQL := `drop table if exists t; +// create table t (id smallint auto_increment primary key);` +// tk.MustExec(testSQL) + +// testSQL = `alter table t add column c1 int default 1;` +// tk.MustExec(testSQL) + +// testSQL = `insert ignore into t(id) values (194626268);` +// tk.MustExec(testSQL) +// require.Empty(t, tk.Session().LastMessage()) + +// r := tk.MustQuery("select * from t;") +// rowStr := fmt.Sprintf("%v %v", "32767", "1") +// r.Check(testkit.Rows(rowStr)) + +// tk.MustExec("insert ignore into t(id) values ('*') on duplicate key update c1 = 2;") +// require.Equal(t, int64(2), int64(tk.Session().AffectedRows())) +// require.Empty(t, tk.Session().LastMessage()) + +// r = tk.MustQuery("select * from t;") +// rowStr = fmt.Sprintf("%v %v", "32767", "2") +// r.Check(testkit.Rows(rowStr)) +// } func TestInsertOnDup(t *testing.T) { store := testkit.CreateMockStore(t) From c2ed02e3ea1e8acc2d5482fc757ce857766b3ffe Mon Sep 17 00:00:00 2001 From: Dousir9 <736191200@qq.com> Date: Tue, 20 Dec 2022 15:45:30 +0800 Subject: [PATCH 08/14] test --- executor/insert_common.go | 11 ++++---- executor/write_test.go | 56 +++++++++++++++++++-------------------- 2 files changed, 34 insertions(+), 33 deletions(-) diff --git a/executor/insert_common.go b/executor/insert_common.go index 9f40a15b4459d..8cefae4f60060 100644 --- a/executor/insert_common.go +++ b/executor/insert_common.go @@ -32,6 +32,7 @@ import ( "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" + "github.com/pingcap/tidb/planner/core" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/sessiontxn" @@ -747,11 +748,11 @@ func setDatumAutoIDAndCast(ctx sessionctx.Context, d *types.Datum, id int64, col if err == nil && d.GetInt64() < id { // Auto ID is out of range, the truncated ID is possible to duplicate with an existing ID. // To prevent updating unrelated rows in the REPLACE statement, it is better to throw an error. - // sc := ctx.GetSessionVars().StmtCtx - // var insertPlan *core.Insert = sc.GetPlan().(*core.Insert) - // if sc.TruncateAsWarning && len(insertPlan.OnDuplicate) > 0 { - // return err - // } + sc := ctx.GetSessionVars().StmtCtx + var insertPlan *core.Insert = sc.GetPlan().(*core.Insert) + if sc.TruncateAsWarning && len(insertPlan.OnDuplicate) > 0 { + return err + } return autoid.ErrAutoincReadFailed } return err diff --git a/executor/write_test.go b/executor/write_test.go index 19c7fee15ee06..af17f47690cb5 100644 --- a/executor/write_test.go +++ b/executor/write_test.go @@ -592,34 +592,34 @@ commit;` tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1526 Table has no partition for value 3")) } -// func TestIssue39847(t *testing.T) { -// store := testkit.CreateMockStore(t) -// var cfg kv.InjectionConfig -// tk := testkit.NewTestKit(t, kv.NewInjectedStore(store, &cfg)) -// tk.MustExec("use test") -// testSQL := `drop table if exists t; -// create table t (id smallint auto_increment primary key);` -// tk.MustExec(testSQL) - -// testSQL = `alter table t add column c1 int default 1;` -// tk.MustExec(testSQL) - -// testSQL = `insert ignore into t(id) values (194626268);` -// tk.MustExec(testSQL) -// require.Empty(t, tk.Session().LastMessage()) - -// r := tk.MustQuery("select * from t;") -// rowStr := fmt.Sprintf("%v %v", "32767", "1") -// r.Check(testkit.Rows(rowStr)) - -// tk.MustExec("insert ignore into t(id) values ('*') on duplicate key update c1 = 2;") -// require.Equal(t, int64(2), int64(tk.Session().AffectedRows())) -// require.Empty(t, tk.Session().LastMessage()) - -// r = tk.MustQuery("select * from t;") -// rowStr = fmt.Sprintf("%v %v", "32767", "2") -// r.Check(testkit.Rows(rowStr)) -// } +func TestIssue39847(t *testing.T) { + store := testkit.CreateMockStore(t) + var cfg kv.InjectionConfig + tk := testkit.NewTestKit(t, kv.NewInjectedStore(store, &cfg)) + tk.MustExec("use test") + testSQL := `drop table if exists t; + create table t (id smallint auto_increment primary key);` + tk.MustExec(testSQL) + + testSQL = `alter table t add column c1 int default 1;` + tk.MustExec(testSQL) + + testSQL = `insert ignore into t(id) values (194626268);` + tk.MustExec(testSQL) + require.Empty(t, tk.Session().LastMessage()) + + r := tk.MustQuery("select * from t;") + rowStr := fmt.Sprintf("%v %v", "32767", "1") + r.Check(testkit.Rows(rowStr)) + + tk.MustExec("insert ignore into t(id) values ('*') on duplicate key update c1 = 2;") + require.Equal(t, int64(2), int64(tk.Session().AffectedRows())) + require.Empty(t, tk.Session().LastMessage()) + + r = tk.MustQuery("select * from t;") + rowStr = fmt.Sprintf("%v %v", "32767", "2") + r.Check(testkit.Rows(rowStr)) +} func TestInsertOnDup(t *testing.T) { store := testkit.CreateMockStore(t) From cdf221615c7c57f8a0760723b396ab3e35bafa15 Mon Sep 17 00:00:00 2001 From: Dousir9 <736191200@qq.com> Date: Mon, 26 Dec 2022 17:32:55 +0800 Subject: [PATCH 09/14] check if the type cast is ok to avoid panic --- executor/insert_common.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/executor/insert_common.go b/executor/insert_common.go index 8cefae4f60060..9508c13ff1a22 100644 --- a/executor/insert_common.go +++ b/executor/insert_common.go @@ -749,8 +749,8 @@ func setDatumAutoIDAndCast(ctx sessionctx.Context, d *types.Datum, id int64, col // Auto ID is out of range, the truncated ID is possible to duplicate with an existing ID. // To prevent updating unrelated rows in the REPLACE statement, it is better to throw an error. sc := ctx.GetSessionVars().StmtCtx - var insertPlan *core.Insert = sc.GetPlan().(*core.Insert) - if sc.TruncateAsWarning && len(insertPlan.OnDuplicate) > 0 { + insertPlan, ok := sc.GetPlan().(*core.Insert) + if ok && sc.TruncateAsWarning && len(insertPlan.OnDuplicate) > 0 { return err } return autoid.ErrAutoincReadFailed From ab74578de298ca627c001a8707f37467acebb2c9 Mon Sep 17 00:00:00 2001 From: Dousir9 <736191200@qq.com> Date: Tue, 27 Dec 2022 16:52:39 +0800 Subject: [PATCH 10/14] change the name of the test case --- executor/write_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/executor/write_test.go b/executor/write_test.go index af17f47690cb5..bc9126f6b34f4 100644 --- a/executor/write_test.go +++ b/executor/write_test.go @@ -592,7 +592,7 @@ commit;` tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1526 Table has no partition for value 3")) } -func TestIssue39847(t *testing.T) { +func TestIssue38950(t *testing.T) { store := testkit.CreateMockStore(t) var cfg kv.InjectionConfig tk := testkit.NewTestKit(t, kv.NewInjectedStore(store, &cfg)) From c236cc3eb6a5aa79694d5f2bac7c9f7c6ad4fbc8 Mon Sep 17 00:00:00 2001 From: Jk Xu <54522439+Dousir9@users.noreply.github.com> Date: Fri, 30 Dec 2022 12:01:30 +0800 Subject: [PATCH 11/14] Update executor/writetest/write_test.go minor Co-authored-by: Mattias Jonsson --- executor/write_test.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/executor/write_test.go b/executor/write_test.go index bc9126f6b34f4..12203827e2e79 100644 --- a/executor/write_test.go +++ b/executor/write_test.go @@ -616,9 +616,7 @@ func TestIssue38950(t *testing.T) { require.Equal(t, int64(2), int64(tk.Session().AffectedRows())) require.Empty(t, tk.Session().LastMessage()) - r = tk.MustQuery("select * from t;") - rowStr = fmt.Sprintf("%v %v", "32767", "2") - r.Check(testkit.Rows(rowStr)) + tk.MustQuery("select * from t").Check(testkit.Rows("32767 2")) } func TestInsertOnDup(t *testing.T) { From 5e2e55b8700f27fd57d06a6a8adfdc1ac6161e25 Mon Sep 17 00:00:00 2001 From: Jk Xu <54522439+Dousir9@users.noreply.github.com> Date: Fri, 30 Dec 2022 12:01:42 +0800 Subject: [PATCH 12/14] Update executor/writetest/write_test.go minor Co-authored-by: Mattias Jonsson --- executor/write_test.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/executor/write_test.go b/executor/write_test.go index 12203827e2e79..52864bb999143 100644 --- a/executor/write_test.go +++ b/executor/write_test.go @@ -608,9 +608,7 @@ func TestIssue38950(t *testing.T) { tk.MustExec(testSQL) require.Empty(t, tk.Session().LastMessage()) - r := tk.MustQuery("select * from t;") - rowStr := fmt.Sprintf("%v %v", "32767", "1") - r.Check(testkit.Rows(rowStr)) + tk.MustQuery("select * from t").Check(testkit.Rows("32767 1")) tk.MustExec("insert ignore into t(id) values ('*') on duplicate key update c1 = 2;") require.Equal(t, int64(2), int64(tk.Session().AffectedRows())) From e41250827749044ad9048fffb12cf47e29b7f03a Mon Sep 17 00:00:00 2001 From: Dousir9 <736191200@qq.com> Date: Fri, 30 Dec 2022 12:25:27 +0800 Subject: [PATCH 13/14] minor --- executor/write_test.go | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/executor/write_test.go b/executor/write_test.go index 52864bb999143..2b6915a775163 100644 --- a/executor/write_test.go +++ b/executor/write_test.go @@ -596,16 +596,10 @@ func TestIssue38950(t *testing.T) { store := testkit.CreateMockStore(t) var cfg kv.InjectionConfig tk := testkit.NewTestKit(t, kv.NewInjectedStore(store, &cfg)) - tk.MustExec("use test") - testSQL := `drop table if exists t; - create table t (id smallint auto_increment primary key);` - tk.MustExec(testSQL) - - testSQL = `alter table t add column c1 int default 1;` - tk.MustExec(testSQL) - - testSQL = `insert ignore into t(id) values (194626268);` - tk.MustExec(testSQL) + tk.MustExec("use test;") + tk.MustExec("drop table if exists t; create table t (id smallint auto_increment primary key);") + tk.MustExec("alter table t add column c1 int default 1;") + tk.MustExec("insert ignore into t(id) values (194626268);") require.Empty(t, tk.Session().LastMessage()) tk.MustQuery("select * from t").Check(testkit.Rows("32767 1")) From 2f0e78acf3fd454dbe9489b439d2adb15b2d2403 Mon Sep 17 00:00:00 2001 From: Dousir9 <736191200@qq.com> Date: Fri, 30 Dec 2022 12:26:44 +0800 Subject: [PATCH 14/14] update comment --- executor/insert_common.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/executor/insert_common.go b/executor/insert_common.go index 9508c13ff1a22..1c20005c69b20 100644 --- a/executor/insert_common.go +++ b/executor/insert_common.go @@ -746,13 +746,17 @@ func setDatumAutoIDAndCast(ctx sessionctx.Context, d *types.Datum, id int64, col var err error *d, err = table.CastValue(ctx, *d, col.ToInfo(), false, false) if err == nil && d.GetInt64() < id { - // Auto ID is out of range, the truncated ID is possible to duplicate with an existing ID. - // To prevent updating unrelated rows in the REPLACE statement, it is better to throw an error. + // Auto ID is out of range. sc := ctx.GetSessionVars().StmtCtx insertPlan, ok := sc.GetPlan().(*core.Insert) if ok && sc.TruncateAsWarning && len(insertPlan.OnDuplicate) > 0 { - return err + // Fix issue #38950: AUTO_INCREMENT is incompatible with mysql + // An auto id out of range error occurs in `insert ignore into ... on duplicate ...`. + // We should allow the SQL to be executed successfully. + return nil } + // The truncated ID is possible to duplicate with an existing ID. + // To prevent updating unrelated rows in the REPLACE statement, it is better to throw an error. return autoid.ErrAutoincReadFailed } return err