improve sql parser

This commit is contained in:
wenshao
2013-08-06 23:52:07 +08:00
parent 072f5ed951
commit ca12cb6f5a
20 changed files with 515 additions and 32 deletions
@@ -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<TriggerEvent> triggerEvents = new ArrayList<TriggerEvent>();
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<TriggerEvent> 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
}
}
@@ -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;
}
}
@@ -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;
}
@@ -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");
@@ -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();
@@ -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;
}
}
@@ -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);
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;