diff --git a/pom.xml b/pom.xml index 47e8279073..07a6b82ee7 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ 4.11 true - false + true UTF-8 1.6 diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java index 1bcced37c9..df5b00b2c8 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java @@ -83,6 +83,8 @@ import com.alibaba.druid.sql.parser.Token; public class OracleExprParser extends SQLExprParser { + + public boolean allowStringAdditive = false; /** @@ -480,12 +482,37 @@ public class OracleExprParser extends SQLExprParser { protected SQLExpr methodRest(SQLExpr expr, boolean acceptLPAREN) { if (acceptLPAREN) { accept(Token.LPAREN); - if (lexer.token() == Token.PLUS) { - lexer.nextToken(); + } + + if (lexer.token() == Token.PLUS) { + lexer.nextToken(); + accept(Token.RPAREN); + return new OracleOuterExpr(expr); + } + + if (expr instanceof SQLIdentifierExpr) { + String methodName = ((SQLIdentifierExpr) expr).getName(); + SQLMethodInvokeExpr methodExpr = new SQLMethodInvokeExpr(methodName); + if ("trim".equalsIgnoreCase(methodName)) { + if (identifierEquals("LEADING") // + || identifierEquals("TRAILING") // + || identifierEquals("BOTH") + ) { + methodExpr.putAttribute("trim_option", lexer.stringVal()); + lexer.nextToken(); + } + SQLExpr trim_character = this.primary(); + trim_character.setParent(methodExpr); + methodExpr.putAttribute("trim_character", trim_character); + accept(Token.FROM); + SQLExpr trim_source = this.expr(); + methodExpr.addParameter(trim_source); + accept(Token.RPAREN); - return new OracleOuterExpr(expr); + return primaryRest(methodExpr); } } + return super.methodRest(expr, false); } 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 9137c0f10b..0e2c1c5731 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 @@ -3383,4 +3383,27 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS protected void printCascade() { print(" CASCADE CONSTRAINTS"); } + + @Override + public boolean visit(SQLMethodInvokeExpr x) { + if ("trim".equalsIgnoreCase(x.getMethodName())) { + SQLExpr trim_character = (SQLExpr) x.getAttribute("trim_character"); + if (trim_character != null) { + print(x.getMethodName()); + print("("); + String trim_option = (String) x.getAttribute("trim_option"); + if (trim_option != null && trim_option.length() != 0) { + print(trim_option); + print(' '); + } + trim_character.accept(this); + print(" FROM "); + x.getParameters().get(0).accept(this); + print(")"); + return false; + } + } + + return super.visit(x); + } } diff --git a/src/main/java/com/alibaba/druid/wall/WallConfig.java b/src/main/java/com/alibaba/druid/wall/WallConfig.java index e417b7d0fd..87d840d5cb 100644 --- a/src/main/java/com/alibaba/druid/wall/WallConfig.java +++ b/src/main/java/com/alibaba/druid/wall/WallConfig.java @@ -108,10 +108,20 @@ public class WallConfig implements WallConfigMBean { private boolean conditionOpXorAllow = false; private boolean conditionOpBitwseAllow = true; + private boolean caseConditionAllow = false; + public WallConfig(){ } + public boolean isCaseConditionAllow() { + return caseConditionAllow; + } + + public void setCaseConditionAllow(boolean caseConditionAllow) { + this.caseConditionAllow = caseConditionAllow; + } + public boolean isConditionDoubleConstAllow() { return conditionDoubleConstAllow; } 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 7731795ae8..f918f6455a 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java @@ -44,6 +44,7 @@ import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; 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.SQLServerExecStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement; import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerASTVisitor; import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerASTVisitorAdapter; @@ -152,6 +153,10 @@ public class SQLServerWallVisitor extends SQLServerASTVisitorAdapter implements return true; } + @Override + public boolean visit(SQLServerExecStatement x) { + return false; + } public boolean visit(SQLExprTableSource x) { WallVisitorUtils.check(this, x); 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 9b58390d80..559e2f1c43 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java @@ -257,7 +257,7 @@ public class WallVisitorUtils { boolean isSimpleConstExpr = false; SQLExpr first = getFirst(where); - if (first == where) { + if (first == where || first instanceof SQLLiteralExpr) { isSimpleConstExpr = true; } else if (first instanceof SQLBinaryOpExpr) { SQLBinaryOpExpr binaryOpExpr = (SQLBinaryOpExpr) first; @@ -278,7 +278,6 @@ public class WallVisitorUtils { addViolation(visitor, ErrorCode.ALWAY_TRUE, "select alway true condition not allow", x); } } - } checkConditionForMultiTenant(visitor, x.getWhere(), x); } finally { @@ -1046,9 +1045,18 @@ public class WallVisitorUtils { return SQLEvalVisitorUtils.eval(dbType, x, Collections.emptyList(), false); } - if (x instanceof SQLCaseExpr) { + if (visitor != null && (!visitor.getConfig().isCaseConditionAllow()) && x instanceof SQLCaseExpr) { SQLCaseExpr caseExpr = (SQLCaseExpr) x; - if (caseExpr.getItems().size() > 0) { + + boolean leftIsName = false; + if (caseExpr.getParent() instanceof SQLBinaryOpExpr) { + SQLExpr left = ((SQLBinaryOpExpr) caseExpr.getParent()).getLeft(); + if (left instanceof SQLName) { + leftIsName = true; + } + } + + if ((!leftIsName) && caseExpr.getItems().size() > 0) { SQLCaseExpr.Item item = caseExpr.getItems().get(0); Object conditionVal = getValue(visitor, item.getConditionExpr()); Object itemVal = getValue(visitor, item.getValueExpr());