Skip to content

Commit

Permalink
flatten the json output (pingcap#30905)
Browse files Browse the repository at this point in the history
Signed-off-by: yisaer <[email protected]>

Co-authored-by: Ti Chi Robot <[email protected]>
  • Loading branch information
2 people authored and tangenta committed Dec 24, 2021
1 parent 6afe4d9 commit f1c3f60
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 8 deletions.
57 changes: 49 additions & 8 deletions util/tracing/opt_trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@ package tracing

// LogicalPlanTrace indicates for the LogicalPlan trace information
type LogicalPlanTrace struct {
ID int `json:"id"`
TP string `json:"type"`
Children []*LogicalPlanTrace `json:"children"`
ID int
TP string
Children []*LogicalPlanTrace

// ExplainInfo should be implemented by each implemented LogicalPlan
ExplainInfo string `json:"info"`
ExplainInfo string
}

// LogicalOptimizeTracer indicates the trace for the whole logicalOptimize processing
type LogicalOptimizeTracer struct {
FinalLogicalPlan *LogicalPlanTrace `json:"final"`
FinalLogicalPlan []FlattenLogicalPlanTrace `json:"final"`
Steps []*LogicalRuleOptimizeTracer `json:"steps"`
// curRuleTracer indicates the current rule Tracer during optimize by rule
curRuleTracer *LogicalRuleOptimizeTracer
Expand All @@ -53,14 +53,14 @@ func (tracer *LogicalOptimizeTracer) AppendRuleTracerStepToCurrent(id int, tp, r

// RecordFinalLogicalPlan add plan trace after logical optimize
func (tracer *LogicalOptimizeTracer) RecordFinalLogicalPlan(final *LogicalPlanTrace) {
tracer.FinalLogicalPlan = final
tracer.FinalLogicalPlan = toFlattenLogicalPlanTrace(final)
}

// LogicalRuleOptimizeTracer indicates the trace for the LogicalPlan tree before and after
// logical rule optimize
type LogicalRuleOptimizeTracer struct {
Index int `json:"index"`
Before *LogicalPlanTrace `json:"before"`
Before []FlattenLogicalPlanTrace `json:"before"`
RuleName string `json:"name"`
Steps []LogicalRuleOptimizeTraceStep `json:"steps"`
}
Expand All @@ -69,7 +69,7 @@ type LogicalRuleOptimizeTracer struct {
func buildLogicalRuleOptimizeTracerBeforeOptimize(index int, name string, before *LogicalPlanTrace) *LogicalRuleOptimizeTracer {
return &LogicalRuleOptimizeTracer{
Index: index,
Before: before,
Before: toFlattenLogicalPlanTrace(before),
RuleName: name,
Steps: make([]LogicalRuleOptimizeTraceStep, 0),
}
Expand All @@ -85,6 +85,47 @@ type LogicalRuleOptimizeTraceStep struct {
Index int `json:"index"`
}

// FlattenLogicalPlanTrace indicates the flatten LogicalPlanTrace
type FlattenLogicalPlanTrace struct {
ID int `json:"id"`
TP string `json:"type"`
Children []int `json:"children"`

// ExplainInfo should be implemented by each implemented LogicalPlan
ExplainInfo string `json:"info"`
}

// toFlattenLogicalPlanTrace transform LogicalPlanTrace into FlattenLogicalPlanTrace
func toFlattenLogicalPlanTrace(root *LogicalPlanTrace) []FlattenLogicalPlanTrace {
wrapper := &flattenWrapper{flatten: make([]FlattenLogicalPlanTrace, 0)}
flattenLogicalPlanTrace(root, wrapper)
return wrapper.flatten
}

type flattenWrapper struct {
flatten []FlattenLogicalPlanTrace
}

func flattenLogicalPlanTrace(node *LogicalPlanTrace, wrapper *flattenWrapper) {
flattenNode := FlattenLogicalPlanTrace{
ID: node.ID,
TP: node.TP,
ExplainInfo: node.ExplainInfo,
Children: make([]int, 0),
}
if len(node.Children) < 1 {
wrapper.flatten = append(wrapper.flatten, flattenNode)
return
}
for _, child := range node.Children {
flattenNode.Children = append(flattenNode.Children, child.ID)
}
for _, child := range node.Children {
flattenLogicalPlanTrace(child, wrapper)
}
wrapper.flatten = append(wrapper.flatten, flattenNode)
}

// CETraceRecord records an expression and related cardinality estimation result.
type CETraceRecord struct {
TableID int64 `json:"-"`
Expand Down
105 changes: 105 additions & 0 deletions util/tracing/opt_trace_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// Copyright 2021 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package tracing

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestFlattenLogicalPlanTrace(t *testing.T) {
root1 := &LogicalPlanTrace{
ID: 1,
TP: "foo1",
ExplainInfo: "bar1",
Children: []*LogicalPlanTrace{
{
ID: 2,
TP: "foo2",
ExplainInfo: "bar2",
Children: nil,
},
},
}
root2 := &LogicalPlanTrace{
ID: 1,
TP: "foo1",
ExplainInfo: "bar1",
Children: []*LogicalPlanTrace{
{
ID: 2,
TP: "foo2",
ExplainInfo: "bar2",
Children: nil,
},
{
ID: 3,
TP: "foo3",
ExplainInfo: "bar3",
Children: []*LogicalPlanTrace{
{
ID: 4,
TP: "foo4",
ExplainInfo: "bar4",
Children: nil,
},
},
},
},
}
expect1 := []FlattenLogicalPlanTrace{
{
ID: 2,
TP: "foo2",
ExplainInfo: "bar2",
Children: []int{},
},
{
ID: 1,
TP: "foo1",
ExplainInfo: "bar1",
Children: []int{2},
},
}
expect2 := []FlattenLogicalPlanTrace{
{
ID: 2,
TP: "foo2",
ExplainInfo: "bar2",
Children: []int{},
},
{
ID: 4,
TP: "foo4",
ExplainInfo: "bar4",
Children: []int{},
},
{
ID: 3,
TP: "foo3",
ExplainInfo: "bar3",
Children: []int{4},
},
{
ID: 1,
TP: "foo1",
ExplainInfo: "bar1",
Children: []int{2, 3},
},
}
require.EqualValues(t, toFlattenLogicalPlanTrace(root1), expect1)
require.EqualValues(t, toFlattenLogicalPlanTrace(root2), expect2)
}

0 comments on commit f1c3f60

Please sign in to comment.