diff --git a/cmd/explaintest/r/explain_easy.result b/cmd/explaintest/r/explain_easy.result index f8be436f089c7..34615b4c4a377 100644 --- a/cmd/explaintest/r/explain_easy.result +++ b/cmd/explaintest/r/explain_easy.result @@ -722,3 +722,24 @@ TableReader_7 1.00 root data:Selection_6 └─Selection_6 1.00 cop[tikv] eq(test.t.b, 1000-01-01 00:00:00.000000) └─TableScan_5 3.00 cop[tikv] table:t, range:[-inf,+inf], keep order:false drop table t; +create table t(a int, b int); +explain format="dot" select * from t where a < 2; +dot contents + +digraph TableReader_7 { +subgraph cluster7{ +node [style=filled, color=lightgrey] +color=black +label = "root" +"TableReader_7" +} +subgraph cluster6{ +node [style=filled, color=lightgrey] +color=black +label = "cop" +"Selection_6" -> "TableScan_5" +} +"TableReader_7" -> "Selection_6" +} + +drop table if exists t; diff --git a/cmd/explaintest/t/explain_easy.test b/cmd/explaintest/t/explain_easy.test index 7c6db8632c592..bec85e447a95c 100644 --- a/cmd/explaintest/t/explain_easy.test +++ b/cmd/explaintest/t/explain_easy.test @@ -179,3 +179,7 @@ analyze table t; explain select * from t where a = 1; explain select * from t where b = "1000-01-01"; drop table t; + +create table t(a int, b int); +explain format="dot" select * from t where a < 2; +drop table if exists t; diff --git a/planner/core/common_plans.go b/planner/core/common_plans.go index 14e7a6f29b044..ce4c1d0e098a3 100644 --- a/planner/core/common_plans.go +++ b/planner/core/common_plans.go @@ -680,22 +680,25 @@ func (e *Explain) prepareOperatorInfo(p PhysicalPlan, taskType string, indent st func (e *Explain) prepareDotInfo(p PhysicalPlan) { buffer := bytes.NewBufferString("") - buffer.WriteString(fmt.Sprintf("\ndigraph %s {\n", p.ExplainID())) + fmt.Fprintf(buffer, "\ndigraph %s {\n", p.ExplainID()) e.prepareTaskDot(p, "root", buffer) - buffer.WriteString(fmt.Sprintln("}")) + buffer.WriteString("}\n") e.Rows = append(e.Rows, []string{buffer.String()}) } func (e *Explain) prepareTaskDot(p PhysicalPlan, taskTp string, buffer *bytes.Buffer) { - buffer.WriteString(fmt.Sprintf("subgraph cluster%v{\n", p.ID())) + fmt.Fprintf(buffer, "subgraph cluster%v{\n", p.ID()) buffer.WriteString("node [style=filled, color=lightgrey]\n") buffer.WriteString("color=black\n") - buffer.WriteString(fmt.Sprintf("label = \"%s\"\n", taskTp)) + fmt.Fprintf(buffer, "label = \"%s\"\n", taskTp) if len(p.Children()) == 0 { - buffer.WriteString(fmt.Sprintf("\"%s\"\n}\n", p.ExplainID())) - return + if taskTp == "cop" { + fmt.Fprintf(buffer, "\"%s\"\n}\n", p.ExplainID()) + return + } + fmt.Fprintf(buffer, "\"%s\"\n", p.ExplainID()) } var copTasks []PhysicalPlan @@ -717,7 +720,7 @@ func (e *Explain) prepareTaskDot(p PhysicalPlan, taskTp string, buffer *bytes.Bu copTasks = append(copTasks, copPlan.indexPlan) } for _, child := range curPlan.Children() { - buffer.WriteString(fmt.Sprintf("\"%s\" -> \"%s\"\n", curPlan.ExplainID(), child.ExplainID())) + fmt.Fprintf(buffer, "\"%s\" -> \"%s\"\n", curPlan.ExplainID(), child.ExplainID()) planQueue = append(planQueue, child) } }