From cb5fac206c118fdf7ff133bc8aeaae776be15b1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=A9=E5=B0=91?= Date: Tue, 15 May 2012 20:15:58 +0800 Subject: [PATCH] mysql enhance --- .../MySqlShowCharacterSetStatement.java | 37 ++++++++++ .../mysql/parser/MySqlStatementParser.java | 19 +++++ .../mysql/visitor/MySqlASTVisitor.java | 5 ++ .../mysql/visitor/MySqlASTVisitorAdapter.java | 11 +++ .../mysql/visitor/MySqlOutputVisitor.java | 20 ++++++ .../mysql/visitor/MySqlSchemaStatVisitor.java | 11 +++ .../druid/bvt/sql/cobar/DALParserTest.java | 71 ++++++++++--------- 7 files changed, 142 insertions(+), 32 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlShowCharacterSetStatement.java diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlShowCharacterSetStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlShowCharacterSetStatement.java new file mode 100644 index 0000000000..de6ebc4952 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlShowCharacterSetStatement.java @@ -0,0 +1,37 @@ +package com.alibaba.druid.sql.dialect.mysql.ast.statement; + +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; + +public class MySqlShowCharacterSetStatement extends MySqlStatementImpl { + + private static final long serialVersionUID = 1L; + + private SQLExpr where; + private SQLExpr pattern; + + public void accept0(MySqlASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, where); + acceptChild(visitor, pattern); + } + visitor.endVisit(this); + } + + public SQLExpr getWhere() { + return where; + } + + public void setWhere(SQLExpr where) { + this.where = where; + } + + public SQLExpr getPattern() { + return pattern; + } + + public void setPattern(SQLExpr pattern) { + this.pattern = pattern; + } + +} 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 eba47880bb..57a5337494 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 @@ -58,6 +58,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetTransactionIsol import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowAuthorsStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowBinLogEventsStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowBinaryLogsStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowCharacterSetStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowCollationStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowColumnsStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowDatabasesStatement; @@ -517,6 +518,24 @@ public class MySqlStatementParser extends SQLStatementParser { return new MySqlShowMasterLogsStatement(); } + if (identifierEquals("CHARACTER")) { + lexer.nextToken(); + accept(Token.SET); + MySqlShowCharacterSetStatement stmt = new MySqlShowCharacterSetStatement(); + + if (lexer.token() == Token.LIKE) { + lexer.nextToken(); + stmt.setPattern(this.exprParser.expr()); + } + + if (lexer.token() == Token.WHERE) { + lexer.nextToken(); + stmt.setWhere(this.exprParser.expr()); + } + + return stmt; + } + if (identifierEquals("COLLATION")) { lexer.nextToken(); MySqlShowCollationStatement stmt = new MySqlShowCollationStatement(); 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 9e2e0e3904..5116a783be 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 @@ -49,6 +49,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetTransactionIsol import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowAuthorsStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowBinLogEventsStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowBinaryLogsStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowCharacterSetStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowCollationStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowColumnsStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowDatabasesStatement; @@ -239,6 +240,10 @@ public interface MySqlASTVisitor extends SQLASTVisitor { void endVisit(MySqlShowMasterLogsStatement x); + boolean visit(MySqlShowCharacterSetStatement x); + + void endVisit(MySqlShowCharacterSetStatement x); + boolean visit(MySqlShowCollationStatement x); void endVisit(MySqlShowCollationStatement 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 f5825fe2fd..07b41ec7e2 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 @@ -36,6 +36,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetTransactionIsol import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowAuthorsStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowBinLogEventsStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowBinaryLogsStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowCharacterSetStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowCollationStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowColumnsStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowDatabasesStatement; @@ -531,4 +532,14 @@ public class MySqlASTVisitorAdapter extends SQLASTVisitorAdapter implements public void endVisit(MySqlShowBinLogEventsStatement x) { } + + @Override + public boolean visit(MySqlShowCharacterSetStatement x) { + return true; + } + + @Override + public void endVisit(MySqlShowCharacterSetStatement 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 3a338d94d4..e63c2adfdc 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 @@ -68,6 +68,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetTransactionIsol import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowAuthorsStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowBinLogEventsStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowBinaryLogsStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowCharacterSetStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowCollationStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowColumnsStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowDatabasesStatement; @@ -1555,4 +1556,23 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV public void endVisit(MySqlShowBinLogEventsStatement x) { } + + @Override + public boolean visit(MySqlShowCharacterSetStatement x) { + print("SHOW CHARACTER SET"); + if (x.getPattern() != null) { + print(" LIKE "); + x.getPattern().accept(this); + } + if (x.getWhere() != null) { + print(" WHERE "); + x.getWhere().accept(this); + } + return false; + } + + @Override + public void endVisit(MySqlShowCharacterSetStatement 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 4f1088e1b7..953f943ca2 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 @@ -45,6 +45,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetTransactionIsol import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowAuthorsStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowBinLogEventsStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowBinaryLogsStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowCharacterSetStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowCollationStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowColumnsStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowDatabasesStatement; @@ -593,4 +594,14 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS public void endVisit(MySqlShowBinLogEventsStatement x) { } + + @Override + public boolean visit(MySqlShowCharacterSetStatement x) { + return false; + } + + @Override + public void endVisit(MySqlShowCharacterSetStatement 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 84c8bfcd28..221938be51 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 @@ -15,6 +15,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetTransactionIsol import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowAuthorsStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowBinLogEventsStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowBinaryLogsStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowCharacterSetStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowCollationStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowMasterLogsStatement; import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; @@ -224,6 +225,15 @@ public class DALParserTest extends TestCase { Assert.assertEquals("SHOW COLLATION WHERE `Default` = 'Yes'", output); } + public void test_show_collation_3() throws Exception { + String sql = "SHOW collation where Collation like 'big5%'"; + MySqlStatementParser parser = new MySqlStatementParser(sql); + MySqlShowCollationStatement show = (MySqlShowCollationStatement) parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(show); + Assert.assertEquals("SHOW COLLATION WHERE Collation LIKE 'big5%'", output); + } + public void test_binaryLog() throws Exception { String sql = "SHOW binlog events in 'a' from 1 limit 1,2 "; MySqlStatementParser parser = new MySqlStatementParser(sql); @@ -251,41 +261,38 @@ public class DALParserTest extends TestCase { Assert.assertEquals("SHOW BINLOG EVENTS", output); } + public void test_show_character_set() throws Exception { + String sql = "SHOW CHARACTER SET like 'var' "; + MySqlStatementParser parser = new MySqlStatementParser(sql); + MySqlShowCharacterSetStatement show = (MySqlShowCharacterSetStatement) parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(show); + Assert.assertEquals("SHOW CHARACTER SET LIKE 'var'", output); + } + + + public void test_show_character_set_1() throws Exception { + String sql = "SHOW CHARACTER SET where Charset = 'big5'"; + MySqlStatementParser parser = new MySqlStatementParser(sql); + MySqlShowCharacterSetStatement show = (MySqlShowCharacterSetStatement) parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(show); + Assert.assertEquals("SHOW CHARACTER SET WHERE Charset = 'big5'", output); + } + + + public void test_show_character_set_2() throws Exception { + String sql = "SHOW CHARACTER SET"; + MySqlStatementParser parser = new MySqlStatementParser(sql); + MySqlShowCharacterSetStatement show = (MySqlShowCharacterSetStatement) parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(show); + Assert.assertEquals("SHOW CHARACTER SET", output); + } + // // public void testShow() throws Exception { // -// sql = "SHOW CHARACTER SET like 'var' "; -// 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 CHARACTER SET LIKE 'var'", output); -// -// sql = "SHOW CHARACTER SET where (select a from tb)in(a) "; -// 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 CHARACTER SET WHERE (SELECT a FROM tb) IN (a)", output); -// -// sql = "SHOW CHARACTER SET "; -// 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 CHARACTER SET", output); -// -// sql = "SHOW collation where avg((select * from (tb1,tb2)))!=100 "; -// 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 COLLATION WHERE AVG(SELECT * FROM tb1, tb2) != 100", output); -// // sql = "SHOW full columns from tb1 from db1 like 'var' "; // lexer = new SQLLexer(sql); // parser = new DALParser(lexer, new SQLExprParser(lexer));