diff --git a/executor/trace.go b/executor/trace.go index 9d30e21ebd94d..f5fa27b5917d5 100644 --- a/executor/trace.go +++ b/executor/trace.go @@ -179,6 +179,18 @@ func dfsTree(t *appdash.Trace, prefix string, isLast bool, chk *chunk.Chunk) { chk.AppendString(1, start.Format("15:04:05.000000")) chk.AppendString(2, duration.String()) + // Sort events by their start time + sort.Slice(t.Sub, func(i, j int) bool { + var istart, jstart time.Time + if ievent, err := t.Sub[i].TimespanEvent(); err == nil { + istart = ievent.Start() + } + if jevent, err := t.Sub[j].TimespanEvent(); err == nil { + jstart = jevent.Start() + } + return istart.Before(jstart) + }) + for i, sp := range t.Sub { dfsTree(sp, newPrefix, i == (len(t.Sub))-1 /*last element of array*/, chk) } diff --git a/executor/trace_test.go b/executor/trace_test.go index fe60b58692cd5..d1e19e210dd5a 100644 --- a/executor/trace_test.go +++ b/executor/trace_test.go @@ -14,6 +14,8 @@ package executor_test import ( + "strings" + . "github.com/pingcap/check" "github.com/pingcap/tidb/util/testkit" ) @@ -39,6 +41,29 @@ func (s *testSuite1) TestTraceExec(c *C) { // | └─recordSet.Next | 22:08:38.249340 | 155.317µs | // +---------------------------+-----------------+------------+ rows = tk.MustQuery("trace format='row' select * from trace where id = 0;").Rows() - c.Assert(len(rows) > 1, IsTrue) + c.Assert(rowsOrdered(rows), IsTrue) +} + +func rowsOrdered(rows [][]interface{}) (ordered bool) { + for idx := range rows { + if idx == 0 || !isSibling(rows[idx-1][0].(string), rows[idx][0].(string)) { + continue + } + + if rows[idx-1][1].(string) > rows[idx][1].(string) { + return false + } + } + return true +} + +func isSibling(x string, y string) bool { + indexF := func(c rune) bool { + if (c < 'a' || c > 'z') && (c < 'A' || c > 'Z') { + return false + } + return true + } + return strings.IndexFunc(x, indexF) == strings.IndexFunc(y, indexF) }