From ba22f4387d6148d60a23ec813f0ef7dc731a13de Mon Sep 17 00:00:00 2001 From: Ti Chi Robot Date: Tue, 14 Feb 2023 22:40:02 +0800 Subject: [PATCH] planner: fix space requirement when binding from history (#41140) (#41244) close pingcap/tidb#41126 --- infoschema/cluster_tables_test.go | 28 +++++++++++++++++++++++++++ util/stmtsummary/statement_summary.go | 6 ++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/infoschema/cluster_tables_test.go b/infoschema/cluster_tables_test.go index 5e323b2adc88a..15e6c5e71340d 100644 --- a/infoschema/cluster_tables_test.go +++ b/infoschema/cluster_tables_test.go @@ -852,3 +852,31 @@ func TestMDLView(t *testing.T) { wg.Wait() } + +func TestCreateBindingForPrepareToken(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) + + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int, b time, c varchar(5))") + + //some builtin functions listed in https://dev.mysql.com/doc/refman/8.0/en/function-resolution.html + cases := []string{ + "select std(a) from t", + "select cast(a as decimal(10, 2)) from t", + "select bit_or(a) from t", + "select min(a) from t", + "select max(a) from t", + "select substr(c, 1, 2) from t", + } + + for _, sql := range cases { + prep := fmt.Sprintf("prepare stmt from '%s'", sql) + tk.MustExec(prep) + tk.MustExec("execute stmt") + planDigest := tk.MustQuery(fmt.Sprintf("select plan_digest from information_schema.statements_summary where query_sample_text = '%s'", sql)).Rows() + tk.MustExec(fmt.Sprintf("create binding from history using plan digest '%s'", planDigest[0][0])) + } +} diff --git a/util/stmtsummary/statement_summary.go b/util/stmtsummary/statement_summary.go index 4db62bdb7c048..6740656c9ca9e 100644 --- a/util/stmtsummary/statement_summary.go +++ b/util/stmtsummary/statement_summary.go @@ -516,10 +516,12 @@ func getBindableStmtByPlanDigest(ssbd *stmtSummaryByDigest, planDigest string) * Collation: ssElement.collation, Users: ssElement.authUsers, } - // If it is SQL command prepare / execute, the ssElement.sampleSQL is `execute ...`, we should get the original select query. + // If it is SQL command prepare / execute, we should remove the arguments // If it is binary protocol prepare / execute, ssbd.normalizedSQL should be same as ssElement.sampleSQL. if ssElement.prepared { - stmt.Query = ssbd.normalizedSQL + if idx := strings.LastIndex(stmt.Query, "[arguments:"); idx != -1 { + stmt.Query = stmt.Query[:idx] + } } return stmt }