diff --git a/planner/core/explain.go b/planner/core/explain.go index 16140495de3e7..48428eab15cca 100644 --- a/planner/core/explain.go +++ b/planner/core/explain.go @@ -174,10 +174,11 @@ func (p *PhysicalTableScan) ExplainNormalizedInfo() string { func (p *PhysicalTableScan) OperatorInfo(normalized bool) string { var buffer strings.Builder if len(p.rangeInfo) > 0 { - // TODO: deal with normalized case - buffer.WriteString("range: decided by ") - buffer.WriteString(p.rangeInfo) - buffer.WriteString(", ") + if !normalized { + buffer.WriteString("range: decided by ") + buffer.WriteString(p.rangeInfo) + buffer.WriteString(", ") + } } else if p.haveCorCol() { if normalized { buffer.WriteString("range: decided by ") diff --git a/planner/core/plan_test.go b/planner/core/plan_test.go index 2e69205a2b9c6..7f6e328f32cc1 100644 --- a/planner/core/plan_test.go +++ b/planner/core/plan_test.go @@ -152,6 +152,44 @@ func TestNormalizedPlan(t *testing.T) { } } +func TestIssue47634(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t3,t4") + tk.MustExec("create table t3(a int, b int, c int);") + tk.MustExec("create table t4(a int, b int, c int, primary key (a, b) clustered);") + tk.MustExec("create table t5(a int, b int, c int, key idx_a_b (a, b));") + tk.Session().GetSessionVars().PlanID = 0 + queriesGroup1 := []string{ + "explain select /*+ inl_join(t4) */ * from t3 join t4 on t3.b = t4.b where t4.a = 1;", + "explain select /*+ inl_join(t5) */ * from t3 join t5 on t3.b = t5.b where t5.a = 1;", + } + queriesGroup2 := []string{ + "explain select /*+ inl_join(t4) */ * from t3 join t4 on t3.b = t4.b where t4.a = 2;", + "explain select /*+ inl_join(t5) */ * from t3 join t5 on t3.b = t5.b where t5.a = 2;", + } + for i := 0; i < len(queriesGroup1); i++ { + query1 := queriesGroup1[i] + query2 := queriesGroup2[i] + t.Run(query1+" vs "+query2, func(t *testing.T) { + tk.MustExec(query1) + info1 := tk.Session().ShowProcess() + require.NotNil(t, info1) + p1, ok := info1.Plan.(core.Plan) + require.True(t, ok) + _, digest1 := core.NormalizePlan(p1) + tk.MustExec(query2) + info2 := tk.Session().ShowProcess() + require.NotNil(t, info2) + p2, ok := info2.Plan.(core.Plan) + require.True(t, ok) + _, digest2 := core.NormalizePlan(p2) + require.Equal(t, digest1, digest2) + }) + } +} + func TestNormalizedPlanForDiffStore(t *testing.T) { store, dom := testkit.CreateMockStoreAndDomain(t) tk := testkit.NewTestKit(t, store) diff --git a/planner/core/testdata/plan_normalized_suite_out.json b/planner/core/testdata/plan_normalized_suite_out.json index 0f4218ba2649a..70de129af4de6 100644 --- a/planner/core/testdata/plan_normalized_suite_out.json +++ b/planner/core/testdata/plan_normalized_suite_out.json @@ -95,7 +95,7 @@ " │ └─Selection cop gt(test.t1.c, ?)", " │ └─TableFullScan cop table:t1, range:[?,?], keep order:false", " └─TableReader root ", - " └─TableRangeScan cop table:t2, range: decided by [test.t1.a], keep order:false" + " └─TableRangeScan cop table:t2, keep order:false" ] }, { @@ -128,7 +128,7 @@ " │ └─Selection cop gt(test.t1.c, ?)", " │ └─TableFullScan cop table:t1, range:[?,?], keep order:false", " └─TableReader root ", - " └─TableRangeScan cop table:t2, range: decided by [test.t1.a], keep order:false" + " └─TableRangeScan cop table:t2, keep order:false" ] }, {