From ac60c03e379e481cce2634872d6785a5d1f5d30e Mon Sep 17 00:00:00 2001 From: Feng Liyuan Date: Thu, 20 Aug 2020 17:45:47 +0800 Subject: [PATCH] cherry pick #19316 to release-3.1 Signed-off-by: ti-srebot --- executor/seqtest/prepared_test.go | 70 +++++++++++++++++++++++++++++++ planner/core/util.go | 5 +++ 2 files changed, 75 insertions(+) diff --git a/executor/seqtest/prepared_test.go b/executor/seqtest/prepared_test.go index f6140b074d09f..a7c8bd5db5b6f 100644 --- a/executor/seqtest/prepared_test.go +++ b/executor/seqtest/prepared_test.go @@ -15,12 +15,22 @@ package executor_test import ( "context" + "crypto/tls" "math" + "time" . "github.com/pingcap/check" + "github.com/pingcap/parser/mysql" "github.com/pingcap/tidb/executor" "github.com/pingcap/tidb/metrics" plannercore "github.com/pingcap/tidb/planner/core" +<<<<<<< HEAD +======= + "github.com/pingcap/tidb/session" + "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util" + "github.com/pingcap/tidb/util/kvcache" +>>>>>>> 57e43bd... planner: workaround the panic of command EXECUTE when printing an expensive query log (#19316) "github.com/pingcap/tidb/util/testkit" dto "github.com/prometheus/client_model/go" ) @@ -757,3 +767,63 @@ func (s *seqTestSuite) TestPreparedIssue8644(c *C) { r.Check(testkit.Rows("a", "aaaaaaaaaaaaaaaaaa")) } } + +// mockSessionManager is a mocked session manager which is used for test. +type mockSessionManager1 struct { + Se session.Session +} + +// ShowProcessList implements the SessionManager.ShowProcessList interface. +func (msm *mockSessionManager1) ShowProcessList() map[uint64]*util.ProcessInfo { + ret := make(map[uint64]*util.ProcessInfo) + return ret +} + +func (msm *mockSessionManager1) GetProcessInfo(id uint64) (*util.ProcessInfo, bool) { + pi := msm.Se.ShowProcess() + return pi, true +} + +// Kill implements the SessionManager.Kill interface. +func (msm *mockSessionManager1) Kill(cid uint64, query bool) {} + +func (msm *mockSessionManager1) UpdateTLSConfig(cfg *tls.Config) {} + +func (s *seqTestSuite) TestPreparedIssue17419(c *C) { + ctx := context.Background() + tk := testkit.NewTestKit(c, s.store) + + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t (a int)") + tk.MustExec("insert into t (a) values (1), (2), (3)") + + tk1 := testkit.NewTestKit(c, s.store) + + var err error + tk1.Se, err = session.CreateSession4Test(s.store) + c.Assert(err, IsNil) + tk1.GetConnectionID() + + query := "select * from test.t" + stmtID, _, _, err := tk1.Se.PrepareStmt(query) + c.Assert(err, IsNil) + + sm := &mockSessionManager1{ + Se: tk1.Se, + } + tk1.Se.SetSessionManager(sm) + s.domain.ExpensiveQueryHandle().SetSessionManager(sm) + + rs, err := tk1.Se.ExecutePreparedStmt(ctx, stmtID, []types.Datum{}) + c.Assert(err, IsNil) + tk1.ResultSetToResult(rs, Commentf("%v", rs)).Check(testkit.Rows("1", "2", "3")) + tk1.Se.SetProcessInfo("", time.Now(), mysql.ComStmtExecute, 0) + + s.domain.ExpensiveQueryHandle().LogOnQueryExceedMemQuota(tk.Se.GetSessionVars().ConnectionID) + + // After entirely fixing https://github.com/pingcap/tidb/issues/17419 + // c.Assert(tk1.Se.ShowProcess().Plan, NotNil) + // _, ok := tk1.Se.ShowProcess().Plan.(*plannercore.Execute) + // c.Assert(ok, IsTrue) +} diff --git a/planner/core/util.go b/planner/core/util.go index 4d6fd39973712..12fceb060db27 100644 --- a/planner/core/util.go +++ b/planner/core/util.go @@ -169,6 +169,11 @@ func buildPhysicalJoinSchema(joinType JoinType, join PhysicalPlan) *expression.S // GetStatsInfo gets the statistics info from a physical plan tree. func GetStatsInfo(i interface{}) map[string]uint64 { + if i == nil { + // it's a workaround for https://github.com/pingcap/tidb/issues/17419 + // To entirely fix this, uncomment the assertion in TestPreparedIssue17419 + return nil + } p := i.(Plan) var physicalPlan PhysicalPlan switch x := p.(type) {