Skip to content

Commit

Permalink
executor: special handling is required when an "auto id out of range"…
Browse files Browse the repository at this point in the history
… error occurs in `insert ignore into ... on on duplicate ...` (#39847)

close #38950
  • Loading branch information
Dousir9 authored Jan 3, 2023
1 parent 1f344ba commit 3ccff46
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 1 deletion.
12 changes: 11 additions & 1 deletion executor/insert_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -771,7 +772,16 @@ 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.
// Auto ID is out of range.
sc := ctx.GetSessionVars().StmtCtx
insertPlan, ok := sc.GetPlan().(*core.Insert)
if ok && sc.TruncateAsWarning && len(insertPlan.OnDuplicate) > 0 {
// 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
}
Expand Down
19 changes: 19 additions & 0 deletions executor/writetest/write_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,25 @@ commit;`
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1526 Table has no partition for value 3"))
}

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;")
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"))

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())

tk.MustQuery("select * from t").Check(testkit.Rows("32767 2"))
}

func TestInsertOnDup(t *testing.T) {
store := testkit.CreateMockStore(t)
var cfg kv.InjectionConfig
Expand Down

0 comments on commit 3ccff46

Please sign in to comment.