diff --git a/pom.xml b/pom.xml index d63a4a8d0b..6af37599b3 100644 --- a/pom.xml +++ b/pom.xml @@ -529,9 +529,9 @@ - com.alibaba - fastjson - 1.1.33 + com.yammer.metrics + metrics-core + 2.2.0 test diff --git a/src/main/java/com/alibaba/druid/sql/PagerUtils.java b/src/main/java/com/alibaba/druid/sql/PagerUtils.java index 71dbba0e37..8457e27ced 100644 --- a/src/main/java/com/alibaba/druid/sql/PagerUtils.java +++ b/src/main/java/com/alibaba/druid/sql/PagerUtils.java @@ -33,6 +33,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource; import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; +import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2SelectQueryBlock; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock.Limit; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAggregateExpr; @@ -226,6 +227,10 @@ public class PagerUtils { if (JdbcConstants.SQL_SERVER.equals(dbType)) { return new SQLServerSelectQueryBlock(); } + + if (JdbcConstants.DB2.equals(dbType)) { + return new DB2SelectQueryBlock(); + } return new SQLSelectQueryBlock(); } diff --git a/src/main/java/com/alibaba/druid/sql/SQLUtils.java b/src/main/java/com/alibaba/druid/sql/SQLUtils.java index ba01460e62..4cd4b91f0f 100644 --- a/src/main/java/com/alibaba/druid/sql/SQLUtils.java +++ b/src/main/java/com/alibaba/druid/sql/SQLUtils.java @@ -21,6 +21,8 @@ import com.alibaba.druid.DruidRuntimeException; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLObject; import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.db2.visitor.DB2OutputVisitor; +import com.alibaba.druid.sql.dialect.db2.visitor.DB2SchemaStatVisitor; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlOutputVisitor; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor; import com.alibaba.druid.sql.dialect.oracle.visitor.OracleOutputVisitor; @@ -38,8 +40,8 @@ import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; import com.alibaba.druid.sql.visitor.SchemaStatVisitor; import com.alibaba.druid.support.logging.Log; import com.alibaba.druid.support.logging.LogFactory; -import com.alibaba.druid.util.JdbcUtils; import com.alibaba.druid.util.JdbcConstants; +import com.alibaba.druid.util.JdbcUtils; import com.alibaba.druid.util.StringUtils; @@ -201,6 +203,10 @@ public class SQLUtils { if (JdbcUtils.JTDS.equals(dbType)) { return new SQLServerOutputVisitor(out); } + + if (JdbcUtils.DB2.equals(dbType)) { + return new DB2OutputVisitor(out); + } return new SQLASTOutputVisitor(out); } @@ -231,6 +237,10 @@ public class SQLUtils { if (JdbcUtils.JTDS.equals(dbType)) { return new SQLServerSchemaStatVisitor(); } + + if (JdbcUtils.DB2.equals(dbType)) { + return new DB2SchemaStatVisitor(); + } return new SchemaStatVisitor(); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/ast/stmt/DB2SelectQueryBlock.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/ast/stmt/DB2SelectQueryBlock.java new file mode 100644 index 0000000000..24ead6662c --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/ast/stmt/DB2SelectQueryBlock.java @@ -0,0 +1,25 @@ +/* + * 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.db2.ast.stmt; + +import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; + +public class DB2SelectQueryBlock extends SQLSelectQueryBlock { + + private static final long serialVersionUID = 1L; + + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2ExprParser.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2ExprParser.java new file mode 100644 index 0000000000..eaeadf00e9 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2ExprParser.java @@ -0,0 +1,20 @@ +package com.alibaba.druid.sql.dialect.db2.parser; + +import com.alibaba.druid.sql.parser.Lexer; +import com.alibaba.druid.sql.parser.SQLExprParser; + +public class DB2ExprParser extends SQLExprParser { + + public final static String[] AGGREGATE_FUNCTIONS = { "AVG", "COUNT", "MAX", "MIN", "STDDEV", "SUM", "ROW_NUMBER" }; + + public DB2ExprParser(String sql){ + this(new DB2Lexer(sql)); + this.lexer.nextToken(); + } + + public DB2ExprParser(Lexer lexer){ + super(lexer); + this.aggregateFunctions = AGGREGATE_FUNCTIONS; + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2Lexer.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2Lexer.java new file mode 100644 index 0000000000..66cfc0604d --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2Lexer.java @@ -0,0 +1,27 @@ +package com.alibaba.druid.sql.dialect.db2.parser; + +import java.util.HashMap; +import java.util.Map; + +import com.alibaba.druid.sql.parser.Keywords; +import com.alibaba.druid.sql.parser.Lexer; +import com.alibaba.druid.sql.parser.Token; + + +public class DB2Lexer extends Lexer { + + public final static Keywords DEFAULT_DB2_KEYWORDS; + + static { + Map map = new HashMap(); + + map.putAll(Keywords.DEFAULT_KEYWORDS.getKeywords()); + + DEFAULT_DB2_KEYWORDS = new Keywords(map); + } + + public DB2Lexer(String input){ + super(input); + super.keywods = DEFAULT_DB2_KEYWORDS; + } +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2SelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2SelectParser.java new file mode 100644 index 0000000000..f7c9ad9491 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2SelectParser.java @@ -0,0 +1,80 @@ +/* + * 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.db2.parser; + +import com.alibaba.druid.sql.ast.SQLSetQuantifier; +import com.alibaba.druid.sql.ast.statement.SQLSelectQuery; +import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; +import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2SelectQueryBlock; +import com.alibaba.druid.sql.parser.SQLExprParser; +import com.alibaba.druid.sql.parser.SQLSelectParser; +import com.alibaba.druid.sql.parser.Token; + +public class DB2SelectParser extends SQLSelectParser { + + public DB2SelectParser(SQLExprParser exprParser){ + super(exprParser); + } + + public DB2SelectParser(String sql){ + this(new DB2ExprParser(sql)); + } + + protected SQLExprParser createExprParser() { + return new DB2ExprParser(lexer); + } + + @Override + public SQLSelectQuery query() { + if (lexer.token() == Token.LPAREN) { + lexer.nextToken(); + + SQLSelectQuery select = query(); + accept(Token.RPAREN); + + return queryRest(select); + } + + accept(Token.SELECT); + + if (lexer.token() == Token.COMMENT) { + lexer.nextToken(); + } + + DB2SelectQueryBlock queryBlock = new DB2SelectQueryBlock(); + + if (lexer.token() == Token.DISTINCT) { + queryBlock.setDistionOption(SQLSetQuantifier.DISTINCT); + lexer.nextToken(); + } else if (lexer.token() == Token.UNIQUE) { + queryBlock.setDistionOption(SQLSetQuantifier.UNIQUE); + lexer.nextToken(); + } else if (lexer.token() == Token.ALL) { + queryBlock.setDistionOption(SQLSetQuantifier.ALL); + lexer.nextToken(); + } + + parseSelectList(queryBlock); + + parseFrom(queryBlock); + + parseWhere(queryBlock); + + parseGroupBy(queryBlock); + + return queryRest(queryBlock); + } +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2StatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2StatementParser.java new file mode 100644 index 0000000000..6f81d7ffc0 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2StatementParser.java @@ -0,0 +1,19 @@ +package com.alibaba.druid.sql.dialect.db2.parser; + +import com.alibaba.druid.sql.parser.Lexer; +import com.alibaba.druid.sql.parser.SQLStatementParser; + + +public class DB2StatementParser extends SQLStatementParser { + public DB2StatementParser(String sql) { + super (new DB2ExprParser(sql)); + } + + public DB2StatementParser(Lexer lexer){ + super(new DB2ExprParser(lexer)); + } + + public DB2SelectParser createSQLSelectParser() { + return new DB2SelectParser(this.exprParser); + } +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ASTVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ASTVisitor.java new file mode 100644 index 0000000000..b7ce9438bf --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ASTVisitor.java @@ -0,0 +1,8 @@ +package com.alibaba.druid.sql.dialect.db2.visitor; + +import com.alibaba.druid.sql.visitor.SQLASTVisitor; + + +public interface DB2ASTVisitor extends SQLASTVisitor { + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ASTVisitorAdapter.java new file mode 100644 index 0000000000..0ad9ec85ed --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ASTVisitorAdapter.java @@ -0,0 +1,7 @@ +package com.alibaba.druid.sql.dialect.db2.visitor; + +import com.alibaba.druid.sql.visitor.SQLASTVisitorAdapter; + +public class DB2ASTVisitorAdapter extends SQLASTVisitorAdapter implements DB2ASTVisitor { + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2EvalVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2EvalVisitor.java new file mode 100644 index 0000000000..112609f638 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2EvalVisitor.java @@ -0,0 +1,142 @@ +/* + * 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.db2.visitor; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; +import com.alibaba.druid.sql.ast.expr.SQLCaseExpr; +import com.alibaba.druid.sql.ast.expr.SQLCharExpr; +import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; +import com.alibaba.druid.sql.ast.expr.SQLInListExpr; +import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr; +import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; +import com.alibaba.druid.sql.ast.expr.SQLNullExpr; +import com.alibaba.druid.sql.ast.expr.SQLNumberExpr; +import com.alibaba.druid.sql.ast.expr.SQLQueryExpr; +import com.alibaba.druid.sql.ast.expr.SQLUnaryExpr; +import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; +import com.alibaba.druid.sql.visitor.SQLEvalVisitor; +import com.alibaba.druid.sql.visitor.SQLEvalVisitorUtils; +import com.alibaba.druid.sql.visitor.functions.Function; + +public class DB2EvalVisitor extends DB2ASTVisitorAdapter implements SQLEvalVisitor { + + private Map functions = new HashMap(); + private List parameters = new ArrayList(); + + private int variantIndex = -1; + + private boolean markVariantIndex = true; + + public DB2EvalVisitor(){ + this(new ArrayList(1)); + } + + public DB2EvalVisitor(List parameters){ + this.parameters = parameters; + } + + public List getParameters() { + return parameters; + } + + public void setParameters(List parameters) { + this.parameters = parameters; + } + + public boolean visit(SQLCharExpr x) { + return SQLEvalVisitorUtils.visit(this, x); + } + + public int incrementAndGetVariantIndex() { + return ++variantIndex; + } + + public int getVariantIndex() { + return variantIndex; + } + + public boolean visit(SQLVariantRefExpr x) { + return SQLEvalVisitorUtils.visit(this, x); + } + + public boolean visit(SQLBinaryOpExpr x) { + return SQLEvalVisitorUtils.visit(this, x); + } + + public boolean visit(SQLUnaryExpr x) { + return SQLEvalVisitorUtils.visit(this, x); + } + + public boolean visit(SQLIntegerExpr x) { + return SQLEvalVisitorUtils.visit(this, x); + } + + public boolean visit(SQLNumberExpr x) { + return SQLEvalVisitorUtils.visit(this, x); + } + + @Override + public boolean visit(SQLCaseExpr x) { + return SQLEvalVisitorUtils.visit(this, x); + } + + @Override + public boolean visit(SQLInListExpr x) { + return SQLEvalVisitorUtils.visit(this, x); + } + + @Override + public boolean visit(SQLNullExpr x) { + return SQLEvalVisitorUtils.visit(this, x); + } + + @Override + public boolean visit(SQLMethodInvokeExpr x) { + return SQLEvalVisitorUtils.visit(this, x); + } + + @Override + public boolean visit(SQLQueryExpr x) { + return SQLEvalVisitorUtils.visit(this, x); + } + + public boolean isMarkVariantIndex() { + return markVariantIndex; + } + + public void setMarkVariantIndex(boolean markVariantIndex) { + this.markVariantIndex = markVariantIndex; + } + + @Override + public Function getFunction(String funcName) { + return functions.get(funcName); + } + + @Override + public void registerFunction(String funcName, Function function) { + functions.put(funcName, function); + } + + public boolean visit(SQLIdentifierExpr x) { + return SQLEvalVisitorUtils.visit(this, x); + } +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ExportParameterVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ExportParameterVisitor.java new file mode 100644 index 0000000000..d0af822640 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ExportParameterVisitor.java @@ -0,0 +1,87 @@ +/* + * 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.db2.visitor; + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.druid.sql.ast.SQLOrderBy; +import com.alibaba.druid.sql.ast.expr.SQLBetweenExpr; +import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; +import com.alibaba.druid.sql.ast.expr.SQLInListExpr; +import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; +import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause; +import com.alibaba.druid.sql.ast.statement.SQLSelectItem; +import com.alibaba.druid.sql.visitor.ExportParameterVisitor; +import com.alibaba.druid.sql.visitor.ExportParameterVisitorUtils; + +public class DB2ExportParameterVisitor extends DB2ASTVisitorAdapter implements ExportParameterVisitor { + + private final List parameters; + + public DB2ExportParameterVisitor(){ + this(new ArrayList()); + } + + public DB2ExportParameterVisitor(List parameters){ + this.parameters = parameters; + } + + public List getParameters() { + return parameters; + } + + @Override + public boolean visit(SQLSelectItem x) { + return false; + } + + @Override + public boolean visit(SQLOrderBy x) { + return false; + } + + @Override + public boolean visit(SQLSelectGroupByClause x) { + return false; + } + + @Override + public boolean visit(SQLMethodInvokeExpr x) { + ExportParameterVisitorUtils.exportParamterAndAccept(this.parameters, x.getParameters()); + + return true; + } + + @Override + public boolean visit(SQLInListExpr x) { + ExportParameterVisitorUtils.exportParamterAndAccept(this.parameters, x.getTargetList()); + + return true; + } + + @Override + public boolean visit(SQLBetweenExpr x) { + ExportParameterVisitorUtils.exportParameter(this.parameters, x); + return true; + } + + public boolean visit(SQLBinaryOpExpr x) { + ExportParameterVisitorUtils.exportParameter(this.parameters, x); + return true; + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2OutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2OutputVisitor.java new file mode 100644 index 0000000000..9e2adb0f91 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2OutputVisitor.java @@ -0,0 +1,10 @@ +package com.alibaba.druid.sql.dialect.db2.visitor; + +import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; + + +public class DB2OutputVisitor extends SQLASTOutputVisitor implements DB2ASTVisitor { + public DB2OutputVisitor(Appendable appender){ + super(appender); + } +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ParameterizedOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ParameterizedOutputVisitor.java new file mode 100644 index 0000000000..3235266edf --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ParameterizedOutputVisitor.java @@ -0,0 +1,88 @@ +/* + * 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.db2.visitor; + +import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; +import com.alibaba.druid.sql.ast.expr.SQLCharExpr; +import com.alibaba.druid.sql.ast.expr.SQLInListExpr; +import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr; +import com.alibaba.druid.sql.ast.expr.SQLNCharExpr; +import com.alibaba.druid.sql.ast.expr.SQLNullExpr; +import com.alibaba.druid.sql.ast.expr.SQLNumberExpr; +import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils; + +public class DB2ParameterizedOutputVisitor extends DB2OutputVisitor { + + public DB2ParameterizedOutputVisitor(){ + this(new StringBuilder()); + } + + public DB2ParameterizedOutputVisitor(Appendable appender){ + super(appender); + } + + public boolean visit(SQLInListExpr x) { + return ParameterizedOutputVisitorUtils.visit(this, x); + } + + public boolean visit(SQLBinaryOpExpr x) { + x = ParameterizedOutputVisitorUtils.merge(x); + + return super.visit(x); + } + + public boolean visit(SQLNullExpr x) { + print('?'); + return false; + } + + public boolean visit(SQLIntegerExpr x) { + if (Boolean.TRUE.equals(x.getAttribute(ParameterizedOutputVisitorUtils.ATTR_PARAMS_SKIP))) { + return super.visit(x); + } + + print('?'); + return false; + } + + public boolean visit(SQLNumberExpr x) { + if (Boolean.TRUE.equals(x.getAttribute(ParameterizedOutputVisitorUtils.ATTR_PARAMS_SKIP))) { + return super.visit(x); + } + + print('?'); + return false; + } + + public boolean visit(SQLCharExpr x) { + if (Boolean.TRUE.equals(x.getAttribute(ParameterizedOutputVisitorUtils.ATTR_PARAMS_SKIP))) { + return super.visit(x); + } + + print('?'); + return false; + } + + public boolean visit(SQLNCharExpr x) { + if (Boolean.TRUE.equals(x.getAttribute(ParameterizedOutputVisitorUtils.ATTR_PARAMS_SKIP))) { + return super.visit(x); + } + + print('?'); + return false; + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2SchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2SchemaStatVisitor.java new file mode 100644 index 0000000000..5ae94a43c0 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2SchemaStatVisitor.java @@ -0,0 +1,28 @@ +/* + * 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.db2.visitor; + +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.util.JdbcUtils; + +public class DB2SchemaStatVisitor extends SchemaStatVisitor implements DB2ASTVisitor { + + @Override + public String getDbType() { + return JdbcUtils.DB2; + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLParserUtils.java b/src/main/java/com/alibaba/druid/sql/parser/SQLParserUtils.java index 6a3c642b84..f7c90a83f6 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLParserUtils.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLParserUtils.java @@ -15,6 +15,8 @@ */ package com.alibaba.druid.sql.parser; +import com.alibaba.druid.sql.dialect.db2.parser.DB2ExprParser; +import com.alibaba.druid.sql.dialect.db2.parser.DB2StatementParser; import com.alibaba.druid.sql.dialect.mysql.parser.MySqlExprParser; import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; import com.alibaba.druid.sql.dialect.oracle.parser.OracleExprParser; @@ -55,6 +57,10 @@ public class SQLParserUtils { if (JdbcUtils.H2.equals(dbType)) { return new MySqlStatementParser(sql); } + + if (JdbcUtils.DB2.equals(dbType)) { + return new DB2StatementParser(sql); + } return new SQLStatementParser(sql); } @@ -81,6 +87,10 @@ public class SQLParserUtils { if (JdbcUtils.JTDS.equals(dbType)) { return new SQLServerExprParser(sql); } + + if (JdbcUtils.DB2.equals(dbType)) { + return new DB2ExprParser(sql); + } return new SQLExprParser(sql); } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java b/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java index 823bc6c903..499718ca8e 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java @@ -25,6 +25,7 @@ import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator; import com.alibaba.druid.sql.ast.expr.SQLInListExpr; import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr; import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; +import com.alibaba.druid.sql.dialect.db2.visitor.DB2ParameterizedOutputVisitor; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlParameterizedOutputVisitor; import com.alibaba.druid.sql.dialect.oracle.visitor.OracleParameterizedOutputVisitor; import com.alibaba.druid.sql.dialect.postgresql.visitor.PGParameterizedOutputVisitor; @@ -77,6 +78,10 @@ public class ParameterizedOutputVisitorUtils { if (JdbcUtils.SQL_SERVER.equals(dbType) || JdbcUtils.JTDS.equals(dbType)) { return new SQLServerParameterizedOutputVisitor(out); } + + if (JdbcUtils.DB2.equals(dbType)) { + return new DB2ParameterizedOutputVisitor(out); + } return new ParameterizedOutputVisitor(out); } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java index 9b299cae7a..3a151f5e8f 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java @@ -52,6 +52,7 @@ import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; import com.alibaba.druid.sql.ast.statement.SQLSelectItem; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; +import com.alibaba.druid.sql.dialect.db2.visitor.DB2EvalVisitor; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlEvalVisitorImpl; import com.alibaba.druid.sql.dialect.oracle.visitor.OracleEvalVisitor; import com.alibaba.druid.sql.dialect.postgresql.visitor.PGEvalVisitor; @@ -167,6 +168,10 @@ public class SQLEvalVisitorUtils { if (JdbcUtils.SQL_SERVER.equals(dbType)) { return new SQLServerEvalVisitor(); } + + if (JdbcUtils.DB2.equals(dbType)) { + return new DB2EvalVisitor(); + } return new SQLEvalVisitorImpl(); } diff --git a/src/main/java/com/alibaba/druid/wall/WallFilter.java b/src/main/java/com/alibaba/druid/wall/WallFilter.java index 3a41b68770..154ede83c8 100644 --- a/src/main/java/com/alibaba/druid/wall/WallFilter.java +++ b/src/main/java/com/alibaba/druid/wall/WallFilter.java @@ -34,6 +34,7 @@ import com.alibaba.druid.proxy.jdbc.StatementProxy; import com.alibaba.druid.support.logging.Log; import com.alibaba.druid.support.logging.LogFactory; import com.alibaba.druid.util.JdbcUtils; +import com.alibaba.druid.wall.spi.DB2WallProvider; import com.alibaba.druid.wall.spi.MySqlWallProvider; import com.alibaba.druid.wall.spi.OracleWallProvider; import com.alibaba.druid.wall.spi.PGWallProvider; @@ -97,6 +98,12 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean { } provider = new PGWallProvider(config); + } else if (JdbcUtils.DB2.equals(dbType)) { + if (config == null) { + config = new WallConfig(DB2WallProvider.DEFAULT_CONFIG_DIR); + } + + provider = new DB2WallProvider(config); } else { throw new IllegalStateException("dbType not support : " + dbType + ", url " + dataSource.getUrl()); } diff --git a/src/main/java/com/alibaba/druid/wall/WallUtils.java b/src/main/java/com/alibaba/druid/wall/WallUtils.java index f4f8d5e8d3..a30052dee2 100644 --- a/src/main/java/com/alibaba/druid/wall/WallUtils.java +++ b/src/main/java/com/alibaba/druid/wall/WallUtils.java @@ -15,12 +15,23 @@ */ package com.alibaba.druid.wall; +import com.alibaba.druid.wall.spi.DB2WallProvider; import com.alibaba.druid.wall.spi.MySqlWallProvider; import com.alibaba.druid.wall.spi.OracleWallProvider; import com.alibaba.druid.wall.spi.PGWallProvider; import com.alibaba.druid.wall.spi.SQLServerWallProvider; public class WallUtils { + public static boolean isValidateDB2(String sql) { + DB2WallProvider provider = new DB2WallProvider(); + return provider.checkValid(sql); + } + + public static boolean isValidateDB2(String sql, WallConfig config) { + DB2WallProvider provider = new DB2WallProvider(config); + return provider.checkValid(sql); + } + public static boolean isValidatePostgres(String sql) { PGWallProvider provider = new PGWallProvider(); return provider.checkValid(sql); diff --git a/src/main/java/com/alibaba/druid/wall/spi/DB2WallProvider.java b/src/main/java/com/alibaba/druid/wall/spi/DB2WallProvider.java new file mode 100644 index 0000000000..322364c922 --- /dev/null +++ b/src/main/java/com/alibaba/druid/wall/spi/DB2WallProvider.java @@ -0,0 +1,55 @@ +/* + * 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.wall.spi; + +import com.alibaba.druid.sql.dialect.db2.parser.DB2StatementParser; +import com.alibaba.druid.sql.dialect.db2.visitor.DB2ExportParameterVisitor; +import com.alibaba.druid.sql.parser.SQLStatementParser; +import com.alibaba.druid.sql.visitor.ExportParameterVisitor; +import com.alibaba.druid.util.JdbcConstants; +import com.alibaba.druid.wall.WallConfig; +import com.alibaba.druid.wall.WallProvider; +import com.alibaba.druid.wall.WallVisitor; + + +public class DB2WallProvider extends WallProvider { + + public final static String DEFAULT_CONFIG_DIR = "META-INF/druid/wall/db2"; + + public DB2WallProvider(){ + this(new WallConfig(DEFAULT_CONFIG_DIR)); + } + + public DB2WallProvider(WallConfig config){ + super(config, JdbcConstants.DB2); + } + + @Override + public SQLStatementParser createParser(String sql) { + return new DB2StatementParser(sql); + } + + @Override + public WallVisitor createWallVisitor() { + return new DB2WallVisitor(this); + } + + @Override + public ExportParameterVisitor createExportParameterVisitor() { + return new DB2ExportParameterVisitor(); + } + +} diff --git a/src/main/java/com/alibaba/druid/wall/spi/DB2WallVisitor.java b/src/main/java/com/alibaba/druid/wall/spi/DB2WallVisitor.java new file mode 100644 index 0000000000..f6b69567f8 --- /dev/null +++ b/src/main/java/com/alibaba/druid/wall/spi/DB2WallVisitor.java @@ -0,0 +1,210 @@ +package com.alibaba.druid.wall.spi; + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLName; +import com.alibaba.druid.sql.ast.SQLObject; +import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; +import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; +import com.alibaba.druid.sql.ast.expr.SQLInListExpr; +import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; +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.SQLDeleteStatement; +import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; +import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; +import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause; +import com.alibaba.druid.sql.ast.statement.SQLSelectItem; +import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; +import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; +import com.alibaba.druid.sql.ast.statement.SQLSetStatement; +import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; +import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; +import com.alibaba.druid.sql.dialect.db2.visitor.DB2ASTVisitorAdapter; +import com.alibaba.druid.wall.Violation; +import com.alibaba.druid.wall.WallConfig; +import com.alibaba.druid.wall.WallProvider; +import com.alibaba.druid.wall.WallVisitor; +import com.alibaba.druid.wall.violation.ErrorCode; +import com.alibaba.druid.wall.violation.IllegalSQLObjectViolation; + +public class DB2WallVisitor extends DB2ASTVisitorAdapter implements WallVisitor { + + private final WallConfig config; + private final WallProvider provider; + private final List violations = new ArrayList(); + + public DB2WallVisitor(WallProvider provider){ + this.config = provider.getConfig(); + this.provider = provider; + } + + public WallProvider getProvider() { + return provider; + } + + public WallConfig getConfig() { + return config; + } + + public void addViolation(Violation violation) { + this.violations.add(violation); + } + + public List getViolations() { + return violations; + } + + public boolean visit(SQLIdentifierExpr x) { + String name = x.getName(); + name = WallVisitorUtils.form(name); + if (config.isVariantCheck() && config.getDenyVariants().contains(name)) { + getViolations().add(new IllegalSQLObjectViolation(ErrorCode.VARIANT_DENY, "variable not allow : " + name, + toSQL(x))); + } + return true; + } + + public boolean visit(SQLPropertyExpr x) { + WallVisitorUtils.check(this, x); + return true; + } + + public boolean visit(SQLInListExpr x) { + WallVisitorUtils.check(this, x); + return true; + } + + public boolean visit(SQLBinaryOpExpr x) { + WallVisitorUtils.check(this, x); + return true; + } + + @Override + public boolean visit(SQLMethodInvokeExpr x) { + WallVisitorUtils.checkFunction(this, x); + + return true; + } + + public boolean visit(SQLExprTableSource x) { + WallVisitorUtils.check(this, x); + + if (x.getExpr() instanceof SQLName) { + return false; + } + + return true; + } + + public boolean visit(SQLSelectGroupByClause x) { + WallVisitorUtils.checkHaving(this, x.getHaving()); + return true; + } + + @Override + public boolean visit(SQLSelectQueryBlock x) { + WallVisitorUtils.checkSelelct(this, x); + + return true; + } + + @Override + public boolean visit(SQLUnionQuery x) { + WallVisitorUtils.checkUnion(this, x); + + return true; + } + + @Override + public String toSQL(SQLObject obj) { + return SQLUtils.toOracleString(obj); + } + + @Override + public boolean isDenyTable(String name) { + if (!config.isTableCheck()) { + return false; + } + + name = WallVisitorUtils.form(name); + if (name.startsWith("v$") || name.startsWith("v_$")) { + return true; + } + return !this.provider.checkDenyTable(name); + } + + public void preVisit(SQLObject x) { + WallVisitorUtils.preVisitCheck(this, x); + } + + @Override + public boolean visit(SQLSelectStatement x) { + if (!config.isSelelctAllow()) { + this.getViolations().add(new IllegalSQLObjectViolation(ErrorCode.SELECT_NOT_ALLOW, "selelct not allow", + this.toSQL(x))); + return false; + } + + return true; + } + + @Override + public boolean visit(SQLInsertStatement x) { + WallVisitorUtils.checkInsert(this, x); + + return true; + } + + @Override + public boolean visit(SQLDeleteStatement x) { + WallVisitorUtils.checkDelete(this, x); + return true; + } + + @Override + public boolean visit(SQLUpdateStatement x) { + WallVisitorUtils.checkUpdate(this, x); + + return true; + } + + @Override + public boolean visit(SQLSelectItem x) { + WallVisitorUtils.check(this, x); + return true; + } + + @Override + public boolean visit(SQLCreateTableStatement x) { + WallVisitorUtils.check(this, x); + return true; + } + + @Override + public boolean visit(SQLAlterTableStatement x) { + WallVisitorUtils.check(this, x); + return true; + } + + @Override + public boolean visit(SQLDropTableStatement x) { + WallVisitorUtils.check(this, x); + return true; + } + + @Override + public boolean visit(SQLSetStatement x) { + return false; + } + + @Override + public boolean visit(SQLCallStatement 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 3ec1bb7bfc..a0258d1a39 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/OracleWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/OracleWallVisitor.java @@ -40,7 +40,6 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; import com.alibaba.druid.sql.ast.statement.SQLSetStatement; import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplaceStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateTableStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement; @@ -89,7 +88,8 @@ public class OracleWallVisitor extends OracleASTVisitorAdapter implements WallVi String name = x.getName(); name = WallVisitorUtils.form(name); if (config.isVariantCheck() && config.getDenyVariants().contains(name)) { - getViolations().add(new IllegalSQLObjectViolation(ErrorCode.VARIANT_DENY, "variable not allow : " + name, toSQL(x))); + getViolations().add(new IllegalSQLObjectViolation(ErrorCode.VARIANT_DENY, "variable not allow : " + name, + toSQL(x))); } return true; } @@ -181,7 +181,8 @@ public class OracleWallVisitor extends OracleASTVisitorAdapter implements WallVi @Override public boolean visit(SQLSelectStatement x) { if (!config.isSelelctAllow()) { - this.getViolations().add(new IllegalSQLObjectViolation(ErrorCode.SELECT_NOT_ALLOW, "select not allow", this.toSQL(x))); + this.getViolations().add(new IllegalSQLObjectViolation(ErrorCode.SELECT_NOT_ALLOW, "select not allow", + this.toSQL(x))); return false; } @@ -210,7 +211,8 @@ public class OracleWallVisitor extends OracleASTVisitorAdapter implements WallVi @Override public boolean visit(OracleMultiInsertStatement x) { if (!config.isInsertAllow()) { - this.getViolations().add(new IllegalSQLObjectViolation(ErrorCode.INSERT_NOT_ALLOW, "insert not allow", this.toSQL(x))); + this.getViolations().add(new IllegalSQLObjectViolation(ErrorCode.INSERT_NOT_ALLOW, "insert not allow", + this.toSQL(x))); return false; } @@ -257,34 +259,30 @@ public class OracleWallVisitor extends OracleASTVisitorAdapter implements WallVi WallVisitorUtils.check(this, x); return true; } - + @Override public boolean visit(SQLAlterTableStatement x) { WallVisitorUtils.check(this, x); return true; } - + @Override public boolean visit(OracleAlterTableStatement x) { WallVisitorUtils.check(this, x); return true; } - + @Override public boolean visit(SQLDropTableStatement x) { WallVisitorUtils.check(this, x); return true; } - + @Override public boolean visit(SQLSetStatement x) { return false; } - - public boolean visit(MySqlReplaceStatement x) { - return true; - } - + @Override public boolean visit(SQLCallStatement 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 0fa2c17cd8..03d1a72fb8 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/PGWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/PGWallVisitor.java @@ -40,8 +40,6 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; import com.alibaba.druid.sql.ast.statement.SQLSetStatement; import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplaceStatement; -import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableReference; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock; import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitorAdapter; import com.alibaba.druid.wall.Violation; @@ -82,7 +80,8 @@ public class PGWallVisitor extends PGASTVisitorAdapter implements WallVisitor { String name = x.getName(); name = WallVisitorUtils.form(name); if (config.isVariantCheck() && config.getDenyVariants().contains(name)) { - getViolations().add(new IllegalSQLObjectViolation(ErrorCode.VARIANT_DENY, "variable not allow : " + name, toSQL(x))); + getViolations().add(new IllegalSQLObjectViolation(ErrorCode.VARIANT_DENY, "variable not allow : " + name, + toSQL(x))); } return true; } @@ -109,10 +108,6 @@ public class PGWallVisitor extends PGASTVisitorAdapter implements WallVisitor { return true; } - public boolean visit(OracleSelectTableReference x) { - return WallVisitorUtils.check(this, x); - } - public boolean visit(SQLExprTableSource x) { WallVisitorUtils.check(this, x); @@ -134,11 +129,11 @@ public class PGWallVisitor extends PGASTVisitorAdapter implements WallVisitor { return true; } - + @Override public boolean visit(PGSelectQueryBlock x) { WallVisitorUtils.checkSelelct(this, x); - + return true; } @@ -174,7 +169,8 @@ public class PGWallVisitor extends PGASTVisitorAdapter implements WallVisitor { @Override public boolean visit(SQLSelectStatement x) { if (!config.isSelelctAllow()) { - this.getViolations().add(new IllegalSQLObjectViolation(ErrorCode.SELECT_NOT_ALLOW, "selelct not allow", this.toSQL(x))); + this.getViolations().add(new IllegalSQLObjectViolation(ErrorCode.SELECT_NOT_ALLOW, "selelct not allow", + this.toSQL(x))); return false; } @@ -206,34 +202,30 @@ public class PGWallVisitor extends PGASTVisitorAdapter implements WallVisitor { WallVisitorUtils.check(this, x); return true; } - + @Override public boolean visit(SQLCreateTableStatement x) { WallVisitorUtils.check(this, x); return true; } - + @Override public boolean visit(SQLAlterTableStatement x) { WallVisitorUtils.check(this, x); return true; } - + @Override public boolean visit(SQLDropTableStatement x) { WallVisitorUtils.check(this, x); return true; } - + @Override public boolean visit(SQLSetStatement x) { return false; } - - public boolean visit(MySqlReplaceStatement x) { - return true; - } - + @Override public boolean visit(SQLCallStatement 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 a56bc930bf..13a1b68e39 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java @@ -41,7 +41,6 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; import com.alibaba.druid.sql.ast.statement.SQLSetStatement; import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplaceStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock; import com.alibaba.druid.sql.dialect.sqlserver.ast.expr.SQLServerObjectReferenceExpr; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement; @@ -306,10 +305,6 @@ public class SQLServerWallVisitor extends SQLServerASTVisitorAdapter implements return false; } - public boolean visit(MySqlReplaceStatement x) { - return true; - } - @Override public boolean visit(SQLCallStatement x) { return false; diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlInsertTest_8.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlInsertTest_8.java new file mode 100644 index 0000000000..de2d0cae00 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlInsertTest_8.java @@ -0,0 +1,58 @@ +/* + * 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.mysql; + +import java.util.List; + +import org.junit.Assert; + +import com.alibaba.druid.sql.MysqlTest; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement; +import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor; + +public class MySqlInsertTest_8 extends MysqlTest { + + public void test_0() throws Exception { + String sql = "insert into dd.table1(d,e) select * from bb.table3"; + + MySqlStatementParser parser = new MySqlStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + + MySqlInsertStatement insertStmt = (MySqlInsertStatement) stmt; + + Assert.assertEquals(2, insertStmt.getColumns().size()); + Assert.assertEquals(0, insertStmt.getValuesList().size()); + + Assert.assertEquals(1, statementList.size()); + + MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); + stmt.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals("INSERT INTO dd.table1 (d, e)" // + + "\nSELECT *" // + + "\nFROM bb.table3", // + SQLUtils.toMySqlString(insertStmt)); + } +}