diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSetTransactionIsolationLevelStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSetTransactionStatement.java similarity index 68% rename from src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSetTransactionIsolationLevelStatement.java rename to src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSetTransactionStatement.java index 1761a02156..325556d9c9 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSetTransactionIsolationLevelStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSetTransactionStatement.java @@ -17,19 +17,13 @@ package com.alibaba.druid.sql.dialect.mysql.ast.statement; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; -public class MySqlSetTransactionIsolationLevelStatement extends MySqlStatementImpl { +public class MySqlSetTransactionStatement extends MySqlStatementImpl { private Boolean global; - private String level; + private String isolationLevel; - public String getLevel() { - return level; - } - - public void setLevel(String level) { - this.level = level; - } + private String accessModel; public void accept0(MySqlASTVisitor visitor) { visitor.visit(this); @@ -44,4 +38,20 @@ public class MySqlSetTransactionIsolationLevelStatement extends MySqlStatementIm this.global = global; } + public String getIsolationLevel() { + return isolationLevel; + } + + public void setIsolationLevel(String isolationLevel) { + this.isolationLevel = isolationLevel; + } + + public String getAccessModel() { + return accessModel; + } + + public void setAccessModel(String accessModel) { + this.accessModel = accessModel; + } + } 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 84d25de089..183e9e9743 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 @@ -95,7 +95,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock.L import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetCharSetStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetNamesStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetPasswordStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetTransactionIsolationLevelStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetTransactionStatement; 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; @@ -2090,44 +2090,57 @@ public class MySqlStatementParser extends SQLStatementParser { } if (identifierEquals("TRANSACTION")) { - lexer.nextToken(); - acceptIdentifier("ISOLATION"); - acceptIdentifier("LEVEL"); - - MySqlSetTransactionIsolationLevelStatement stmt = new MySqlSetTransactionIsolationLevelStatement(); + MySqlSetTransactionStatement stmt = new MySqlSetTransactionStatement(); stmt.setGlobal(global); + + lexer.nextToken(); + if(identifierEquals("ISOLATION")) { + lexer.nextToken(); + acceptIdentifier("LEVEL"); - if (identifierEquals(READ)) { - lexer.nextToken(); - - if (identifierEquals("UNCOMMITTED")) { - stmt.setLevel("READ UNCOMMITTED"); - lexer.nextToken(); - } else if (identifierEquals(WRITE)) { - stmt.setLevel("READ WRITE"); - lexer.nextToken(); - } else if (identifierEquals("ONLY")) { - stmt.setLevel("READ ONLY"); - lexer.nextToken(); - } else if (identifierEquals("COMMITTED")) { - stmt.setLevel("READ COMMITTED"); - lexer.nextToken(); - } else { - throw new ParserException("UNKOWN TRANSACTION LEVEL : " + lexer.stringVal()); - } - } else if (identifierEquals("SERIALIZABLE")) { - stmt.setLevel("SERIALIZABLE"); - lexer.nextToken(); - } else if (identifierEquals("REPEATABLE")) { - lexer.nextToken(); if (identifierEquals(READ)) { - stmt.setLevel("REPEATABLE READ"); lexer.nextToken(); + + if (identifierEquals("UNCOMMITTED")) { + stmt.setIsolationLevel("READ UNCOMMITTED"); + lexer.nextToken(); + } else if (identifierEquals(WRITE)) { + stmt.setIsolationLevel("READ WRITE"); + lexer.nextToken(); + } else if (identifierEquals("ONLY")) { + stmt.setIsolationLevel("READ ONLY"); + lexer.nextToken(); + } else if (identifierEquals("COMMITTED")) { + stmt.setIsolationLevel("READ COMMITTED"); + lexer.nextToken(); + } else { + throw new ParserException("UNKOWN TRANSACTION LEVEL : " + lexer.stringVal()); + } + } else if (identifierEquals("SERIALIZABLE")) { + stmt.setIsolationLevel("SERIALIZABLE"); + lexer.nextToken(); + } else if (identifierEquals("REPEATABLE")) { + lexer.nextToken(); + if (identifierEquals(READ)) { + stmt.setIsolationLevel("REPEATABLE READ"); + lexer.nextToken(); + } else { + throw new ParserException("UNKOWN TRANSACTION LEVEL : " + lexer.stringVal()); + } } else { throw new ParserException("UNKOWN TRANSACTION LEVEL : " + lexer.stringVal()); } - } else { - throw new ParserException("UNKOWN TRANSACTION LEVEL : " + lexer.stringVal()); + } else if (identifierEquals(READ)) { + lexer.nextToken(); + if (identifierEquals("ONLY")) { + stmt.setAccessModel("ONLY"); + lexer.nextToken(); + } else if (identifierEquals("WRITE")) { + stmt.setAccessModel("WRITE"); + lexer.nextToken(); + } else { + throw new ParserException("UNKOWN ACCESS MODEL : " + lexer.stringVal()); + } } return stmt; 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 01d996651f..f2260f392f 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 @@ -71,7 +71,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetCharSetStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetNamesStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetPasswordStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetTransactionIsolationLevelStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetTransactionStatement; 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; @@ -271,9 +271,9 @@ public interface MySqlASTVisitor extends SQLASTVisitor { void endVisit(MySqlUpdateStatement x); - boolean visit(MySqlSetTransactionIsolationLevelStatement x); + boolean visit(MySqlSetTransactionStatement x); - void endVisit(MySqlSetTransactionIsolationLevelStatement x); + void endVisit(MySqlSetTransactionStatement x); boolean visit(MySqlSetNamesStatement 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 ff0af1b06f..93d235dba0 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 @@ -76,7 +76,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock.L import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetCharSetStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetNamesStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetPasswordStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetTransactionIsolationLevelStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetTransactionStatement; 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; @@ -489,12 +489,12 @@ public class MySqlASTVisitorAdapter extends SQLASTVisitorAdapter implements MySq } @Override - public boolean visit(MySqlSetTransactionIsolationLevelStatement x) { + public boolean visit(MySqlSetTransactionStatement x) { return true; } @Override - public void endVisit(MySqlSetTransactionIsolationLevelStatement x) { + public void endVisit(MySqlSetTransactionStatement 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 27bce282a1..2f516a0cd2 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 @@ -99,7 +99,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock.L import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetCharSetStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetNamesStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetPasswordStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetTransactionIsolationLevelStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetTransactionStatement; 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; @@ -1748,20 +1748,30 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV } @Override - public boolean visit(MySqlSetTransactionIsolationLevelStatement x) { + public boolean visit(MySqlSetTransactionStatement x) { if (x.getGlobal() == null) { - print("SET TRANSACTION ISOLATION LEVEL "); + print("SET TRANSACTION "); } else if (x.getGlobal().booleanValue()) { - print("SET GLOBAL TRANSACTION ISOLATION LEVEL "); + print("SET GLOBAL TRANSACTION "); } else { - print("SET SESSION TRANSACTION ISOLATION LEVEL "); + print("SET SESSION TRANSACTION "); } - print(x.getLevel()); + + if (x.getIsolationLevel() != null) { + print("ISOLATION LEVEL "); + print(x.getIsolationLevel()); + } + + if (x.getAccessModel() != null) { + print("READ "); + print(x.getAccessModel()); + } + return false; } @Override - public void endVisit(MySqlSetTransactionIsolationLevelStatement x) { + public void endVisit(MySqlSetTransactionStatement 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 2a0dd9cd6c..b630810441 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 @@ -91,7 +91,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock.L import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetCharSetStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetNamesStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetPasswordStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetTransactionIsolationLevelStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetTransactionStatement; 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; @@ -565,12 +565,12 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS } @Override - public boolean visit(MySqlSetTransactionIsolationLevelStatement x) { + public boolean visit(MySqlSetTransactionStatement x) { return false; } @Override - public void endVisit(MySqlSetTransactionIsolationLevelStatement x) { + public void endVisit(MySqlSetTransactionStatement x) { } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleToMySqlOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleToMySqlOutputVisitor.java index 0242e292a5..16761b97bb 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleToMySqlOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleToMySqlOutputVisitor.java @@ -28,7 +28,7 @@ public class OracleToMySqlOutputVisitor extends OracleOutputVisitor { { if (x.getParent() instanceof SQLSelect) { SQLSelect select = (SQLSelect) x.getParent(); - if (select.getParent() instanceof SQLSelectStatement) { + if (select.getParent() instanceof SQLSelectStatement || select.getParent() instanceof SQLSubqueryTableSource) { parentIsSelectStatment = true; } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/stmt/SQLServerCommitStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/stmt/SQLServerCommitStatement.java new file mode 100644 index 0000000000..f28c06986b --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/stmt/SQLServerCommitStatement.java @@ -0,0 +1,62 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.druid.sql.dialect.sqlserver.ast.stmt; + +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerObjectImpl; +import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerStatement; +import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerASTVisitor; + +public class SQLServerCommitStatement extends SQLServerObjectImpl implements SQLServerStatement { + + private boolean work = false; + + private SQLExpr transactionName; + + private SQLExpr delayedDurability; + + public boolean isWork() { + return work; + } + + public void setWork(boolean work) { + this.work = work; + } + + @Override + public void accept0(SQLServerASTVisitor visitor) { + visitor.visit(this); + + visitor.endVisit(this); + + } + + public SQLExpr getTransactionName() { + return transactionName; + } + + public void setTransactionName(SQLExpr transactionName) { + this.transactionName = transactionName; + } + + public SQLExpr getDelayedDurability() { + return delayedDurability; + } + + public void setDelayedDurability(SQLExpr delayedDurability) { + this.delayedDurability = delayedDurability; + } +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/stmt/SQLServerRollbackStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/stmt/SQLServerRollbackStatement.java new file mode 100644 index 0000000000..9d7566ff45 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/stmt/SQLServerRollbackStatement.java @@ -0,0 +1,61 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.druid.sql.dialect.sqlserver.ast.stmt; + +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.statement.SQLRollbackStatement; +import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerStatement; +import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerASTVisitor; +import com.alibaba.druid.sql.visitor.SQLASTVisitor; + +public class SQLServerRollbackStatement extends SQLRollbackStatement implements SQLServerStatement { + + private boolean work = false; + + private SQLExpr name; + + public boolean isWork() { + return work; + } + + public void setWork(boolean work) { + this.work = work; + } + + @Override + public void accept0(SQLASTVisitor visitor) { + if (visitor instanceof SQLServerASTVisitor) { + accept0((SQLServerASTVisitor) visitor); + } else { + throw new IllegalArgumentException("not support visitor type : " + visitor.getClass().getName()); + } + } + + public void accept0(SQLServerASTVisitor visitor) { + visitor.visit(this); + + visitor.endVisit(this); + } + + public SQLExpr getName() { + return name; + } + + public void setName(SQLExpr name) { + this.name = name; + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java index c567c1a791..44a38f10d4 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java @@ -33,10 +33,12 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerDeclareItem; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerOutput; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerTop; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerBlockStatement; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerCommitStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerDeclareStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerIfStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerRollbackStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerSetStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerSetTransactionIsolationLevelStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerUpdateStatement; @@ -106,6 +108,11 @@ public class SQLServerStatementParser extends SQLStatementParser { statementList.add(this.parseBlock()); return true; } + + if (lexer.token() == Token.COMMIT) { + statementList.add(this.parseCommit()); + return true; + } return false; } @@ -429,4 +436,56 @@ public class SQLServerStatementParser extends SQLStatementParser { return block; } + + public SQLServerCommitStatement parseCommit() { + acceptIdentifier("COMMIT"); + + SQLServerCommitStatement stmt = new SQLServerCommitStatement(); + + if (identifierEquals("WORK")) { + lexer.nextToken(); + stmt.setWork(true); + } + + if (identifierEquals("TRAN") || identifierEquals("TRANSACTION")) { + lexer.nextToken(); + if (lexer.token() == Token.IDENTIFIER || lexer.token() == Token.VARIANT) { + stmt.setTransactionName(this.exprParser.expr()); + } + + if (lexer.token() == Token.WITH) { + lexer.nextToken(); + accept(Token.LPAREN); + acceptIdentifier("DELAYED_DURABILITY"); + accept(Token.EQ); + stmt.setDelayedDurability(this.exprParser.expr()); + accept(Token.RPAREN); + } + + } + + return stmt; + } + + public SQLServerRollbackStatement parseRollback() { + acceptIdentifier("ROLLBACK"); + + SQLServerRollbackStatement stmt = new SQLServerRollbackStatement(); + + if (identifierEquals("WORK")) { + lexer.nextToken(); + stmt.setWork(true); + } + + if (identifierEquals("TRAN") || identifierEquals("TRANSACTION")) { + lexer.nextToken(); + if (lexer.token() == Token.IDENTIFIER || lexer.token() == Token.VARIANT) { + stmt.setName(this.exprParser.expr()); + } + + + } + + return stmt; + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitor.java index 0cd3b966a1..ccfe625ed1 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitor.java @@ -23,11 +23,13 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerTop; import com.alibaba.druid.sql.dialect.sqlserver.ast.expr.SQLServerObjectReferenceExpr; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerBlockStatement; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerCommitStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerDeclareStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerIfStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerIfStatement.Else; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerRollbackStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerSetStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerSetTransactionIsolationLevelStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerUpdateStatement; @@ -102,5 +104,13 @@ public interface SQLServerASTVisitor extends SQLASTVisitor { boolean visit(SQLServerSelect x); void endVisit(SQLServerSelect x); + + boolean visit(SQLServerCommitStatement x); + + void endVisit(SQLServerCommitStatement x); + + boolean visit(SQLServerRollbackStatement x); + + void endVisit(SQLServerRollbackStatement x); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitorAdapter.java index ac14f09c0e..40917b9265 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitorAdapter.java @@ -23,11 +23,13 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerTop; import com.alibaba.druid.sql.dialect.sqlserver.ast.expr.SQLServerObjectReferenceExpr; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerBlockStatement; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerCommitStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerDeclareStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerIfStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerIfStatement.Else; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerRollbackStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerSetStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerSetTransactionIsolationLevelStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerUpdateStatement; @@ -205,4 +207,24 @@ public class SQLServerASTVisitorAdapter extends SQLASTVisitorAdapter implements } + @Override + public boolean visit(SQLServerCommitStatement x) { + return true; + } + + @Override + public void endVisit(SQLServerCommitStatement x) { + + } + + @Override + public boolean visit(SQLServerRollbackStatement x) { + return true; + } + + @Override + public void endVisit(SQLServerRollbackStatement x) { + + } + } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerOutputVisitor.java index 0d4a0b2a7c..9357b410f6 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerOutputVisitor.java @@ -32,11 +32,13 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerTop; import com.alibaba.druid.sql.dialect.sqlserver.ast.expr.SQLServerObjectReferenceExpr; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerBlockStatement; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerCommitStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerDeclareStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerIfStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerIfStatement.Else; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerRollbackStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerSetStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerSetTransactionIsolationLevelStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerUpdateStatement; @@ -595,4 +597,53 @@ public class SQLServerOutputVisitor extends SQLASTOutputVisitor implements SQLSe } return false; } + + @Override + public boolean visit(SQLServerCommitStatement x) { + print("COMMIT"); + + if (x.isWork()) { + print(" WORK"); + } else { + print(" TRANSACTION"); + if (x.getTransactionName() != null) { + print(" "); + x.getTransactionName().accept(this); + } + if (x.getDelayedDurability() != null) { + print(" WITH ( DELAYED_DURABILITY = "); + x.getDelayedDurability().accept(this); + print(" )"); + } + } + + return false; + } + + @Override + public void endVisit(SQLServerCommitStatement x) { + + } + + @Override + public boolean visit(SQLServerRollbackStatement x) { + print("ROLLBACK"); + + if (x.isWork()) { + print(" WORK"); + } else { + print(" TRANSACTION"); + if (x.getName() != null) { + print(" "); + x.getName().accept(this); + } + } + + return false; + } + + @Override + public void endVisit(SQLServerRollbackStatement x) { + + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerSchemaStatVisitor.java index f39c524d0b..01ab9e9335 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerSchemaStatVisitor.java @@ -30,11 +30,13 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerTop; import com.alibaba.druid.sql.dialect.sqlserver.ast.expr.SQLServerObjectReferenceExpr; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerBlockStatement; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerCommitStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerDeclareStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerIfStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerIfStatement.Else; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerRollbackStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerSetStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerSetTransactionIsolationLevelStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerUpdateStatement; @@ -241,4 +243,24 @@ public class SQLServerSchemaStatVisitor extends SchemaStatVisitor implements SQL } + @Override + public boolean visit(SQLServerCommitStatement x) { + return true; + } + + @Override + public void endVisit(SQLServerCommitStatement x) { + + } + + @Override + public boolean visit(SQLServerRollbackStatement x) { + return true; + } + + @Override + public void endVisit(SQLServerRollbackStatement 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 bb0a005a1f..b2fae44ebb 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 @@ -27,7 +27,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSetStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDescribeStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetCharSetStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetNamesStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetTransactionIsolationLevelStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetTransactionStatement; 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; @@ -144,7 +144,7 @@ public class DALParserTest extends TestCase { public void testSetTxn_0() throws Exception { String sql = "SET transaction ISOLATION LEVEL READ UNCOMMITTED"; MySqlStatementParser parser = new MySqlStatementParser(sql); - MySqlSetTransactionIsolationLevelStatement set = (MySqlSetTransactionIsolationLevelStatement) parser.parseStatementList().get(0); + MySqlSetTransactionStatement set = (MySqlSetTransactionStatement) parser.parseStatementList().get(0); parser.match(Token.EOF); String output = SQLUtils.toMySqlString(set); Assert.assertEquals("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED", output); @@ -153,7 +153,7 @@ public class DALParserTest extends TestCase { public void testSetTxn_1() throws Exception { String sql = "SET global transaction ISOLATION LEVEL READ COMMITTED"; MySqlStatementParser parser = new MySqlStatementParser(sql); - MySqlSetTransactionIsolationLevelStatement set = (MySqlSetTransactionIsolationLevelStatement) parser.parseStatementList().get(0); + MySqlSetTransactionStatement set = (MySqlSetTransactionStatement) parser.parseStatementList().get(0); parser.match(Token.EOF); String output = SQLUtils.toMySqlString(set); Assert.assertEquals("SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED", output); @@ -162,7 +162,7 @@ public class DALParserTest extends TestCase { public void testSetTxn_2() throws Exception { String sql = "SET transaction ISOLATION LEVEL REPEATABLE READ "; MySqlStatementParser parser = new MySqlStatementParser(sql); - MySqlSetTransactionIsolationLevelStatement set = (MySqlSetTransactionIsolationLevelStatement) parser.parseStatementList().get(0); + MySqlSetTransactionStatement set = (MySqlSetTransactionStatement) parser.parseStatementList().get(0); parser.match(Token.EOF); String output = SQLUtils.toMySqlString(set); Assert.assertEquals("SET TRANSACTION ISOLATION LEVEL REPEATABLE READ", output); @@ -171,7 +171,7 @@ public class DALParserTest extends TestCase { public void testSetTxn_3() throws Exception { String sql = "SET session transaction ISOLATION LEVEL SERIALIZABLE"; MySqlStatementParser parser = new MySqlStatementParser(sql); - MySqlSetTransactionIsolationLevelStatement set = (MySqlSetTransactionIsolationLevelStatement) parser.parseStatementList().get(0); + MySqlSetTransactionStatement set = (MySqlSetTransactionStatement) parser.parseStatementList().get(0); parser.match(Token.EOF); String output = SQLUtils.toMySqlString(set); Assert.assertEquals("SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE", output); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlASTVisitorAdapterTest.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlASTVisitorAdapterTest.java index b63ece3a02..f2fb0cc1c3 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlASTVisitorAdapterTest.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlASTVisitorAdapterTest.java @@ -48,7 +48,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectGroupBy; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock.Limit; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetCharSetStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetNamesStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetTransactionIsolationLevelStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetTransactionStatement; 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; @@ -130,7 +130,7 @@ public class MySqlASTVisitorAdapterTest extends TestCase { new MySqlPartitionByKey().accept(adapter); new MySqlOutFileExpr().accept(adapter); new MySqlUpdateStatement().accept(adapter); - new MySqlSetTransactionIsolationLevelStatement().accept(adapter); + new MySqlSetTransactionStatement().accept(adapter); new MySqlSetNamesStatement().accept(adapter); new MySqlShowMasterLogsStatement().accept(adapter); new MySqlSetCharSetStatement().accept(adapter); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/tomysql/OracleToMySql_PageTest.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/tomysql/OracleToMySql_PageTest.java index 1048d46ac3..b25b6ff0e6 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/tomysql/OracleToMySql_PageTest.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/tomysql/OracleToMySql_PageTest.java @@ -23,4 +23,15 @@ public class OracleToMySql_PageTest extends TestCase { + "\nLIMIT 10", mysqlSql); System.out.println(mysqlSql); } + + + public void test_page1() throws Exception { + String sql = "select * from t_xiaoxi where rowid in(select rid from (select rownum rn,rid from(select rowid rid,cid from t_xiaoxi order by cid desc) where rownum<10000) where rn>9980) order by cid desc;"; + + //sql = "SELECT rid FROM ( SELECT rownum AS rn, rid FROM ( SELECT rowid AS rid, cid FROM t_xiaoxi ORDER BY cid DESC ) WHERE rownum < 10000 ) WHERE rn > 9980"; + String mysqlSql = SQLUtils.translateOracleToMySql(sql); + + System.out.println(mysqlSql); + } } + \ No newline at end of file diff --git a/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerCommitTest.java b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerCommitTest.java new file mode 100644 index 0000000000..6a423a09f1 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerCommitTest.java @@ -0,0 +1,70 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.druid.bvt.sql.sqlserver; + +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.sqlserver.parser.SQLServerStatementParser; +import com.alibaba.druid.util.JdbcUtils; + +public class SQLServerCommitTest extends TestCase { + + public void test_0() { + String sql = "COMMIT WORK"; + + SQLServerStatementParser parser = new SQLServerStatementParser(sql); + List stmtList = parser.parseStatementList(); + + Assert.assertEquals(1, stmtList.size()); + + String text = SQLUtils.toSQLString(stmtList, JdbcUtils.SQL_SERVER); + + Assert.assertEquals("COMMIT WORK", text); + } + + public void test_1() { + String sql = "COMMIT TRAN"; + + SQLServerStatementParser parser = new SQLServerStatementParser(sql); + List stmtList = parser.parseStatementList(); + + Assert.assertEquals(1, stmtList.size()); + + String text = SQLUtils.toSQLString(stmtList, JdbcUtils.SQL_SERVER); + + Assert.assertEquals("COMMIT TRANSACTION", text); + } + + public void test_2() { + String sql = "COMMIT TRANSACTION @tran_name_variable WITH ( DELAYED_DURABILITY = OFF )"; + + SQLServerStatementParser parser = new SQLServerStatementParser(sql); + List stmtList = parser.parseStatementList(); + + Assert.assertEquals(1, stmtList.size()); + + String text = SQLUtils.toSQLString(stmtList, JdbcUtils.SQL_SERVER); + + Assert.assertEquals("COMMIT TRANSACTION @tran_name_variable WITH ( DELAYED_DURABILITY = OFF )", text); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerRollbackTest.java b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerRollbackTest.java new file mode 100644 index 0000000000..dff9fa80d4 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerRollbackTest.java @@ -0,0 +1,70 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.druid.bvt.sql.sqlserver; + +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.sqlserver.parser.SQLServerStatementParser; +import com.alibaba.druid.util.JdbcUtils; + +public class SQLServerRollbackTest extends TestCase { + + public void test_0() { + String sql = "ROLLBACK WORK"; + + SQLServerStatementParser parser = new SQLServerStatementParser(sql); + List stmtList = parser.parseStatementList(); + + Assert.assertEquals(1, stmtList.size()); + + String text = SQLUtils.toSQLString(stmtList, JdbcUtils.SQL_SERVER); + + Assert.assertEquals("ROLLBACK WORK", text); + } + + public void test_1() { + String sql = "ROLLBACK TRAN"; + + SQLServerStatementParser parser = new SQLServerStatementParser(sql); + List stmtList = parser.parseStatementList(); + + Assert.assertEquals(1, stmtList.size()); + + String text = SQLUtils.toSQLString(stmtList, JdbcUtils.SQL_SERVER); + + Assert.assertEquals("ROLLBACK TRANSACTION", text); + } + + public void test_2() { + String sql = "ROLLBACK TRANSACTION @tran_name_variable"; + + SQLServerStatementParser parser = new SQLServerStatementParser(sql); + List stmtList = parser.parseStatementList(); + + Assert.assertEquals(1, stmtList.size()); + + String text = SQLUtils.toSQLString(stmtList, JdbcUtils.SQL_SERVER); + + Assert.assertEquals("ROLLBACK TRANSACTION @tran_name_variable", text); + } + +}