From 009a426ce994611849e38090392bffdc615a0d17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=A9=E5=B0=91?= Date: Wed, 16 May 2012 12:37:10 +0800 Subject: [PATCH] mysql parser show --- .../statement/MySqlShowProfileStatement.java | 60 +++++++++++++++++ .../statement/MySqlShowProfilesStatement.java | 13 ++++ .../mysql/parser/MySqlStatementParser.java | 65 +++++++++++++++++++ .../mysql/visitor/MySqlASTVisitor.java | 10 +++ .../mysql/visitor/MySqlASTVisitorAdapter.java | 22 +++++++ .../mysql/visitor/MySqlOutputVisitor.java | 42 ++++++++++++ .../mysql/visitor/MySqlSchemaStatVisitor.java | 22 +++++++ .../druid/bvt/sql/cobar/DALParserTest.java | 54 ++++++++------- 8 files changed, 264 insertions(+), 24 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlShowProfileStatement.java create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlShowProfilesStatement.java diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlShowProfileStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlShowProfileStatement.java new file mode 100644 index 0000000000..3e033309df --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlShowProfileStatement.java @@ -0,0 +1,60 @@ +package com.alibaba.druid.sql.dialect.mysql.ast.statement; + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock.Limit; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; + +public class MySqlShowProfileStatement extends MySqlStatementImpl { + + private static final long serialVersionUID = 1L; + + private List types = new ArrayList(); + + private SQLExpr forQuery; + + private Limit limit; + + public void accept0(MySqlASTVisitor visitor) { + visitor.visit(this); + visitor.endVisit(this); + } + + public List getTypes() { + return types; + } + + public void setTypes(List types) { + this.types = types; + } + + public SQLExpr getForQuery() { + return forQuery; + } + + public void setForQuery(SQLExpr forQuery) { + this.forQuery = forQuery; + } + + public Limit getLimit() { + return limit; + } + + public void setLimit(Limit limit) { + this.limit = limit; + } + + public static enum Type { + ALL("ALL"), BLOCK_IO("BLOCK IO"), CONTEXT_SWITCHES("CONTEXT SWITCHES"), CPU("CPU"), IPC("IPC"), + MEMORY("MEMORY"), PAGE_FAULTS("PAGE FAULTS"), SOURCE("SOURCE"), SWAPS("SWAPS"); + + public final String name; + + Type(String name){ + this.name = name; + } + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlShowProfilesStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlShowProfilesStatement.java new file mode 100644 index 0000000000..7322b8a6f6 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlShowProfilesStatement.java @@ -0,0 +1,13 @@ +package com.alibaba.druid.sql.dialect.mysql.ast.statement; + +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; + +public class MySqlShowProfilesStatement extends MySqlStatementImpl { + + private static final long serialVersionUID = 1L; + + public void accept0(MySqlASTVisitor visitor) { + visitor.visit(this); + visitor.endVisit(this); + } +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java index 0ded2ff33b..1f11ae57a5 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java @@ -88,6 +88,8 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowPrivilegesStat import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProcedureCodeStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProcedureStatusStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProcessListStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProfileStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProfilesStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowStatusStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowTablesStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowWarningsStatement; @@ -877,6 +879,69 @@ public class MySqlStatementParser extends SQLStatementParser { MySqlShowProcessListStatement stmt = new MySqlShowProcessListStatement(); return stmt; } + + if (identifierEquals("PROFILES")) { + lexer.nextToken(); + MySqlShowProfilesStatement stmt = new MySqlShowProfilesStatement(); + return stmt; + } + + if (identifierEquals("PROFILE")) { + lexer.nextToken(); + MySqlShowProfileStatement stmt = new MySqlShowProfileStatement(); + + for (;;) { + if (lexer.token() == Token.ALL) { + stmt.getTypes().add(MySqlShowProfileStatement.Type.ALL); + lexer.nextToken(); + } else if (identifierEquals("BLOCK")) { + lexer.nextToken(); + acceptIdentifier("IO"); + stmt.getTypes().add(MySqlShowProfileStatement.Type.BLOCK_IO); + } else if (identifierEquals("CONTEXT")) { + lexer.nextToken(); + acceptIdentifier("SWITCHES"); + stmt.getTypes().add(MySqlShowProfileStatement.Type.CONTEXT_SWITCHES); + } else if (identifierEquals("CPU")) { + lexer.nextToken(); + stmt.getTypes().add(MySqlShowProfileStatement.Type.CPU); + } else if (identifierEquals("IPC")) { + lexer.nextToken(); + stmt.getTypes().add(MySqlShowProfileStatement.Type.IPC); + } else if (identifierEquals("MEMORY")) { + lexer.nextToken(); + stmt.getTypes().add(MySqlShowProfileStatement.Type.MEMORY); + } else if (identifierEquals("PAGE")) { + lexer.nextToken(); + acceptIdentifier("FAULTS"); + stmt.getTypes().add(MySqlShowProfileStatement.Type.PAGE_FAULTS); + } else if (identifierEquals("SOURCE")) { + lexer.nextToken(); + stmt.getTypes().add(MySqlShowProfileStatement.Type.SOURCE); + } else if (identifierEquals("SWAPS")) { + lexer.nextToken(); + stmt.getTypes().add(MySqlShowProfileStatement.Type.SWAPS); + } else { + break; + } + + if (lexer.token() == Token.COMMA) { + lexer.nextToken(); + continue; + } + break; + } + + if (lexer.token() == Token.FOR) { + lexer.nextToken(); + acceptIdentifier("QUERY"); + stmt.setForQuery(this.exprParser.primary()); + } + + stmt.setLimit(this.parseLimit()); + + return stmt; + } throw new ParserException("TODO " + lexer.stringVal()); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitor.java index 7843cc54f4..6df639ab08 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitor.java @@ -79,6 +79,8 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowPrivilegesStat import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProcedureCodeStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProcedureStatusStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProcessListStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProfileStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProfilesStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowStatusStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowTablesStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowWarningsStatement; @@ -376,4 +378,12 @@ public interface MySqlASTVisitor extends SQLASTVisitor { boolean visit(MySqlShowProcessListStatement x); void endVisit(MySqlShowProcessListStatement x); + + boolean visit(MySqlShowProfileStatement x); + + void endVisit(MySqlShowProfileStatement x); + + boolean visit(MySqlShowProfilesStatement x); + + void endVisit(MySqlShowProfilesStatement x); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitorAdapter.java index abf1cc7801..94191b8fd0 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitorAdapter.java @@ -66,6 +66,8 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowPrivilegesStat import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProcedureCodeStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProcedureStatusStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProcessListStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProfileStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProfilesStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowStatusStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowTablesStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowWarningsStatement; @@ -816,4 +818,24 @@ public class MySqlASTVisitorAdapter extends SQLASTVisitorAdapter implements public void endVisit(MySqlShowProcessListStatement x) { } + + @Override + public boolean visit(MySqlShowProfileStatement x) { + return true; + } + + @Override + public void endVisit(MySqlShowProfileStatement x) { + + } + + @Override + public boolean visit(MySqlShowProfilesStatement x) { + return true; + } + + @Override + public void endVisit(MySqlShowProfilesStatement x) { + + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java index c0aa98e5e5..33e16a79c0 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java @@ -98,6 +98,8 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowPrivilegesStat import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProcedureCodeStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProcedureStatusStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProcessListStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProfileStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProfilesStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowStatusStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowTablesStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowWarningsStatement; @@ -1979,4 +1981,44 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV public void endVisit(MySqlShowProcessListStatement x) { } + + @Override + public boolean visit(MySqlShowProfileStatement x) { + print("SHOW PROFILE"); + for (int i = 0; i < x.getTypes().size(); ++i) { + if (i == 0) { + print(' '); + } else { + print(", "); + } + print(x.getTypes().get(i).name); + } + + if (x.getForQuery() != null) { + print(" FOR QUERY "); + x.getForQuery().accept(this); + } + + if (x.getLimit() != null) { + print(' '); + x.getLimit().accept(this); + } + return false; + } + + @Override + public void endVisit(MySqlShowProfileStatement x) { + + } + + @Override + public boolean visit(MySqlShowProfilesStatement x) { + print("SHOW PROFILES"); + return false; + } + + @Override + public void endVisit(MySqlShowProfilesStatement x) { + + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java index a94fd3b6d6..3aa5813056 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java @@ -75,6 +75,8 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowPrivilegesStat import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProcedureCodeStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProcedureStatusStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProcessListStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProfileStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProfilesStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowStatusStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowTablesStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowWarningsStatement; @@ -879,4 +881,24 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS public void endVisit(MySqlShowProcessListStatement x) { } + + @Override + public boolean visit(MySqlShowProfileStatement x) { + return false; + } + + @Override + public void endVisit(MySqlShowProfileStatement x) { + + } + + @Override + public boolean visit(MySqlShowProfilesStatement x) { + return false; + } + + @Override + public void endVisit(MySqlShowProfilesStatement x) { + + } } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/cobar/DALParserTest.java b/src/test/java/com/alibaba/druid/bvt/sql/cobar/DALParserTest.java index 88ea48c767..a7905490ea 100755 --- a/src/test/java/com/alibaba/druid/bvt/sql/cobar/DALParserTest.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/cobar/DALParserTest.java @@ -44,6 +44,8 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowPrivilegesStat import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProcedureCodeStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProcedureStatusStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProcessListStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProfileStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProfilesStatement; import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; import com.alibaba.druid.sql.parser.Token; @@ -828,35 +830,39 @@ public class DALParserTest extends TestCase { String output = SQLUtils.toMySqlString(show); Assert.assertEquals("SHOW FULL PROCESSLIST", output); } + + public void test_show_profiles() throws Exception { + String sql = "SHOW profiles"; + MySqlStatementParser parser = new MySqlStatementParser(sql); + MySqlShowProfilesStatement show = (MySqlShowProfilesStatement) parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(show); + Assert.assertEquals("SHOW PROFILES", output); + } + + + public void test_show_profile() throws Exception { + String sql = "SHOW profile"; + MySqlStatementParser parser = new MySqlStatementParser(sql); + MySqlShowProfileStatement show = (MySqlShowProfileStatement) parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(show); + Assert.assertEquals("SHOW PROFILE", output); + } + + public void test_show_profile_1() throws Exception { + String sql = "SHOW profile all,block io,context switches,cpu,ipc,memory, page faults,source,swaps for query 2 limit 1 offset 2"; + MySqlStatementParser parser = new MySqlStatementParser(sql); + MySqlShowProfileStatement show = (MySqlShowProfileStatement) parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(show); + Assert.assertEquals("SHOW PROFILE ALL, BLOCK IO, CONTEXT SWITCHES, CPU, IPC, MEMORY, PAGE FAULTS, SOURCE, SWAPS FOR QUERY 2 LIMIT 2, 1", output); + } // // public void testShow() throws Exception { // -// sql = "SHOW processlist"; -// lexer = new SQLLexer(sql); -// parser = new DALParser(lexer, new SQLExprParser(lexer)); -// show = (DALShowStatement) parser.show(); -// parser.match(Token.EOF); -// output = output2MySQL(show, sql); -// Assert.assertEquals("SHOW PROCESSLIST", output); -// -// sql = "SHOW full processlist"; -// lexer = new SQLLexer(sql); -// parser = new DALParser(lexer, new SQLExprParser(lexer)); -// show = (DALShowStatement) parser.show(); -// parser.match(Token.EOF); -// output = output2MySQL(show, sql); -// Assert.assertEquals("SHOW FULL PROCESSLIST", output); -// -// sql = "SHOW profiles"; -// lexer = new SQLLexer(sql); -// parser = new DALParser(lexer, new SQLExprParser(lexer)); -// show = (DALShowStatement) parser.show(); -// parser.match(Token.EOF); -// output = output2MySQL(show, sql); -// Assert.assertEquals("SHOW PROFILES", output); -// // sql = // "SHOW profile all,block io,context switches,cpu,ipc,memory," // + "page faults,source,swaps for query 2 limit 1 offset 2";