diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTriggerStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTriggerStatement.java new file mode 100644 index 0000000000..9a0b05a538 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTriggerStatement.java @@ -0,0 +1,115 @@ +/* + * 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.ast.statement; + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.druid.sql.ast.SQLName; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.ast.SQLStatementImpl; +import com.alibaba.druid.sql.visitor.SQLASTVisitor; + +public class SQLCreateTriggerStatement extends SQLStatementImpl { + + private SQLName name; + + private boolean orReplace = false; + + private TriggerType triggerType; + private final List triggerEvents = new ArrayList(); + + private SQLName on; + + private boolean forEachRow = false; + + private SQLStatement body; + + protected void accept0(SQLASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, name); + acceptChild(visitor, on); + acceptChild(visitor, body); + } + visitor.endVisit(this); + } + + public SQLName getOn() { + return on; + } + + public void setOn(SQLName on) { + this.on = on; + } + + public SQLName getName() { + return name; + } + + public void setName(SQLName name) { + if (name != null) { + name.setParent(this); + } + this.name = name; + } + + public SQLStatement getBody() { + return body; + } + + public void setBody(SQLStatement body) { + if (body != null) { + body.setParent(this); + } + this.body = body; + } + + public boolean isOrReplace() { + return orReplace; + } + + public void setOrReplace(boolean orReplace) { + this.orReplace = orReplace; + } + + public TriggerType getTriggerType() { + return triggerType; + } + + public void setTriggerType(TriggerType triggerType) { + this.triggerType = triggerType; + } + + public List getTriggerEvents() { + return triggerEvents; + } + + public boolean isForEachRow() { + return forEachRow; + } + + public void setForEachRow(boolean forEachRow) { + this.forEachRow = forEachRow; + } + + public static enum TriggerType { + BEFORE, AFTER, INSTEAD_OF + } + + public static enum TriggerEvent { + INSERT, UPDATE, DELETE + } +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateSequenceStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateSequenceStatement.java index 43bea26d8e..3ce4368fe5 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateSequenceStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateSequenceStatement.java @@ -25,7 +25,10 @@ public class OracleCreateSequenceStatement extends OracleStatementImpl { private SQLExpr startWith; private SQLExpr incrementBy; + private SQLExpr minValue; private SQLExpr maxValue; + private boolean noMaxValue; + private boolean noMinValue; private Boolean cycle; private Boolean cache; @@ -37,6 +40,7 @@ public class OracleCreateSequenceStatement extends OracleStatementImpl { acceptChild(visitor, name); acceptChild(visitor, startWith); acceptChild(visitor, incrementBy); + acceptChild(visitor, minValue); acceptChild(visitor, maxValue); } visitor.endVisit(this); @@ -98,4 +102,28 @@ public class OracleCreateSequenceStatement extends OracleStatementImpl { this.order = order; } + public SQLExpr getMinValue() { + return minValue; + } + + public void setMinValue(SQLExpr minValue) { + this.minValue = minValue; + } + + public boolean isNoMaxValue() { + return noMaxValue; + } + + public void setNoMaxValue(boolean noMaxValue) { + this.noMaxValue = noMaxValue; + } + + public boolean isNoMinValue() { + return noMinValue; + } + + public void setNoMinValue(boolean noMinValue) { + this.noMinValue = noMinValue; + } + } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java index 3d67a48436..485873bd42 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java @@ -1650,6 +1650,22 @@ public class OracleStatementParser extends SQLStatementParser { lexer.nextToken(); stmt.setCycle(Boolean.FALSE); continue; + } else if (identifierEquals("MINVALUE")) { + lexer.nextToken(); + stmt.setMinValue(this.exprParser.expr()); + continue; + } else if (identifierEquals("MAXVALUE")) { + lexer.nextToken(); + stmt.setMaxValue(this.exprParser.expr()); + continue; + } else if (identifierEquals("NOMAXVALUE")) { + lexer.nextToken(); + stmt.setNoMaxValue(true); + continue; + } else if (identifierEquals("NOMINVALUE")) { + lexer.nextToken(); + stmt.setNoMinValue(true); + continue; } break; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java index 5a01c5a890..9137c0f10b 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java @@ -185,24 +185,27 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS } public void postVisit(SQLObject x) { - if (!isPrintPostSemi()) { + if (!(x instanceof SQLStatement)) { return; } - if (x instanceof SQLStatement) { - if (x instanceof OraclePLSQLCommitStatement) { - return; - } - if (x.getParent() instanceof OracleCreateProcedureStatement) { - return; - } + if ((!isPrintPostSemi()) // + && (!(x.getParent() instanceof OracleBlockStatement))) { + return; + } - if (isPrettyFormat()) { - if (x.getParent() != null) { - print(";"); - } else { - println(";"); - } + if (x instanceof OraclePLSQLCommitStatement) { + return; + } + if (x.getParent() instanceof OracleCreateProcedureStatement) { + return; + } + + if (isPrettyFormat()) { + if (x.getParent() != null) { + print(";"); + } else { + println(";"); } } } @@ -2839,6 +2842,19 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS x.getMaxValue().accept(this); } + if (x.isNoMaxValue()) { + print(" NOMAXVALUE"); + } + + if (x.getMinValue() != null) { + print(" MINVALUE "); + x.getMinValue().accept(this); + } + + if (x.isNoMinValue()) { + print(" NOMINVALUE"); + } + if (x.getCycle() != null) { if (x.getCycle().booleanValue()) { print(" CYCLE"); 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 7e3321a97a..33ff09972a 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java @@ -43,6 +43,9 @@ import com.alibaba.druid.sql.ast.statement.SQLConstaint; import com.alibaba.druid.sql.ast.statement.SQLCreateDatabaseStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateIndexStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement; +import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement.TriggerEvent; +import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement.TriggerType; import com.alibaba.druid.sql.ast.statement.SQLCreateViewStatement; import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; import com.alibaba.druid.sql.ast.statement.SQLDropDatabaseStatement; @@ -1052,6 +1055,8 @@ public class SQLStatementParser extends SQLParser { return parseCreateDbLink(); } else if (token == Token.VIEW) { return parseCreateView(); + } else if (token == Token.TRIGGER) { + return parseCreateTrigger(); } throw new ParserException("TODO " + lexer.token()); @@ -1061,6 +1066,64 @@ public class SQLStatementParser extends SQLParser { throw new ParserException("TODO " + lexer.token()); } + public SQLStatement parseCreateTrigger() { + accept(Token.TRIGGER); + + SQLCreateTriggerStatement stmt = new SQLCreateTriggerStatement(); + stmt.setName(this.exprParser.name()); + + if (identifierEquals("BEFORE")) { + stmt.setTriggerType(TriggerType.BEFORE); + lexer.nextToken(); + } else if (identifierEquals("AFTER")) { + stmt.setTriggerType(TriggerType.AFTER); + lexer.nextToken(); + } else if (identifierEquals("INSTEAD")) { + lexer.nextToken(); + accept(Token.OF); + stmt.setTriggerType(TriggerType.INSTEAD_OF); + } + + for (;;) { + if (lexer.token() == Token.INSERT) { + lexer.nextToken(); + stmt.getTriggerEvents().add(TriggerEvent.INSERT); + continue; + } + + if (lexer.token() == Token.UPDATE) { + lexer.nextToken(); + stmt.getTriggerEvents().add(TriggerEvent.UPDATE); + continue; + } + + if (lexer.token() == Token.DELETE) { + lexer.nextToken(); + stmt.getTriggerEvents().add(TriggerEvent.DELETE); + continue; + } + break; + } + + accept(Token.ON); + stmt.setOn(this.exprParser.name()); + + if (lexer.token() == Token.FOR) { + lexer.nextToken(); + acceptIdentifier("EACH"); + accept(Token.ROW); + stmt.setForEachRow(true); + } + + SQLStatement body = this.parseBlock(); + stmt.setBody(body); + return stmt; + } + + public SQLStatement parseBlock() { + throw new ParserException("TODO " + lexer.token()); + } + public SQLStatement parseCreateDatabase() { if (lexer.token() == Token.CREATE) { lexer.nextToken(); diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java index 173db60297..f0d1730367 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -94,6 +94,8 @@ import com.alibaba.druid.sql.ast.statement.SQLCommentStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateDatabaseStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateIndexStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement; +import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement.TriggerEvent; import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; import com.alibaba.druid.sql.ast.statement.SQLDropDatabaseStatement; import com.alibaba.druid.sql.ast.statement.SQLDropIndexStatement; @@ -109,6 +111,7 @@ import com.alibaba.druid.sql.ast.statement.SQLForeignKeyConstraint; import com.alibaba.druid.sql.ast.statement.SQLForeignKeyImpl; import com.alibaba.druid.sql.ast.statement.SQLGrantStatement; import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; +import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement.TriggerType; import com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause; import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource; import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource.JoinType; @@ -1825,4 +1828,41 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab x.getConstraint().accept(this); return false; } + + public boolean visit(SQLCreateTriggerStatement x) { + print("CREATE "); + + if (x.isOrReplace()) { + print("OR REPLEACE "); + } + + print("TRIGGER "); + + x.getName().accept(this); + + incrementIndent(); + println(); + if (TriggerType.INSTEAD_OF.equals(x.getTriggerType())) { + print("INSTEAD OF"); + } else { + print(x.getTriggerType().name()); + } + + for (TriggerEvent event : x.getTriggerEvents()) { + print(' '); + print(event.name()); + } + println(); + print("ON "); + x.getOn().accept(this); + + if (x.isForEachRow()) { + println(); + print("FOR EACH ROW"); + } + decrementIndent(); + println(); + x.getBody().accept(this); + return false; + } } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java index 0d7bbc72cd..f8e94f4686 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java @@ -77,6 +77,7 @@ import com.alibaba.druid.sql.ast.statement.SQLCommentStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateDatabaseStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateIndexStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateViewStatement; import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; import com.alibaba.druid.sql.ast.statement.SQLDropDatabaseStatement; @@ -514,4 +515,8 @@ public interface SQLASTVisitor { void endVisit(SQLAlterTableAddConstraint x); boolean visit(SQLAlterTableAddConstraint x); + + void endVisit(SQLCreateTriggerStatement x); + + boolean visit(SQLCreateTriggerStatement x); } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java index d6dd6a2474..26e8a4a18b 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java @@ -78,6 +78,7 @@ import com.alibaba.druid.sql.ast.statement.SQLCommentStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateDatabaseStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateIndexStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateViewStatement; import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; import com.alibaba.druid.sql.ast.statement.SQLDropDatabaseStatement; @@ -997,4 +998,14 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor { public boolean visit(SQLAlterTableAddConstraint x) { return true; } + + @Override + public void endVisit(SQLCreateTriggerStatement x) { + + } + + @Override + public boolean visit(SQLCreateTriggerStatement x) { + return true; + } } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java index 4a0fc68b6c..8eab221640 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java @@ -52,6 +52,7 @@ import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition; import com.alibaba.druid.sql.ast.statement.SQLCommentStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateIndexStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateViewStatement; import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; import com.alibaba.druid.sql.ast.statement.SQLDropDatabaseStatement; @@ -1287,4 +1288,8 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { x.getExpr().accept(this); return false; } + + public boolean visit(SQLCreateTriggerStatement x) { + return false; + } } diff --git a/src/main/java/com/alibaba/druid/wall/spi/DB2WallVisitor.java b/src/main/java/com/alibaba/druid/wall/spi/DB2WallVisitor.java index 6a051ca40e..b0084bf94b 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/DB2WallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/DB2WallVisitor.java @@ -29,6 +29,7 @@ import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement; import com.alibaba.druid.sql.ast.statement.SQLCallStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement; import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement; import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; @@ -187,12 +188,12 @@ public class DB2WallVisitor extends DB2ASTVisitorAdapter implements WallVisitor this.toSQL(x))); return false; } - + WallVisitorUtils.initWallTopStatementContext(); return true; } - + @Override public void endVisit(SQLSelectStatement x) { WallVisitorUtils.clearWallTopStatementContext(); @@ -205,7 +206,7 @@ public class DB2WallVisitor extends DB2ASTVisitorAdapter implements WallVisitor return true; } - + @Override public void endVisit(SQLInsertStatement x) { WallVisitorUtils.clearWallTopStatementContext(); @@ -224,7 +225,7 @@ public class DB2WallVisitor extends DB2ASTVisitorAdapter implements WallVisitor return true; } - + @Override public void endVisit(SQLUpdateStatement x) { WallVisitorUtils.clearWallTopStatementContext(); @@ -264,4 +265,8 @@ public class DB2WallVisitor extends DB2ASTVisitorAdapter implements WallVisitor return false; } + @Override + public boolean visit(SQLCreateTriggerStatement x) { + return false; + } } diff --git a/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java b/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java index 5a63b775d3..2f89adad3b 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java @@ -31,6 +31,7 @@ import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement; import com.alibaba.druid.sql.ast.statement.SQLAssignItem; import com.alibaba.druid.sql.ast.statement.SQLCallStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement; import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement; import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; @@ -438,4 +439,9 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi } return false; } + + @Override + public boolean visit(SQLCreateTriggerStatement x) { + return false; + } } diff --git a/src/main/java/com/alibaba/druid/wall/spi/OracleWallVisitor.java b/src/main/java/com/alibaba/druid/wall/spi/OracleWallVisitor.java index 6703a6b91c..9e2df7c7a5 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/OracleWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/OracleWallVisitor.java @@ -29,6 +29,7 @@ import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement; import com.alibaba.druid.sql.ast.statement.SQLCallStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement; import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement; import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; @@ -336,4 +337,9 @@ public class OracleWallVisitor extends OracleASTVisitorAdapter implements WallVi public boolean visit(SQLCallStatement x) { return false; } + + @Override + public boolean visit(SQLCreateTriggerStatement x) { + return false; + } } diff --git a/src/main/java/com/alibaba/druid/wall/spi/PGWallVisitor.java b/src/main/java/com/alibaba/druid/wall/spi/PGWallVisitor.java index 2823cf0391..3ac9c316f8 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/PGWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/PGWallVisitor.java @@ -29,6 +29,7 @@ import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement; import com.alibaba.druid.sql.ast.statement.SQLCallStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement; import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement; import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; @@ -193,7 +194,7 @@ public class PGWallVisitor extends PGASTVisitorAdapter implements WallVisitor { return true; } - + @Override public void endVisit(SQLSelectStatement x) { WallVisitorUtils.clearWallTopStatementContext(); @@ -206,7 +207,7 @@ public class PGWallVisitor extends PGASTVisitorAdapter implements WallVisitor { return true; } - + @Override public void endVisit(SQLInsertStatement x) { WallVisitorUtils.clearWallTopStatementContext(); @@ -217,7 +218,7 @@ public class PGWallVisitor extends PGASTVisitorAdapter implements WallVisitor { WallVisitorUtils.checkDelete(this, x); return true; } - + @Override public void endVisit(SQLDeleteStatement x) { WallVisitorUtils.clearWallTopStatementContext(); @@ -230,7 +231,7 @@ public class PGWallVisitor extends PGASTVisitorAdapter implements WallVisitor { return true; } - + @Override public void endVisit(SQLUpdateStatement x) { WallVisitorUtils.clearWallTopStatementContext(); @@ -269,4 +270,9 @@ public class PGWallVisitor extends PGASTVisitorAdapter implements WallVisitor { public boolean visit(SQLCallStatement x) { return false; } + + @Override + public boolean visit(SQLCreateTriggerStatement x) { + return false; + } } diff --git a/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java b/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java index d49a13aa32..88b69f50c4 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java @@ -30,6 +30,7 @@ import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement; import com.alibaba.druid.sql.ast.statement.SQLCallStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement; import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement; import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; @@ -64,7 +65,7 @@ public class SQLServerWallVisitor extends SQLServerASTVisitorAdapter implements this.config = provider.getConfig(); this.provider = provider; } - + @Override public boolean isSqlModified() { return sqlModified; @@ -322,4 +323,9 @@ public class SQLServerWallVisitor extends SQLServerASTVisitorAdapter implements public boolean visit(SQLCallStatement x) { return false; } + + @Override + public boolean visit(SQLCreateTriggerStatement x) { + return false; + } } diff --git a/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java b/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java index b7132976fb..c768f2b2ac 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java @@ -51,10 +51,13 @@ import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement; import com.alibaba.druid.sql.ast.statement.SQLCallStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateIndexStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateViewStatement; import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; import com.alibaba.druid.sql.ast.statement.SQLDropIndexStatement; +import com.alibaba.druid.sql.ast.statement.SQLDropSequenceStatement; import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLDropTriggerStatement; import com.alibaba.druid.sql.ast.statement.SQLDropViewStatement; import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; import com.alibaba.druid.sql.ast.statement.SQLInsertInto; @@ -1700,8 +1703,9 @@ public class WallVisitorUtils { } else if (x instanceof SQLCreateTableStatement // || x instanceof SQLCreateIndexStatement // || x instanceof SQLCreateViewStatement // + || x instanceof SQLCreateTriggerStatement // || x instanceof OracleCreateSequenceStatement // - ) { + ) { allow = config.isCreateTableAllow(); denyMessage = "create table not allow"; errorCode = ErrorCode.CREATE_TABLE_NOT_ALLOW; @@ -1711,7 +1715,10 @@ public class WallVisitorUtils { errorCode = ErrorCode.ALTER_TABLE_NOT_ALLOW; } else if (x instanceof SQLDropTableStatement // || x instanceof SQLDropIndexStatement // - || x instanceof SQLDropViewStatement) { + || x instanceof SQLDropViewStatement // + || x instanceof SQLDropTriggerStatement // + || x instanceof SQLDropSequenceStatement // + ) { allow = config.isDropTableAllow(); denyMessage = "drop table not allow"; errorCode = ErrorCode.DROP_TABLE_NOT_ALLOW; diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/OracleWallTest3.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/OracleWallTest3.java index a4c79e6fbf..897840c455 100644 --- a/src/test/java/com/alibaba/druid/bvt/filter/wall/OracleWallTest3.java +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/OracleWallTest3.java @@ -25,11 +25,12 @@ public class OracleWallTest3 extends TestCase { public void test_true() throws Exception { String sql = // - "select sequence_name from all_sequences " // - + "union select synonym_name" // - + " from all_synonyms us, all_sequences asq" // - + " where asq.sequence_name = us.table_name" // - + " and asq.sequence_owner = us.table_owner"; // + "CREATE TRIGGER \"AO_4AEACD_WEBHOOK_D367380484\" " // + + "BEFORE INSERT"// + + " ON \"AO_4AEACD_WEBHOOK_DAO\" FOR EACH ROW "// + + "BEGIN"// + + " SELECT \"AO_4AEACD_WEBHOOK_DAO_ID_SEQ\".NEXTVAL INTO :NEW.\"ID\" FROM DUAL;"// + + "END;"; Assert.assertTrue(WallUtils.isValidateOracle(sql)); } } diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/OracleWallTest4.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/OracleWallTest4.java new file mode 100644 index 0000000000..c584a78c54 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/OracleWallTest4.java @@ -0,0 +1,35 @@ +/* + * 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.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.wall.WallUtils; + +public class OracleWallTest4 extends TestCase { + + public void test_true() throws Exception { + String sql = // + "select sequence_name from all_sequences " // + + "union select synonym_name" // + + " from all_synonyms us, all_sequences asq" // + + " where asq.sequence_name = us.table_name" // + + " and asq.sequence_owner = us.table_owner"; // + Assert.assertTrue(WallUtils.isValidateOracle(sql)); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/OracleWallTest5.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/OracleWallTest5.java new file mode 100644 index 0000000000..e29f69e50a --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/OracleWallTest5.java @@ -0,0 +1,31 @@ +/* + * 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.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.wall.WallUtils; + +public class OracleWallTest5 extends TestCase { + + public void test_true() throws Exception { + String sql = // + "DROP TRIGGER \"AO_4AEACD_WEBHOOK_D367380484\""; + Assert.assertTrue(WallUtils.isValidateOracle(sql)); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateSequenceTest_2.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateSequenceTest_2.java index ae636647f9..2d4c691072 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateSequenceTest_2.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateSequenceTest_2.java @@ -20,9 +20,11 @@ import java.util.List; import org.junit.Assert; import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.util.JdbcConstants; public class OracleCreateSequenceTest_2 extends OracleTest { @@ -32,13 +34,16 @@ public class OracleCreateSequenceTest_2 extends OracleTest { OracleStatementParser parser = new OracleStatementParser(sql); List statementList = parser.parseStatementList(); - SQLStatement statemen = statementList.get(0); + SQLStatement stmt = statementList.get(0); print(statementList); Assert.assertEquals(1, statementList.size()); + + Assert.assertEquals("CREATE SEQUENCE \"AO_4AEACD_WEBHOOK_DAO_ID_SEQ\" START WITH 1 INCREMENT BY 1 NOMAXVALUE MINVALUE 1",// + SQLUtils.toSQLString(stmt, JdbcConstants.ORACLE)); OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); - statemen.accept(visitor); + stmt.accept(visitor); System.out.println("Tables : " + visitor.getTables()); System.out.println("fields : " + visitor.getColumns()); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTriggerTest.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTriggerTest.java new file mode 100644 index 0000000000..0c60adf61f --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTriggerTest.java @@ -0,0 +1,76 @@ +/* + * 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.oracle; + +import java.util.List; + +import org.junit.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.util.JdbcConstants; + +public class OracleCreateTriggerTest extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "CREATE TRIGGER \"AO_4AEACD_WEBHOOK_D367380484\" " // + + "BEFORE INSERT"// + + " ON \"AO_4AEACD_WEBHOOK_DAO\" FOR EACH ROW "// + + "BEGIN"// + + " SELECT \"AO_4AEACD_WEBHOOK_DAO_ID_SEQ\".NEXTVAL INTO :NEW.\"ID\" FROM DUAL;"// + + "END;"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + Assert.assertEquals("CREATE TRIGGER \"AO_4AEACD_WEBHOOK_D367380484\"" // + + "\n\tBEFORE INSERT"// + + "\n\tON \"AO_4AEACD_WEBHOOK_DAO\""// + + "\n\tFOR EACH ROW"// + + "\nBEGIN"// + + "\n\tSELECT \"AO_4AEACD_WEBHOOK_DAO_ID_SEQ\".NEXTVAL"// + + "\n\tINTO :NEW.\"ID\"" // + + "\n\tFROM DUAL;" + "\nEND",// + SQLUtils.toSQLString(stmt, JdbcConstants.ORACLE)); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + stmt.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(0, visitor.getTables().size()); + + // Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("cdc.en_complaint_ipr_stat_fdt0"))); + + Assert.assertEquals(0, visitor.getColumns().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "*"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +}