Skip to content

Commit

Permalink
Support the tck format for the output of EXPLAIN (#265)
Browse files Browse the repository at this point in the history
* Support the tck format for the output of EXPLAIN

* Update go.mod

* aaa

* bbb

* u

* u

* u

* u

* u

* u

* u

* u

* u

* u

* u

* u

* u

* u

* u

* Support the tck format for the output of EXPLAIN

* u

* Update go.mod

* Update result_set.go

---------

Co-authored-by: Yichen Wang <[email protected]>
  • Loading branch information
AntiTopQuark and Aiee authored Apr 3, 2023
1 parent 94abfb9 commit bf9fe21
Showing 1 changed file with 94 additions and 45 deletions.
139 changes: 94 additions & 45 deletions result_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -1252,6 +1252,65 @@ func (res ResultSet) MakeDotGraphByStruct() string {
return builder.String()
}

// generate profiling data for both Row and TCK formats.
func MakeProfilingData(planNodeDesc *graph.PlanNodeDescription, isTckFmt bool) string {
var profileArr []string
for i, profile := range planNodeDesc.GetProfiles() {
var statArr []string
statArr = append(statArr, fmt.Sprintf("\"version\":%d", i))
statArr = append(statArr, fmt.Sprintf("\"rows\":%d", profile.GetRows()))
if !isTckFmt {
// tck format doesn't need these fields
statArr = append(statArr, fmt.Sprintf("\"execTime\":\"%d(us)\"", profile.GetExecDurationInUs()))
statArr = append(statArr, fmt.Sprintf("\"totalTime\":\"%d(us)\"", profile.GetTotalDurationInUs()))
}
for k, v := range profile.GetOtherStats() {
s := string(v)
if matched, err := regexp.Match(`^[^{(\[]\w+`, v); err == nil && matched {
if !strings.HasPrefix(s, "\"") {
s = fmt.Sprintf("\"%s", s)
}
if !strings.HasSuffix(s, "\"") {
s = fmt.Sprintf("%s\"", s)
}
}
statArr = append(statArr, fmt.Sprintf("\"%s\": %s", k, s))
}
sort.Strings(statArr)
statStr := fmt.Sprintf("{%s}", strings.Join(statArr, ",\n"))
profileArr = append(profileArr, statStr)
}
allProfiles := strings.Join(profileArr, ",\n")
if len(profileArr) > 1 {
allProfiles = fmt.Sprintf("[%s]", allProfiles)
}
var buffer bytes.Buffer
json.Indent(&buffer, []byte(allProfiles), "", " ")
return string(buffer.Bytes())
}

// generate operator info for Row format.
func MakeOperatorInfo(planNodeDesc *graph.PlanNodeDescription) string {
var columnInfo []string
if planNodeDesc.IsSetBranchInfo() {
branchInfo := planNodeDesc.GetBranchInfo()
columnInfo = append(columnInfo, fmt.Sprintf("branch: %t, nodeId: %d\n",
branchInfo.GetIsDoBranch(), branchInfo.GetConditionNodeID()))
}

outputVar := fmt.Sprintf("outputVar: %s", prettyFormatJsonString(planNodeDesc.GetOutputVar()))
columnInfo = append(columnInfo, outputVar)

if planNodeDesc.IsSetDescription() {
desc := planNodeDesc.GetDescription()
for _, pair := range desc {
value := prettyFormatJsonString(pair.GetValue())
columnInfo = append(columnInfo, fmt.Sprintf("%s: %s", string(pair.GetKey()), value))
}
}
return strings.Join(columnInfo, "\n")
}

// explain/profile format="row"
func (res ResultSet) MakePlanByRow() [][]interface{} {
p := res.GetPlanDesc()
Expand All @@ -1272,58 +1331,48 @@ func (res ResultSet) MakePlanByRow() [][]interface{} {
}

if planNodeDesc.IsSetProfiles() {
var profileArr []string
for i, profile := range planNodeDesc.GetProfiles() {
var statArr []string
statArr = append(statArr, fmt.Sprintf("\"version\":%d", i))
statArr = append(statArr, fmt.Sprintf("\"rows\":%d", profile.GetRows()))
statArr = append(statArr, fmt.Sprintf("\"execTime\":\"%d(us)\"", profile.GetExecDurationInUs()))
statArr = append(statArr, fmt.Sprintf("\"totalTime\":\"%d(us)\"", profile.GetTotalDurationInUs()))
for k, v := range profile.GetOtherStats() {
s := string(v)
if matched, err := regexp.Match(`^[^{(\[]\w+`, v); err == nil && matched {
if !strings.HasPrefix(s, "\"") {
s = fmt.Sprintf("\"%s", s)
}
if !strings.HasSuffix(s, "\"") {
s = fmt.Sprintf("%s\"", s)
}
}
statArr = append(statArr, fmt.Sprintf("\"%s\": %s", k, s))
}
sort.Strings(statArr)
statStr := fmt.Sprintf("{%s}", strings.Join(statArr, ",\n"))
profileArr = append(profileArr, statStr)
}
allProfiles := strings.Join(profileArr, ",\n")
if len(profileArr) > 1 {
allProfiles = fmt.Sprintf("[%s]", allProfiles)
}
var buffer bytes.Buffer
json.Indent(&buffer, []byte(allProfiles), "", " ")
row = append(row, string(buffer.Bytes()))
row = append(row, MakeProfilingData(planNodeDesc, false))
} else {
row = append(row, "")
}
aaa := MakeOperatorInfo(planNodeDesc)
fmt.Println(aaa)
row = append(row, aaa)
rows = append(rows, row)
}
return rows
}

var columnInfo []string
if planNodeDesc.IsSetBranchInfo() {
branchInfo := planNodeDesc.GetBranchInfo()
columnInfo = append(columnInfo, fmt.Sprintf("branch: %t, nodeId: %d\n",
branchInfo.GetIsDoBranch(), branchInfo.GetConditionNodeID()))
}

outputVar := fmt.Sprintf("outputVar: %s", prettyFormatJsonString(planNodeDesc.GetOutputVar()))
columnInfo = append(columnInfo, outputVar)
// explain/profile format="tck"
func (res ResultSet) MakePlanByTck() [][]interface{} {
p := res.GetPlanDesc()
planNodeDescs := p.GetPlanNodeDescs()
var rows [][]interface{}
for _, planNodeDesc := range planNodeDescs {
var row []interface{}
row = append(row, planNodeDesc.GetId(), string(planNodeDesc.GetName()))

if planNodeDesc.IsSetDescription() {
desc := planNodeDesc.GetDescription()
for _, pair := range desc {
value := prettyFormatJsonString(pair.GetValue())
columnInfo = append(columnInfo, fmt.Sprintf("%s: %s", string(pair.GetKey()), value))
if planNodeDesc.IsSetDependencies() {
var deps []string
for _, dep := range planNodeDesc.GetDependencies() {
deps = append(deps, fmt.Sprintf("%d", dep))
}
row = append(row, strings.Join(deps, ","))
} else {
row = append(row, "")
}
row = append(row, strings.Join(columnInfo, "\n"))

if planNodeDesc.IsSetProfiles() {
var compactProfilingData bytes.Buffer
// compress JSON data and remove whitespace characters
json.Compact(&compactProfilingData, []byte(MakeProfilingData(planNodeDesc, true)))
row = append(row, compactProfilingData.String())
} else {
row = append(row, "")
}
// append operator info
row = append(row, "")

rows = append(rows, row)
}
return rows
Expand Down

0 comments on commit bf9fe21

Please sign in to comment.