From 6cbbcea3f1bde3bce4051096acadef241847eca9 Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Thu, 11 Jul 2019 15:24:27 +0800 Subject: [PATCH] executor: fix a bug of 'insert on duplicate update' statement on partitioned table (#11204) In this statement: insert into t1 set a=1,b=1 on duplicate key update a=1,b=1 Batch checker find a=1,b=1 is duplicated, then in the "on duplicate update" step, it uses the non-partitioned table to get the old row, which is a bug. getOldRow returns this error: (1105, u'can not be duplicated row, due to old row not found. handle 1 not found') --- executor/insert.go | 2 +- executor/insert_test.go | 14 ++++++++++++++ executor/simple_test.go | 9 +++++++-- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/executor/insert.go b/executor/insert.go index 97085684332b4..3b559e2699246 100644 --- a/executor/insert.go +++ b/executor/insert.go @@ -169,7 +169,7 @@ func (e *InsertExec) Open(ctx context.Context) error { // updateDupRow updates a duplicate row to a new row. func (e *InsertExec) updateDupRow(row toBeCheckedRow, handle int64, onDuplicate []*expression.Assignment) error { - oldRow, err := e.getOldRow(e.ctx, e.Table, handle, e.GenExprs) + oldRow, err := e.getOldRow(e.ctx, row.t, handle, e.GenExprs) if err != nil { logutil.Logger(context.Background()).Error("get old row failed when insert on dup", zap.Int64("handle", handle), zap.String("toBeInsertedRow", types.DatumsToStrNoErr(row.row))) return err diff --git a/executor/insert_test.go b/executor/insert_test.go index 8c3510b044126..e26834572f12b 100644 --- a/executor/insert_test.go +++ b/executor/insert_test.go @@ -286,3 +286,17 @@ func (s *testSuite3) TestAllowInvalidDates(c *C) { runWithMode("STRICT_TRANS_TABLES,ALLOW_INVALID_DATES") runWithMode("ALLOW_INVALID_DATES") } + +func (s *testSuite3) TestPartitionInsertOnDuplicate(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec(`use test`) + tk.MustExec(`create table t1 (a int,b int,primary key(a,b)) partition by range(a) (partition p0 values less than (100),partition p1 values less than (1000))`) + tk.MustExec(`insert into t1 set a=1, b=1`) + tk.MustExec(`insert into t1 set a=1,b=1 on duplicate key update a=1,b=1`) + tk.MustQuery(`select * from t1`).Check(testkit.Rows("1 1")) + + tk.MustExec(`create table t2 (a int,b int,primary key(a,b)) partition by hash(a) partitions 4`) + tk.MustExec(`insert into t2 set a=1,b=1;`) + tk.MustExec(`insert into t2 set a=1,b=1 on duplicate key update a=1,b=1`) + tk.MustQuery(`select * from t2`).Check(testkit.Rows("1 1")) +} diff --git a/executor/simple_test.go b/executor/simple_test.go index 185a64cc6833f..4a0499f9e9b73 100644 --- a/executor/simple_test.go +++ b/executor/simple_test.go @@ -405,14 +405,19 @@ func (s *testFlushSuite) TestFlushPrivilegesPanic(c *C) { c.Assert(err, IsNil) defer store.Close() - config.GetGlobalConfig().Security.SkipGrantTable = true + saveConf := config.GetGlobalConfig() + conf := config.NewConfig() + conf.Security.SkipGrantTable = true + config.StoreGlobalConfig(conf) + dom, err := session.BootstrapSession(store) c.Assert(err, IsNil) defer dom.Close() tk := testkit.NewTestKit(c, store) tk.MustExec("FLUSH PRIVILEGES") - config.GetGlobalConfig().Security.SkipGrantTable = false + + config.StoreGlobalConfig(saveConf) } func (s *testSuite3) TestDropStats(c *C) {