Skip to content

Commit

Permalink
*: adding trace syntax support (pingcap#6644)
Browse files Browse the repository at this point in the history
  • Loading branch information
zhexuany authored and coocood committed Jun 3, 2018
1 parent 941f118 commit e2b2361
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 6 deletions.
23 changes: 23 additions & 0 deletions ast/misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,29 @@ type AuthOption struct {
// TODO: support auth_plugin
}

// TraceStmt is a statement to trace what sql actually does at background.
type TraceStmt struct {
stmtNode

Stmt StmtNode
Format string
}

// Accept implements Node Accept interface.
func (n *TraceStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*TraceStmt)
node, ok := n.Stmt.Accept(v)
if !ok {
return n, false
}
n.Stmt = node.(DMLNode)
return v.Leave(n)
}

// ExplainStmt is a statement to provide information about how is SQL statement executed
// or get columns information in a table.
// See https://dev.mysql.com/doc/refman/5.7/en/explain.html
Expand Down
8 changes: 4 additions & 4 deletions parser/consistent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@ func (s *testConsistentSuite) TestKeywordConsistent(c *C) {
keywordCount := len(reservedKeywords) + len(unreservedKeywords) + len(notKeywordTokens) + len(tidbKeywords)
c.Assert(len(tokenMap)-len(aliases), Equals, keywordCount)

unreservedCollectionDef := extratKeywordsFromCollectionDef(content, "\nUnReservedKeyword:")
unreservedCollectionDef := extractKeywordsFromCollectionDef(content, "\nUnReservedKeyword:")
c.Assert(unreservedKeywords, DeepEquals, unreservedCollectionDef)

notKeywordTokensCollectionDef := extratKeywordsFromCollectionDef(content, "\nNotKeywordToken:")
notKeywordTokensCollectionDef := extractKeywordsFromCollectionDef(content, "\nNotKeywordToken:")
c.Assert(notKeywordTokens, DeepEquals, notKeywordTokensCollectionDef)

tidbKeywordsCollectionDef := extratKeywordsFromCollectionDef(content, "\nTiDBKeyword:")
tidbKeywordsCollectionDef := extractKeywordsFromCollectionDef(content, "\nTiDBKeyword:")
c.Assert(tidbKeywords, DeepEquals, tidbKeywordsCollectionDef)
}

Expand Down Expand Up @@ -101,7 +101,7 @@ func extractKeywords(content, startMarker, endMarker string) []string {
return extractQuotedWords(lines)
}

func extratKeywordsFromCollectionDef(content, startMarker string) []string {
func extractKeywordsFromCollectionDef(content, startMarker string) []string {
keywordSection := extractMiddle(content, startMarker, "\n\n")
words := strings.Split(keywordSection, "|")
return extractQuotedWords(words)
Expand Down
1 change: 1 addition & 0 deletions parser/misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@ var tokenMap = map[string]int{
"TINYINT": tinyIntType,
"TINYTEXT": tinytextType,
"TO": to,
"TRACE": trace,
"TRAILING": trailing,
"TRANSACTION": transaction,
"TRIGGER": trigger,
Expand Down
25 changes: 23 additions & 2 deletions parser/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,7 @@ import (
than "THAN"
timeType "TIME"
timestampType "TIMESTAMP"
trace "TRACE"
transaction "TRANSACTION"
triggers "TRIGGERS"
truncate "TRUNCATE"
Expand Down Expand Up @@ -541,6 +542,7 @@ import (
EmptyStmt "empty statement"
ExecuteStmt "Execute statement"
ExplainStmt "EXPLAIN statement"
ExplainableStmt "explainable statement"
FlushStmt "Flush statement"
GrantStmt "Grant statement"
InsertIntoStmt "INSERT INTO statement"
Expand All @@ -557,7 +559,8 @@ import (
SetStmt "Set variable statement"
ShowStmt "Show engines/databases/tables/columns/warnings/status statement"
Statement "statement"
ExplainableStmt "explainable statement"
TraceStmt "TRACE statement"
TraceableStmt "traceable statment"
TruncateTableStmt "TRUNCATE TABLE statement"
UnlockTablesStmt "Unlock tables statement"
UpdateStmt "UPDATE statement"
Expand Down Expand Up @@ -2129,6 +2132,15 @@ EmptyStmt:
$$ = nil
}

TraceStmt:
"TRACE" TraceableStmt
{
$$ = &ast.TraceStmt{
Stmt: $2,
Format: "row",
}
}

ExplainSym:
"EXPLAIN" | "DESCRIBE" | "DESC"

Expand Down Expand Up @@ -2668,7 +2680,7 @@ UnReservedKeyword:
| "DYNAMIC"| "END" | "ENGINE" | "ENGINES" | "ENUM" | "ESCAPE" | "EXECUTE" | "FIELDS" | "FIRST" | "FIXED" | "FLUSH" | "FORMAT" | "FULL" |"GLOBAL"
| "HASH" | "HOUR" | "LESS" | "LOCAL" | "NAMES" | "OFFSET" | "PASSWORD" %prec lowerThanEq | "PREPARE" | "QUICK" | "REDUNDANT"
| "ROLLBACK" | "SESSION" | "SIGNED" | "SNAPSHOT" | "START" | "STATUS" | "TABLES" | "TEXT" | "THAN" | "TIME" %prec lowerThanStringLitToken | "TIMESTAMP" %prec lowerThanStringLitToken
| "TRANSACTION" | "TRUNCATE" | "UNKNOWN" | "VALUE" | "WARNINGS" | "YEAR" | "MODE" | "WEEK" | "ANY" | "SOME" | "USER" | "IDENTIFIED"
| "TRACE" | "TRANSACTION" | "TRUNCATE" | "UNKNOWN" | "VALUE" | "WARNINGS" | "YEAR" | "MODE" | "WEEK" | "ANY" | "SOME" | "USER" | "IDENTIFIED"
| "COLLATION" | "COMMENT" | "AVG_ROW_LENGTH" | "CONNECTION" | "CHECKSUM" | "COMPRESSION" | "KEY_BLOCK_SIZE" | "MAX_ROWS"
| "MIN_ROWS" | "NATIONAL" | "ROW" | "ROW_FORMAT" | "QUARTER" | "GRANTS" | "TRIGGERS" | "DELAY_KEY_WRITE" | "ISOLATION" | "JSON"
| "REPEATABLE" | "COMMITTED" | "UNCOMMITTED" | "ONLY" | "SERIALIZABLE" | "LEVEL" | "VARIABLES" | "SQL_CACHE" | "INDEXES" | "PROCESSLIST"
Expand Down Expand Up @@ -5478,12 +5490,21 @@ Statement:
// TODO: This is used to fix issue #320. There may be a better solution.
$$ = $1.(*ast.SubqueryExpr).Query.(ast.StmtNode)
}
| TraceStmt
| TruncateTableStmt
| UpdateStmt
| UseStmt
| UnlockTablesStmt
| LockTablesStmt

TraceableStmt:
SelectStmt
| DeleteFromStmt
| UpdateStmt
| InsertIntoStmt
| ReplaceIntoStmt
| UnionStmt

ExplainableStmt:
SelectStmt
| DeleteFromStmt
Expand Down
13 changes: 13 additions & 0 deletions parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2066,6 +2066,19 @@ func (s *testParserSuite) TestExplain(c *C) {
s.RunTest(c, table)
}

func (s *testParserSuite) TestTrace(c *C) {
defer testleak.AfterTest(c)()
table := []testCase{
{"trace select c1 from t1", true},
{"trace delete t1, t2 from t1 inner join t2 inner join t3 where t1.id=t2.id and t2.id=t3.id;", true},
{"trace insert into t values (1), (2), (3)", true},
{"trace replace into foo values (1 || 2)", true},
{"trace update t set id = id + 1 order by id desc;", true},
{"trace select c1 from t1 union (select c2 from t2) limit 1, 1", true},
}
s.RunTest(c, table)
}

func (s *testParserSuite) TestView(c *C) {
defer testleak.AfterTest(c)()
table := []testCase{
Expand Down

0 comments on commit e2b2361

Please sign in to comment.