improve sql wall

This commit is contained in:
wenshao
2013-08-26 20:53:06 +08:00
parent b4f345fb7a
commit b3bbdf9eb5
5 changed files with 66 additions and 17 deletions
@@ -52,6 +52,7 @@ import com.alibaba.druid.sql.ast.expr.SQLUnaryExpr;
import com.alibaba.druid.sql.ast.expr.SQLUnaryOperator;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
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;
@@ -605,8 +606,32 @@ public class SQLEvalVisitorUtils {
return false;
}
public static SQLExpr unwrap(SQLExpr expr) {
if (expr == null) {
return null;
}
if (expr instanceof SQLQueryExpr) {
SQLSelect select = ((SQLQueryExpr) expr).getSubQuery();
if (select == null) {
return null;
}
if (select.getQuery() instanceof SQLSelectQueryBlock) {
SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) select.getQuery();
if (queryBlock.getFrom() == null) {
if (queryBlock.getSelectList().size() == 1) {
return queryBlock.getSelectList().get(0).getExpr();
}
}
}
}
return expr;
}
public static boolean visit(SQLEvalVisitor visitor, SQLBetweenExpr x) {
x.getTestExpr().accept(visitor);
SQLExpr testExpr = unwrap(x.getTestExpr());
testExpr.accept(visitor);
if (!x.getTestExpr().getAttributes().containsKey(EVAL_VALUE)) {
return false;
@@ -912,8 +937,12 @@ public class SQLEvalVisitorUtils {
x.putAttribute(EVAL_VALUE, value);
break;
case Divide:
value = div(leftValue, rightValue);
x.putAttribute(EVAL_VALUE, value);
if (rightValue instanceof Number && ((Number) rightValue).intValue() == 0) {
x.putAttribute(EVAL_VALUE, EVAL_ERROR);
} else {
value = div(leftValue, rightValue);
x.putAttribute(EVAL_VALUE, value);
}
break;
case RightShift:
value = rightShift(leftValue, rightValue);
@@ -1161,7 +1190,11 @@ public class SQLEvalVisitorUtils {
}
}
return ((Number) val).intValue();
if (val instanceof Number) {
return ((Number) val).intValue();
}
throw new DruidRuntimeException("cast error");
}
@SuppressWarnings("rawtypes")
@@ -1334,7 +1367,9 @@ public class SQLEvalVisitorUtils {
}
if (a instanceof BigDecimal || b instanceof BigDecimal) {
return castToDecimal(a).divide(castToDecimal(b));
BigDecimal decimalA = castToDecimal(a);
BigDecimal decimalB = castToDecimal(b);
return decimalA.divide(decimalB, BigDecimal.ROUND_HALF_UP);
}
if (a instanceof Double || b instanceof Double) {
@@ -1364,7 +1399,9 @@ public class SQLEvalVisitorUtils {
}
if (a instanceof Integer || b instanceof Integer) {
return castToInteger(a) / castToInteger(b);
Integer intA = castToInteger(a);
Integer intB = castToInteger(b);
return intA / intB;
}
if (a instanceof Short || b instanceof Short) {
@@ -1379,11 +1416,11 @@ public class SQLEvalVisitorUtils {
}
public static boolean gt(Object a, Object b) {
if (a == null) {
if (a == null || a == EVAL_VALUE_NULL) {
return false;
}
if (b == null) {
if (b == null || a == EVAL_VALUE_NULL) {
return true;
}
@@ -1471,7 +1508,9 @@ public class SQLEvalVisitorUtils {
}
if (a instanceof Integer || b instanceof Integer) {
return castToInteger(a) < castToInteger(b);
Integer intA = castToInteger(a);
Integer intB = castToInteger(b);
return intA < intB;
}
if (a instanceof Short || b instanceof Short) {
@@ -44,6 +44,10 @@ public class Left implements Function {
String strValue = param0Value.toString();
int intValue = SQLEvalVisitorUtils.castToInteger(param1Value);
if (intValue > strValue.length()) {
return SQLEvalVisitor.EVAL_ERROR;
}
String result = strValue.substring(0, intValue);
@@ -20,6 +20,7 @@ import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_VALUE;
import java.io.UnsupportedEncodingException;
import com.alibaba.druid.DruidRuntimeException;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
@@ -61,6 +62,10 @@ public class Unhex implements Function {
if (param0Value instanceof String) {
byte[] bytes = HexBin.decode((String) param0Value);
if (bytes == null) {
return SQLEvalVisitor.EVAL_VALUE_NULL;
}
String result;
try {
result = new String(bytes, "UTF-8");
@@ -215,7 +215,7 @@ public class WallVisitorUtils {
SQLExpr where = x.getWhere();
if (where != null) {
if (queryBlockFromIsNull(visitor, x, false)) {
addViolation(visitor, ErrorCode.EmptyQueryHasCondition, "empty select has condition", x);
addViolation(visitor, ErrorCode.EMPTY_QUERY_HAS_CONDITION, "empty select has condition", x);
}
where.setParent(x);
@@ -650,7 +650,7 @@ public class WallVisitorUtils {
Object rightResult = getValue(visitor, right);
if (x.getOperator() == SQLBinaryOperator.Like && leftResult instanceof String && leftResult.equals(rightResult)) {
addViolation(visitor, ErrorCode.SameConstLike, "same const like", x);
addViolation(visitor, ErrorCode.SAME_CONST_LIKE, "same const like", x);
}
if (x.getOperator() == SQLBinaryOperator.Like || x.getOperator() == SQLBinaryOperator.NotLike) {
@@ -670,14 +670,14 @@ public class WallVisitorUtils {
&& leftBinaryOpExpr.getOperator() != SQLBinaryOperator.BooleanOr //
&& leftResult != null //
&& visitor != null) {
addViolation(visitor, ErrorCode.DoubleConstCondition, "double const condition", x);
addViolation(visitor, ErrorCode.DOUBLE_CONST_CONDITION, "double const condition", x);
}
if (leftBinaryOpExpr.getOperator() == SQLBinaryOperator.BooleanAnd //
|| leftBinaryOpExpr.getOperator() == SQLBinaryOperator.BooleanOr) {
Object leftRightVal = getValue(leftBinaryOpExpr.getRight());
if (leftRightVal != null) {
addViolation(visitor, ErrorCode.DoubleConstCondition, "double const condition", x);
addViolation(visitor, ErrorCode.DOUBLE_CONST_CONDITION, "double const condition", x);
}
}
}
@@ -1029,7 +1029,8 @@ public class WallVisitorUtils {
if (caseExpr.getItems().size() > 0) {
SQLCaseExpr.Item item = caseExpr.getItems().get(0);
Object conditionVal = getValue(visitor, item.getConditionExpr());
if (conditionVal instanceof Boolean) {
Object itemVal = getValue(visitor, item.getValueExpr());
if (conditionVal instanceof Boolean && itemVal != null) {
addViolation(visitor, ErrorCode.CONST_CASE_CONDITION, "const case condition", caseExpr);
}
}
@@ -60,9 +60,9 @@ public interface ErrorCode {
public final static int BITWISE = 2103;
public final static int NONE_CONDITION = 2104;
public final static int LIKE_NUMBER = 2105;
public final static int EmptyQueryHasCondition = 2106;
public final static int DoubleConstCondition = 2107;
public final static int SameConstLike = 2108;
public final static int EMPTY_QUERY_HAS_CONDITION = 2106;
public final static int DOUBLE_CONST_CONDITION = 2107;
public final static int SAME_CONST_LIKE = 2108;
public final static int CONST_CASE_CONDITION = 2109;
public final static int NOT_PARAMETERIZED = 2200;