From 0ee992863716aa06b8e9637f73a715e2255b99e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=A9=E5=B0=91?= Date: Thu, 17 May 2012 21:43:50 +0800 Subject: [PATCH] refactor --- .../statement/MySqlLockTableStatement.java | 51 +++++++++++++++++++ .../mysql/parser/MySqlStatementParser.java | 41 ++++++++++----- .../mysql/visitor/MySqlASTVisitor.java | 5 ++ .../mysql/visitor/MySqlASTVisitorAdapter.java | 11 ++++ .../mysql/visitor/MySqlOutputVisitor.java | 17 +++++++ .../mysql/visitor/MySqlSchemaStatVisitor.java | 11 ++++ .../druid/sql/parser/SQLStatementParser.java | 8 +-- .../druid/bvt/sql/cobar/MTSParserTest.java | 18 +++++++ 8 files changed, 146 insertions(+), 16 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlLockTableStatement.java diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlLockTableStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlLockTableStatement.java new file mode 100644 index 0000000000..8c1053e682 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlLockTableStatement.java @@ -0,0 +1,51 @@ +package com.alibaba.druid.sql.dialect.mysql.ast.statement; + +import com.alibaba.druid.sql.ast.SQLName; +import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; + +public class MySqlLockTableStatement extends MySqlStatementImpl { + + private static final long serialVersionUID = 1L; + + private SQLExprTableSource tableSource; + + private LockType lockType; + + public SQLExprTableSource getTableSource() { + return tableSource; + } + + public void setTableSource(SQLExprTableSource tableSource) { + this.tableSource = tableSource; + } + + public void setTableSource(SQLName name) { + this.tableSource = new SQLExprTableSource(name); + } + + public LockType getLockType() { + return lockType; + } + + public void setLockType(LockType lockType) { + this.lockType = lockType; + } + + public void accept0(MySqlASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, tableSource); + } + visitor.endVisit(this); + } + + public static enum LockType { + READ("READ"), READ_LOCAL("READ LOCAL"), WRITE("WRITE"), LOW_PRIORITY_WRITE("LOW_PRIORITY WRITE"); + + public final String name; + + LockType(String name){ + this.name = name; + } + } +} 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 0aa67f0a82..c3305e1072 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 @@ -55,6 +55,8 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlKillStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadDataInFileStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadXmlStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLockTableStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLockTableStatement.LockType; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPrepareStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRenameTableStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplicateStatement; @@ -476,18 +478,6 @@ public class MySqlStatementParser extends SQLStatementParser { return true; } - if (identifierEquals("COMMIT")) { - MySqlCommitStatement stmt = parseCommit(); - statementList.add(stmt); - return true; - } - - if (identifierEquals("ROLLBACK")) { - MySqlRollbackStatement stmt = parseRollback(); - statementList.add(stmt); - return true; - } - if (identifierEquals("SHOW")) { SQLStatement stmt = parseShow(); statementList.add(stmt); @@ -511,6 +501,33 @@ public class MySqlStatementParser extends SQLStatementParser { statementList.add(stmt); return true; } + + if (lexer.token() == Token.LOCK) { + lexer.nextToken(); + acceptIdentifier("TABLES"); + + MySqlLockTableStatement stmt = new MySqlLockTableStatement(); + stmt.setTableSource(this.exprParser.name()); + + if (identifierEquals("READ")) { + lexer.nextToken(); + if (identifierEquals("LOCAL")) { + lexer.nextToken(); + stmt.setLockType(LockType.READ_LOCAL); + } else { + stmt.setLockType(LockType.READ); + } + } else if (identifierEquals("WRITE")) { + stmt.setLockType(LockType.WRITE); + } else if (identifierEquals("LOW_PRIORITY")) { + lexer.nextToken(); + acceptIdentifier("WRITE"); + stmt.setLockType(LockType.LOW_PRIORITY_WRITE); + } + + statementList.add(stmt); + return true; + } return false; } 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 0a29239179..03d19758df 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 @@ -43,6 +43,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlKillStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadDataInFileStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadXmlStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLockTableStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPartitionByKey; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPrepareStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRenameTableStatement; @@ -460,4 +461,8 @@ public interface MySqlASTVisitor extends SQLASTVisitor { boolean visit(MySqlIgnoreIndexHint x); void endVisit(MySqlIgnoreIndexHint x); + + boolean visit(MySqlLockTableStatement x); + + void endVisit(MySqlLockTableStatement 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 090358c0ad..998746518a 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 @@ -29,6 +29,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlKillStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadDataInFileStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadXmlStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLockTableStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPartitionByKey; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPrepareStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRenameTableStatement; @@ -1002,4 +1003,14 @@ public class MySqlASTVisitorAdapter extends SQLASTVisitorAdapter implements public void endVisit(MySqlIgnoreIndexHint x) { } + + @Override + public boolean visit(MySqlLockTableStatement x) { + return true; + } + + @Override + public void endVisit(MySqlLockTableStatement 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 25bb2a4081..db0448c2e0 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 @@ -62,6 +62,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlKillStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadDataInFileStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadXmlStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLockTableStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPartitionByKey; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPrepareStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRenameTableStatement; @@ -2441,4 +2442,20 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV return false; } + + @Override + public boolean visit(MySqlLockTableStatement x) { + print("LOCK TABLES "); + x.getTableSource().accept(this); + if (x.getLockType() != null) { + print(' '); + print(x.getLockType().name); + } + return false; + } + + @Override + public void endVisit(MySqlLockTableStatement 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 5b31abced1..3f31f0ec35 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 @@ -39,6 +39,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlKillStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadDataInFileStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadXmlStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLockTableStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPartitionByKey; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPrepareStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRenameTableStatement; @@ -1066,4 +1067,14 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS public void endVisit(MySqlIgnoreIndexHint x) { } + + @Override + public boolean visit(MySqlLockTableStatement x) { + return false; + } + + @Override + public void endVisit(MySqlLockTableStatement x) { + + } } diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java index 296deb7b9a..b5c42a2476 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java @@ -187,10 +187,6 @@ public class SQLStatementParser extends SQLParser { continue; } - if (parseStatementListDialect(statementList)) { - continue; - } - if (lexer.token() == Token.LPAREN) { char mark_ch = lexer.current(); int mark_bp = lexer.bp(); @@ -202,6 +198,10 @@ public class SQLStatementParser extends SQLParser { continue; } } + + if (parseStatementListDialect(statementList)) { + continue; + } throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/cobar/MTSParserTest.java b/src/test/java/com/alibaba/druid/bvt/sql/cobar/MTSParserTest.java index 0576ce94f3..c75185865b 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/cobar/MTSParserTest.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/cobar/MTSParserTest.java @@ -72,4 +72,22 @@ public class MTSParserTest extends TestCase { String output = SQLUtils.toMySqlString(stmt); Assert.assertEquals("ROLLBACK TO x1", output); } + + public void test_lockTable() throws Exception { + String sql = "LOCK TABLES t1 READ;"; + MySqlStatementParser parser = new MySqlStatementParser(sql); + SQLStatement stmt = parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(stmt); + Assert.assertEquals("LOCK TABLES t1 READ", output); + } + + public void test_lockTable_1() throws Exception { + String sql = "LOCK TABLES t2 READ LOCAL;"; + MySqlStatementParser parser = new MySqlStatementParser(sql); + SQLStatement stmt = parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(stmt); + Assert.assertEquals("LOCK TABLES t2 READ LOCAL", output); + } }