diff --git a/executor/insert.go b/executor/insert.go index 7b0758c7ff076..76197d22ea479 100644 --- a/executor/insert.go +++ b/executor/insert.go @@ -360,7 +360,7 @@ func (e *InsertExec) initEvalBuffer4Dup() { evalBufferTypes = append(evalBufferTypes, &col.FieldType) } if extraLen > 0 { - evalBufferTypes = append(evalBufferTypes, e.SelectExec.base().retFieldTypes[numWritableCols:]...) + evalBufferTypes = append(evalBufferTypes, e.SelectExec.base().retFieldTypes[e.rowLen:]...) } for _, col := range e.Table.Cols() { evalBufferTypes = append(evalBufferTypes, &col.FieldType) @@ -369,7 +369,7 @@ func (e *InsertExec) initEvalBuffer4Dup() { evalBufferTypes = append(evalBufferTypes, types.NewFieldType(mysql.TypeLonglong)) } e.evalBuffer4Dup = chunk.MutRowFromTypes(evalBufferTypes) - e.curInsertVals = chunk.MutRowFromTypes(evalBufferTypes[numWritableCols:]) + e.curInsertVals = chunk.MutRowFromTypes(evalBufferTypes[numWritableCols+extraLen:]) e.row4Update = make([]types.Datum, 0, len(evalBufferTypes)) } diff --git a/executor/insert_test.go b/executor/insert_test.go index e6311a5a74ff8..2c790ccd1ddce 100644 --- a/executor/insert_test.go +++ b/executor/insert_test.go @@ -210,6 +210,36 @@ func (s *testSuite8) TestInsertOnDuplicateKey(c *C) { c.Assert(tk.Se.AffectedRows(), Equals, uint64(2)) tk.MustQuery("select * from a").Check(testkit.Rows("2")) + // Test issue 28078. + // Use different types of columns so that there's likely to be error if the types mismatches. + tk.MustExec("drop table if exists a, b") + tk.MustExec("create table a(id int, a1 timestamp, a2 varchar(10), a3 float, unique(id))") + tk.MustExec("create table b(id int, b1 time, b2 varchar(10), b3 int)") + tk.MustExec("insert into a values (1, '2022-01-04 07:02:04', 'a', 1.1), (2, '2022-01-04 07:02:05', 'b', 2.2)") + tk.MustExec("insert into b values (2, '12:34:56', 'c', 10), (3, '01:23:45', 'd', 20)") + tk.MustExec("insert into a (id) select id from b on duplicate key update a.a2 = b.b2, a.a3 = 3.3") + c.Assert(tk.Se.AffectedRows(), Equals, uint64(3)) + tk.MustQuery("select * from a").Check(testutil.RowsWithSep("/", + "1/2022-01-04 07:02:04/a/1.1", + "2/2022-01-04 07:02:05/c/3.3", + "3///")) + tk.MustExec("insert into a (id) select 4 from b where b3 = 20 on duplicate key update a.a3 = b.b3") + c.Assert(tk.Se.AffectedRows(), Equals, uint64(1)) + tk.MustQuery("select * from a").Check(testutil.RowsWithSep("/", + "1/2022-01-04 07:02:04/a/1.1", + "2/2022-01-04 07:02:05/c/3.3", + "3///", + "4///")) + tk.MustExec("insert into a (a2, a3) select 'x', 1.2 from b on duplicate key update a.a2 = b.b3") + c.Assert(tk.Se.AffectedRows(), Equals, uint64(2)) + tk.MustQuery("select * from a").Check(testutil.RowsWithSep("/", + "1/2022-01-04 07:02:04/a/1.1", + "2/2022-01-04 07:02:05/c/3.3", + "3///", + "4///", + "//x/1.2", + "//x/1.2")) + // reproduce insert on duplicate key update bug under new row format. tk.MustExec(`drop table if exists t1`) tk.MustExec(`create table t1(c1 decimal(6,4), primary key(c1))`)