From d5b2c9b17d4446f2108c41663f91ff8a5d8d0767 Mon Sep 17 00:00:00 2001 From: Chengpeng Yan <41809508+Reminiscent@users.noreply.github.com> Date: Thu, 22 Sep 2022 18:11:03 +0800 Subject: [PATCH] planner: fix panic when prepare and execute the insert on duplicate (#37924) close pingcap/tidb#37187 --- executor/insert_test.go | 13 +++++++++++++ planner/core/planbuilder.go | 5 +++++ 2 files changed, 18 insertions(+) diff --git a/executor/insert_test.go b/executor/insert_test.go index d0d17199c13f7..06c9927bba008 100644 --- a/executor/insert_test.go +++ b/executor/insert_test.go @@ -352,6 +352,19 @@ func TestUpdateDuplicateKey(t *testing.T) { "[kv:1062]Duplicate entry '1-2-4' for key 'PRIMARY'") } +func TestIssue37187(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + + tk.MustExec("drop table if exists a, b") + tk.MustExec("create table t1 (a int(11) ,b varchar(100) ,primary key (a));") + tk.MustExec("create table t2 (c int(11) ,d varchar(100) ,primary key (c));") + tk.MustExec("prepare in1 from 'insert into t1 (a,b) select c,null from t2 t on duplicate key update b=t.d';") + err := tk.ExecToErr("execute in1;") + require.NoError(t, err) +} + func TestInsertWrongValueForField(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) diff --git a/planner/core/planbuilder.go b/planner/core/planbuilder.go index f00d0625c9cf0..14a9b169e5536 100644 --- a/planner/core/planbuilder.go +++ b/planner/core/planbuilder.go @@ -3895,6 +3895,11 @@ func (b *PlanBuilder) buildSelectPlanOfInsert(ctx context.Context, insert *ast.I } sel.Fields.Fields = append(sel.Fields.Fields, &ast.SelectField{Expr: colName, Offset: len(sel.Fields.Fields)}) } + defer func(originSelFieldLen int) { + // Revert the change for ast. Because when we use the 'prepare' and 'execute' statement it will both build plan which will cause problem. + // You can see the issue #37187 for more details. + sel.Fields.Fields = sel.Fields.Fields[:originSelFieldLen] + }(actualColLen) } } }