diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/stmt/SQLServerWaitForStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/stmt/SQLServerWaitForStatement.java new file mode 100644 index 0000000000..ca59e3f8b7 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/stmt/SQLServerWaitForStatement.java @@ -0,0 +1,77 @@ +/* + * 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.SQLStatement; +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 SQLServerWaitForStatement extends SQLServerObjectImpl implements SQLServerStatement { + + private SQLExpr delay; + + private SQLExpr time; + + private SQLStatement statement; + + private SQLExpr timeout; + + @Override + public void accept0(SQLServerASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, delay); + acceptChild(visitor, time); + acceptChild(visitor, statement); + acceptChild(visitor, timeout); + } + visitor.endVisit(this); + } + + public SQLExpr getDelay() { + return delay; + } + + public void setDelay(SQLExpr delay) { + this.delay = delay; + } + + public SQLExpr getTime() { + return time; + } + + public void setTime(SQLExpr time) { + this.time = time; + } + + public SQLStatement getStatement() { + return statement; + } + + public void setStatement(SQLStatement statement) { + this.statement = statement; + } + + public SQLExpr getTimeout() { + return timeout; + } + + public void setTimeout(SQLExpr timeout) { + this.timeout = timeout; + } + +} 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 44a38f10d4..093aa8caef 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 @@ -42,6 +42,7 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerRollbackStateme 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; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerWaitForStatement; import com.alibaba.druid.sql.parser.Lexer; import com.alibaba.druid.sql.parser.ParserException; import com.alibaba.druid.sql.parser.SQLSelectParser; @@ -114,6 +115,11 @@ public class SQLServerStatementParser extends SQLStatementParser { return true; } + if (identifierEquals("WAITFOR")) { + statementList.add(this.parseWaitFor()); + return true; + } + return false; } @@ -488,4 +494,30 @@ public class SQLServerStatementParser extends SQLStatementParser { return stmt; } + + public SQLServerWaitForStatement parseWaitFor() { + acceptIdentifier("WAITFOR"); + + SQLServerWaitForStatement stmt = new SQLServerWaitForStatement(); + + if (identifierEquals("DELAY")) { + lexer.nextToken(); + stmt.setDelay(this.exprParser.expr()); + } + + if (identifierEquals("TIME")) { + lexer.nextToken(); + stmt.setTime(this.exprParser.expr()); + } + + if (lexer.token() == Token.COMMA) { + lexer.nextToken(); + if (identifierEquals("TIMEOUT")) { + lexer.nextToken(); + stmt.setTimeout(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 ccfe625ed1..d6e5dbb29c 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 @@ -33,6 +33,7 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerRollbackStateme 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; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerWaitForStatement; import com.alibaba.druid.sql.visitor.SQLASTVisitor; public interface SQLServerASTVisitor extends SQLASTVisitor { @@ -112,5 +113,9 @@ public interface SQLServerASTVisitor extends SQLASTVisitor { boolean visit(SQLServerRollbackStatement x); void endVisit(SQLServerRollbackStatement x); + + boolean visit(SQLServerWaitForStatement x); + + void endVisit(SQLServerWaitForStatement 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 40917b9265..52f89cc563 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 @@ -33,6 +33,7 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerRollbackStateme 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; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerWaitForStatement; import com.alibaba.druid.sql.visitor.SQLASTVisitorAdapter; public class SQLServerASTVisitorAdapter extends SQLASTVisitorAdapter implements SQLServerASTVisitor { @@ -227,4 +228,14 @@ public class SQLServerASTVisitorAdapter extends SQLASTVisitorAdapter implements } + @Override + public boolean visit(SQLServerWaitForStatement x) { + return true; + } + + @Override + public void endVisit(SQLServerWaitForStatement 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 ad4471b658..42300973d6 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 @@ -42,6 +42,7 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerRollbackStateme 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; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerWaitForStatement; import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; public class SQLServerOutputVisitor extends SQLASTOutputVisitor implements SQLServerASTVisitor { @@ -659,4 +660,32 @@ public class SQLServerOutputVisitor extends SQLASTOutputVisitor implements SQLSe public void endVisit(SQLServerRollbackStatement x) { } + + @Override + public boolean visit(SQLServerWaitForStatement x) { + print("WAITFOR"); + + if (x.getDelay() != null) { + print(" DELAY "); + x.getDelay().accept(this); + } else if (x.getTime() != null) { + print(" TIME "); + x.getTime().accept(this); + } if (x.getStatement() != null) { + print(" DELAY "); + x.getStatement().accept(this); + } + + if(x.getTimeout() != null) { + print(" ,TIMEOUT "); + x.getTimeout().accept(this); + } + + return false; + } + + @Override + public void endVisit(SQLServerWaitForStatement 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 01ab9e9335..7fea92e43c 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 @@ -40,6 +40,7 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerRollbackStateme 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; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerWaitForStatement; import com.alibaba.druid.sql.visitor.SchemaStatVisitor; import com.alibaba.druid.stat.TableStat; import com.alibaba.druid.util.JdbcUtils; @@ -154,7 +155,7 @@ public class SQLServerSchemaStatVisitor extends SchemaStatVisitor implements SQL @Override public void endVisit(SQLServerSetTransactionIsolationLevelStatement x) { - + } @Override @@ -164,7 +165,7 @@ public class SQLServerSchemaStatVisitor extends SchemaStatVisitor implements SQL @Override public void endVisit(SQLServerSetStatement x) { - + } @Override @@ -174,7 +175,7 @@ public class SQLServerSchemaStatVisitor extends SchemaStatVisitor implements SQL @Override public void endVisit(SQLServerOutput x) { - + } @Override @@ -240,7 +241,7 @@ public class SQLServerSchemaStatVisitor extends SchemaStatVisitor implements SQL @Override public void endVisit(SQLServerSelect x) { - + } @Override @@ -250,7 +251,7 @@ public class SQLServerSchemaStatVisitor extends SchemaStatVisitor implements SQL @Override public void endVisit(SQLServerCommitStatement x) { - + } @Override @@ -260,7 +261,17 @@ public class SQLServerSchemaStatVisitor extends SchemaStatVisitor implements SQL @Override public void endVisit(SQLServerRollbackStatement x) { - + + } + + @Override + public boolean visit(SQLServerWaitForStatement x) { + return true; + } + + @Override + public void endVisit(SQLServerWaitForStatement x) { + } } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateTriggerTest.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateTriggerTest.java index 3e481537f6..15f5b6906a 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateTriggerTest.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateTriggerTest.java @@ -22,8 +22,6 @@ import org.junit.Assert; import com.alibaba.druid.sql.MysqlTest; import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; -import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor; -import com.alibaba.druid.stat.TableStat; public class MySqlCreateTriggerTest extends MysqlTest { @@ -36,15 +34,11 @@ public class MySqlCreateTriggerTest extends MysqlTest { Assert.assertEquals(1, statementList.size()); } - + public void test_1() throws Exception { - String sql = "CREATE TRIGGER testref BEFORE INSERT ON test1" - + " FOR EACH ROW" - + " BEGIN" - + " INSERT INTO test2 SET a2 = NEW.a1;" - + " DELETE FROM test3 WHERE a3 = NEW.a1;" - + " UPDATE test4 SET b4 = b4 + 1 WHERE a4 = NEW.a1;" - + " END;"; + String sql = "CREATE TRIGGER testref BEFORE INSERT ON test1" + " FOR EACH ROW" + " BEGIN" + + " INSERT INTO test2 SET a2 = NEW.a1;" + " DELETE FROM test3 WHERE a3 = NEW.a1;" + + " UPDATE test4 SET b4 = b4 + 1 WHERE a4 = NEW.a1;" + " END;"; MySqlStatementParser parser = new MySqlStatementParser(sql); List statementList = parser.parseStatementList(); @@ -52,6 +46,5 @@ public class MySqlCreateTriggerTest extends MysqlTest { Assert.assertEquals(1, statementList.size()); } - - + } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerWaitForTest.java b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerWaitForTest.java new file mode 100644 index 0000000000..e9abde0ddb --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerWaitForTest.java @@ -0,0 +1,57 @@ +/* + * 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 SQLServerWaitForTest extends TestCase { + + public void test_0() { + String sql = "WAITFOR TIME '22:20';"; + + SQLServerStatementParser parser = new SQLServerStatementParser(sql); + List stmtList = parser.parseStatementList(); + + Assert.assertEquals(1, stmtList.size()); + + String text = SQLUtils.toSQLString(stmtList, JdbcUtils.SQL_SERVER); + + Assert.assertEquals("WAITFOR TIME '22:20'", text); + } + + public void test_1() { + String sql = "WAITFOR DELAY '02:00';"; + + SQLServerStatementParser parser = new SQLServerStatementParser(sql); + List stmtList = parser.parseStatementList(); + + Assert.assertEquals(1, stmtList.size()); + + String text = SQLUtils.toSQLString(stmtList, JdbcUtils.SQL_SERVER); + + Assert.assertEquals("WAITFOR DELAY '02:00'", text); + } + +}