improve sql-wal

This commit is contained in:
wenshao
2013-08-25 09:43:58 +08:00
parent 0526585337
commit 1533ecad26
31 changed files with 579 additions and 85 deletions
@@ -52,12 +52,6 @@ public class SQLUnaryExpr extends SQLExprImpl implements Serializable {
this.expr = expr;
}
@Override
public void output(StringBuffer buf) {
buf.append(" NOT ");
this.expr.output(buf);
}
protected void accept0(SQLASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, this.expr);
@@ -30,7 +30,7 @@ public class SQLColumnDefinition extends SQLObjectImpl implements SQLTableElemen
protected SQLDataType dataType;
protected SQLExpr defaultExpr;
protected final List<SQLColumnConstraint> constaints = new ArrayList<SQLColumnConstraint>(0);
protected String comment;
protected SQLExpr comment;
protected Boolean enable;
@@ -99,11 +99,11 @@ public class SQLColumnDefinition extends SQLObjectImpl implements SQLTableElemen
visitor.endVisit(this);
}
public String getComment() {
public SQLExpr getComment() {
return comment;
}
public void setComment(String comment) {
public void setComment(SQLExpr comment) {
this.comment = comment;
}
@@ -135,7 +135,7 @@ public class DB2EvalVisitor extends DB2ASTVisitorAdapter implements SQLEvalVisit
public void registerFunction(String funcName, Function function) {
functions.put(funcName, function);
}
public boolean visit(SQLIdentifierExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
@@ -558,12 +558,6 @@ public class MySqlExprParser extends SQLExprParser {
throw new ParserException("syntax error " + lexer.token() + " " + lexer.stringVal());
}
if (lexer.token() == Token.COMMENT) {
lexer.nextToken();
column.setComment(lexer.stringVal());
accept(Token.LITERAL_CHARS);
}
if (identifierEquals("STORAGE")) {
lexer.nextToken();
SQLExpr expr = expr();
@@ -727,7 +721,7 @@ public class MySqlExprParser extends SQLExprParser {
if (lexer.token() == Token.KEY) {
lexer.nextToken();
}
if (lexer.token() == Token.INDEX) {
lexer.nextToken();
}
@@ -24,6 +24,7 @@ import com.alibaba.druid.sql.ast.expr.SQLBetweenExpr;
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.SQLHexExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLInListExpr;
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
@@ -33,6 +34,7 @@ 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.dialect.mysql.ast.expr.MySqlBinaryExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBooleanExpr;
import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
import com.alibaba.druid.sql.visitor.SQLEvalVisitorUtils;
@@ -94,6 +96,14 @@ public class MySqlEvalVisitorImpl extends MySqlASTVisitorAdapter implements SQLE
public boolean visit(SQLNumberExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
public boolean visit(SQLHexExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
public boolean visit(MySqlBinaryExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
@Override
public boolean visit(SQLCaseExpr x) {
@@ -324,6 +324,11 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
print(' ');
item.accept(this);
}
if (x.getComment() != null) {
print(" COMMENT ");
x.getComment().accept(this);
}
return false;
}
@@ -135,7 +135,7 @@ public class OracleEvalVisitor extends OracleASTVisitorAdapter implements SQLEva
public void registerFunction(String funcName, Function function) {
functions.put(funcName, function);
}
public boolean visit(SQLIdentifierExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
@@ -135,7 +135,7 @@ public class PGEvalVisitor extends PGASTVisitorAdapter implements SQLEvalVisitor
public void registerFunction(String funcName, Function function) {
functions.put(funcName, function);
}
public boolean visit(SQLIdentifierExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
@@ -92,7 +92,7 @@ public class SQLServerEvalVisitor extends SQLServerASTVisitorAdapter implements
public boolean visit(SQLNumberExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
@Override
public boolean visit(SQLCaseExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
@@ -1478,7 +1478,7 @@ public class SQLExprParser extends SQLParser {
column.getConstaints().add(check);
return parseColumnRest(column);
}
if (lexer.token == Token.DEFAULT) {
lexer.nextToken();
SQLExpr expr = this.expr();
@@ -1494,6 +1494,11 @@ public class SQLExprParser extends SQLParser {
column.getConstaints().add(check);
return parseColumnRest(column);
}
if (lexer.token() == Token.COMMENT) {
lexer.nextToken();
column.setComment(primary());
}
return column;
}
@@ -23,6 +23,7 @@ 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.SQLHexExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLInListExpr;
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
@@ -86,6 +87,10 @@ public class SQLEvalVisitorImpl extends SQLASTVisitorAdapter implements SQLEvalV
public boolean visit(SQLNumberExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
public boolean visit(SQLHexExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
@Override
public boolean visit(SQLCaseExpr x) {
@@ -15,6 +15,7 @@
*/
package com.alibaba.druid.sql.visitor;
import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_ERROR;
import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_EXPR;
import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_VALUE;
import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_VALUE_NULL;
@@ -40,6 +41,7 @@ import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
import com.alibaba.druid.sql.ast.expr.SQLCaseExpr;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLHexExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLInListExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
@@ -53,6 +55,7 @@ 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.ast.expr.MySqlBinaryExpr;
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;
@@ -84,6 +87,7 @@ import com.alibaba.druid.sql.visitor.functions.Substring;
import com.alibaba.druid.sql.visitor.functions.Trim;
import com.alibaba.druid.sql.visitor.functions.Ucase;
import com.alibaba.druid.sql.visitor.functions.Unhex;
import com.alibaba.druid.util.HexBin;
import com.alibaba.druid.util.JdbcUtils;
import com.alibaba.druid.wall.spi.WallVisitorUtils;
import com.alibaba.druid.wall.spi.WallVisitorUtils.WallConditionContext;
@@ -192,6 +196,7 @@ public class SQLEvalVisitorUtils {
functions.put("lpad", Lpad.instance);
functions.put("ltrim", Ltrim.instance);
functions.put("mid", Substring.instance);
functions.put("substr", Substring.instance);
functions.put("substring", Substring.instance);
functions.put("right", Right.instance);
functions.put("reverse", Reverse.instance);
@@ -554,6 +559,19 @@ public class SQLEvalVisitorUtils {
return true;
}
public static boolean visit(SQLEvalVisitor visitor, SQLHexExpr x) {
String hex = x.getHex();
byte[] bytes = HexBin.decode(hex);
String val = new String(bytes);
x.putAttribute(EVAL_VALUE, val);
return true;
}
public static boolean visit(SQLEvalVisitor visitor, MySqlBinaryExpr x) {
return true;
}
public static boolean visit(SQLEvalVisitor visitor, SQLBetweenExpr x) {
x.getTestExpr().accept(visitor);
@@ -715,6 +733,36 @@ public class SQLEvalVisitorUtils {
wallConditionContext.setBitwise(true);
}
x.getExpr().accept(visitor);
Object val = x.getExpr().getAttribute(EVAL_VALUE);
if (val == EVAL_ERROR) {
x.putAttribute(EVAL_VALUE, EVAL_ERROR);
return false;
}
switch (x.getOperator()) {
case BINARY:
case RAW:
x.putAttribute(EVAL_VALUE, val);
break;
case NOT:
case Not:
x.putAttribute(EVAL_VALUE, !castToBoolean(val));
break;
case Plus:
x.putAttribute(EVAL_VALUE, val);
break;
case Negative:
x.putAttribute(EVAL_VALUE, multi(val, -1));
break;
case Compl:
x.putAttribute(EVAL_VALUE, ~castToInteger(val));
break;
default:
break;
}
return false;
}
@@ -834,6 +882,18 @@ public class SQLEvalVisitorUtils {
value = div(leftValue, rightValue);
x.putAttribute(EVAL_VALUE, value);
break;
case RightShift:
value = rightShift(leftValue, rightValue);
x.putAttribute(EVAL_VALUE, value);
break;
case BitwiseAnd:
value = bitAnd(leftValue, rightValue);
x.putAttribute(EVAL_VALUE, value);
break;
case BitwiseOr:
value = bitOr(leftValue, rightValue);
x.putAttribute(EVAL_VALUE, value);
break;
case GreaterThan:
value = gt(leftValue, rightValue);
x.putAttribute(EVAL_VALUE, value);
@@ -978,7 +1038,17 @@ public class SQLEvalVisitorUtils {
}
if (val instanceof Number) {
return ((Number) val).intValue() == 1;
return ((Number) val).intValue() > 0;
}
if (val instanceof String) {
if ("1".equals(val) || "true".equalsIgnoreCase((String) val)) {
return true;
}
if ("0".equals(val) || "false".equalsIgnoreCase((String) val)) {
return false;
}
}
throw new IllegalArgumentException(val.getClass() + " not supported.");
@@ -1186,6 +1256,42 @@ public class SQLEvalVisitorUtils {
return BigDecimal.valueOf(((Number) val).longValue());
}
public static Object rightShift(Object a, Object b) {
if (a == null || b == null) {
return null;
}
if (a instanceof Long || b instanceof Long) {
return castToLong(a).longValue() >> castToLong(b).longValue();
}
return castToInteger(a).intValue() >> castToInteger(b).intValue();
}
public static Object bitAnd(Object a, Object b) {
if (a == null || b == null) {
return null;
}
if (a instanceof Long || b instanceof Long) {
return castToLong(a).longValue() & castToLong(b).longValue();
}
return castToInteger(a).intValue() & castToInteger(b).intValue();
}
public static Object bitOr(Object a, Object b) {
if (a == null || b == null) {
return null;
}
if (a instanceof Long || b instanceof Long) {
return castToLong(a).longValue() | castToLong(b).longValue();
}
return castToInteger(a).intValue() | castToInteger(b).intValue();
}
public static Object div(Object a, Object b) {
if (a == null || b == null) {
return null;
@@ -16,6 +16,7 @@
package com.alibaba.druid.sql.visitor.functions;
import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_VALUE;
import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_VALUE_NULL;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
@@ -31,15 +32,19 @@ public class Ascii implements Function {
}
SQLExpr param = x.getParameters().get(0);
param.accept(visitor);
Object paramValue = param.getAttributes().get(EVAL_VALUE);
if (paramValue == null) {
return SQLEvalVisitor.EVAL_ERROR;
}
if (paramValue == EVAL_VALUE_NULL) {
return EVAL_VALUE_NULL;
}
String strValue = paramValue.toString();
if (strValue.length() == 0) {
return SQLEvalVisitor.EVAL_ERROR;
return 0;
}
int ascii = strValue.charAt(0);
@@ -37,4 +37,6 @@ public interface WallVisitor extends SQLASTVisitor {
boolean isSqlModified();
void setSqlModified(boolean sqlModified);
String getDbType();
}
@@ -43,6 +43,7 @@ import com.alibaba.druid.sql.ast.statement.SQLUnionQuery;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2SelectQueryBlock;
import com.alibaba.druid.sql.dialect.db2.visitor.DB2ASTVisitorAdapter;
import com.alibaba.druid.util.JdbcConstants;
import com.alibaba.druid.wall.Violation;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallProvider;
@@ -62,6 +63,11 @@ public class DB2WallVisitor extends DB2ASTVisitorAdapter implements WallVisitor
this.provider = provider;
}
@Override
public String getDbType() {
return JdbcConstants.DB2;
}
@Override
public boolean isSqlModified() {
return sqlModified;
@@ -57,6 +57,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnionQuery;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter;
import com.alibaba.druid.util.JdbcConstants;
import com.alibaba.druid.wall.Violation;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallContext;
@@ -77,6 +78,11 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi
this.config = provider.getConfig();
this.provider = provider;
}
@Override
public String getDbType() {
return JdbcConstants.MYSQL;
}
@Override
public boolean isSqlModified() {
@@ -51,6 +51,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectQueryBlock;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableReference;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleUpdateStatement;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitorAdapter;
import com.alibaba.druid.util.JdbcConstants;
import com.alibaba.druid.wall.Violation;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallProvider;
@@ -69,6 +70,11 @@ public class OracleWallVisitor extends OracleASTVisitorAdapter implements WallVi
this.config = provider.getConfig();
this.provider = provider;
}
@Override
public String getDbType() {
return JdbcConstants.ORACLE;
}
@Override
public boolean isSqlModified() {
@@ -43,6 +43,7 @@ import com.alibaba.druid.sql.ast.statement.SQLUnionQuery;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock;
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitorAdapter;
import com.alibaba.druid.util.JdbcConstants;
import com.alibaba.druid.wall.Violation;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallProvider;
@@ -61,6 +62,11 @@ public class PGWallVisitor extends PGASTVisitorAdapter implements WallVisitor {
this.config = provider.getConfig();
this.provider = provider;
}
@Override
public String getDbType() {
return JdbcConstants.POSTGRESQL;
}
@Override
public boolean isSqlModified() {
@@ -47,6 +47,7 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.expr.SQLServerObjectReference
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;
import com.alibaba.druid.util.JdbcConstants;
import com.alibaba.druid.wall.Violation;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallProvider;
@@ -65,6 +66,11 @@ public class SQLServerWallVisitor extends SQLServerASTVisitorAdapter implements
this.config = provider.getConfig();
this.provider = provider;
}
@Override
public String getDbType() {
return JdbcConstants.SQL_SERVER;
}
@Override
public boolean isSqlModified() {
@@ -47,6 +47,7 @@ import com.alibaba.druid.sql.ast.expr.SQLNumberExpr;
import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
import com.alibaba.druid.sql.ast.expr.SQLUnaryExpr;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLCallStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateIndexStatement;
@@ -612,8 +613,10 @@ public class WallVisitorUtils {
boolean allFalse = true;
for (int i = groupList.size() - 1; i >= 0; --i) {
Object result = getValue(visitor, groupList.get(i));
if (Boolean.TRUE == result) {
SQLExpr item = groupList.get(i);
Object result = getValue(visitor, item);
Boolean booleanVal = SQLEvalVisitorUtils.castToBoolean(result);
if (Boolean.TRUE == booleanVal) {
final WallConditionContext wallContext = WallVisitorUtils.getWallConditionContext();
if (wallContext != null && i != 0) {
wallContext.setPartAlwayTrue(true);
@@ -621,7 +624,7 @@ public class WallVisitorUtils {
return true;
}
if (Boolean.FALSE != result) {
if (Boolean.FALSE != booleanVal) {
allFalse = false;
}
}
@@ -973,63 +976,14 @@ public class WallVisitorUtils {
}
}
if (x instanceof SQLMethodInvokeExpr) {
return getValue(visitor, (SQLMethodInvokeExpr) x);
if (x instanceof SQLMethodInvokeExpr || x instanceof SQLUnaryExpr) {
String dbType = null;
if (visitor != null) {
dbType = visitor.getDbType();
}
return SQLEvalVisitorUtils.eval(dbType, x, Collections.emptyList(), false);
}
return null;
}
public static Object getValue(WallVisitor visitor, SQLMethodInvokeExpr x) {
String methodName = x.getMethodName();
if ("len".equalsIgnoreCase(methodName) || "length".equalsIgnoreCase(methodName)) {
Object firstValue = null;
if (x.getParameters().size() > 0) {
firstValue = (getValue(visitor, x.getParameters().get(0)));
}
if (firstValue instanceof String) {
return ((String) firstValue).length();
}
}
if ("if".equalsIgnoreCase(methodName) && x.getParameters().size() == 3) {
SQLExpr first = x.getParameters().get(0);
Object firstResult = getValue(visitor, first);
if (Boolean.TRUE == firstResult) {
return getValue(visitor, x.getParameters().get(1));
}
if (Boolean.FALSE == firstResult) {
getValue(visitor, x.getParameters().get(2));
}
}
if ("chr".equalsIgnoreCase(methodName) && x.getParameters().size() == 1) {
SQLExpr first = x.getParameters().get(0);
Object firstResult = getValue(visitor, first);
if (firstResult instanceof Number) {
int intValue = ((Number) firstResult).intValue();
char ch = (char) intValue;
return "" + ch;
}
}
if ("concat".equalsIgnoreCase(methodName)) {
StringBuffer buf = new StringBuffer();
for (SQLExpr expr : x.getParameters()) {
Object value = getValue(visitor, expr);
if (value == null) {
return null;
}
buf.append(value.toString());
}
return buf.toString();
}
return null;
}