Merge remote-tracking branch 'upstream/master'

This commit is contained in:
wenshao
2013-06-06 12:28:45 +08:00
28 changed files with 676 additions and 169 deletions
@@ -34,18 +34,14 @@ public class SQLBetweenExpr extends SQLExprImpl implements Serializable {
}
public SQLBetweenExpr(SQLExpr testExpr, SQLExpr beginExpr, SQLExpr endExpr){
this.testExpr = testExpr;
this.beginExpr = beginExpr;
this.endExpr = endExpr;
setTestExpr(testExpr);
setBeginExpr(beginExpr);
setEndExpr(endExpr);
}
public SQLBetweenExpr(SQLExpr testExpr, boolean not, SQLExpr beginExpr, SQLExpr endExpr){
this.testExpr = testExpr;
this(testExpr, beginExpr, endExpr);
this.not = not;
this.beginExpr = beginExpr;
this.endExpr = endExpr;
}
public void output(StringBuffer buf) {
@@ -74,6 +70,9 @@ public class SQLBetweenExpr extends SQLExprImpl implements Serializable {
}
public void setTestExpr(SQLExpr testExpr) {
if (testExpr != null) {
testExpr.setParent(this);
}
this.testExpr = testExpr;
}
@@ -90,6 +89,9 @@ public class SQLBetweenExpr extends SQLExprImpl implements Serializable {
}
public void setBeginExpr(SQLExpr beginExpr) {
if (beginExpr != null) {
beginExpr.setParent(this);
}
this.beginExpr = beginExpr;
}
@@ -98,6 +100,9 @@ public class SQLBetweenExpr extends SQLExprImpl implements Serializable {
}
public void setEndExpr(SQLExpr endExpr) {
if (endExpr != null) {
endExpr.setParent(this);
}
this.endExpr = endExpr;
}
@@ -42,7 +42,7 @@ public class SQLMethodInvokeExpr extends SQLExprImpl implements Serializable {
public SQLMethodInvokeExpr(String methodName, SQLExpr owner){
this.methodName = methodName;
this.owner = owner;
setOwner(owner);
}
public String getMethodName() {
@@ -58,6 +58,9 @@ public class SQLMethodInvokeExpr extends SQLExprImpl implements Serializable {
}
public void setOwner(SQLExpr owner) {
if (owner != null) {
owner.setParent(this);
}
this.owner = owner;
}
@@ -31,8 +31,7 @@ public class SQLQueryExpr extends SQLExprImpl implements Serializable {
}
public SQLQueryExpr(SQLSelect select){
this.subQuery = select;
setSubQuery(select);
}
public SQLSelect getSubQuery() {
@@ -40,6 +39,9 @@ public class SQLQueryExpr extends SQLExprImpl implements Serializable {
}
public void setSubQuery(SQLSelect subQuery) {
if (subQuery != null) {
subQuery.setParent(this);
}
this.subQuery = subQuery;
}
@@ -430,7 +430,7 @@ public class MySqlExprParser extends SQLExprParser {
SQLMethodInvokeExpr methodInvokeExpr = new SQLMethodInvokeExpr(ident);
if (lexer.token() != Token.RPAREN) {
exprList(methodInvokeExpr.getParameters());
exprList(methodInvokeExpr.getParameters(), methodInvokeExpr);
}
if (identifierEquals("USING")) {
@@ -454,11 +454,11 @@ public class MySqlExprParser extends SQLExprParser {
accept(Token.IN);
SQLExpr str = this.expr();
accept(Token.RPAREN);
SQLMethodInvokeExpr locate = new SQLMethodInvokeExpr("LOCATE");
locate.getParameters().add(subStr);
locate.getParameters().add(str);
expr = locate;
return primaryRest(expr);
}
@@ -536,7 +536,7 @@ public class MySqlExprParser extends SQLExprParser {
SQLExpr expr = this.expr();
((MySqlSQLColumnDefinition) column).setOnUpdate(expr);
}
if (identifierEquals("AUTO_INCREMENT")) {
lexer.nextToken();
if (column instanceof MySqlSQLColumnDefinition) {
@@ -552,13 +552,13 @@ public class MySqlExprParser extends SQLExprParser {
if (identifierEquals("PARTITION")) {
throw new ParserException("syntax error " + lexer.token() + " " + lexer.stringVal());
}
if (identifierEquals("COMMENT")) {
lexer.nextToken();
column.setComment(lexer.stringVal());
accept(Token.LITERAL_CHARS);
}
if (identifierEquals("STORAGE")) {
lexer.nextToken();
SQLExpr expr = expr();
@@ -566,15 +566,15 @@ public class MySqlExprParser extends SQLExprParser {
((MySqlSQLColumnDefinition) column).setStorage(expr);
}
}
super.parseColumnRest(column);
return column;
}
protected SQLDataType parseDataTypeRest(SQLDataType dataType) {
super.parseDataTypeRest(dataType);
if (identifierEquals("UNSIGNED")) {
lexer.nextToken();
dataType.getAttributes().put("unsigned", true);
@@ -718,9 +718,9 @@ public class MySqlExprParser extends SQLExprParser {
public MySqlUnique parseUnique() {
accept(Token.UNIQUE);
if (lexer.token() == Token.KEY) {
lexer.nextToken();
lexer.nextToken();
}
MySqlUnique unique = new MySqlUnique();
@@ -730,12 +730,12 @@ public class MySqlExprParser extends SQLExprParser {
unique.setIndexType(lexer.stringVal());
lexer.nextToken();
}
if (lexer.token() != Token.LPAREN) {
SQLName name = name();
unique.setName(name);
SQLName name = name();
unique.setName(name);
}
accept(Token.LPAREN);
for (;;) {
unique.getColumns().add(this.expr());
@@ -749,21 +749,21 @@ public class MySqlExprParser extends SQLExprParser {
return unique;
}
public MySqlForeignKey parseForeignKey() {
accept(Token.FOREIGN);
accept(Token.KEY);
MySqlForeignKey fk = new MySqlForeignKey();
accept(Token.LPAREN);
this.names(fk.getReferencingColumns());
accept(Token.RPAREN);
accept(Token.REFERENCES);
fk.setReferencedTableName(this.name());
accept(Token.LPAREN);
this.names(fk.getReferencedColumns());
accept(Token.RPAREN);
@@ -578,7 +578,7 @@ public class SQLExprParser extends SQLParser {
methodInvokeExpr.getParameters().add(new SQLIdentifierExpr("+"));
lexer.nextToken();
} else {
exprList(methodInvokeExpr.getParameters());
exprList(methodInvokeExpr.getParameters(), methodInvokeExpr);
}
accept(Token.RPAREN);
}
@@ -612,7 +612,7 @@ public class SQLExprParser extends SQLParser {
exprCol.add(name());
}
}
public final void exprList(Collection<SQLExpr> exprCol) {
exprList(exprCol, null);
}
@@ -1264,7 +1264,7 @@ public class SQLExprParser extends SQLParser {
column.getConstaints().add(new SQLColumnPrimaryKey());
return parseColumnRest(column);
}
if (lexer.token == Token.CHECK) {
lexer.nextToken();
SQLExpr expr = this.expr();
@@ -796,7 +796,7 @@ public class SQLEvalVisitorUtils {
if (wallConditionContext != null) {
wallConditionContext.setConstArithmetic(true);
}
if (leftValue == null || rightValue == null) {
return false;
}
@@ -1290,7 +1290,7 @@ public class SQLEvalVisitorUtils {
}
if (a instanceof String || b instanceof String) {
return ((String) a).compareTo((String) b) < 0;
return (castToString(a)).compareTo(castToString(b)) < 0;
}
if (a instanceof BigDecimal || b instanceof BigDecimal) {
@@ -163,11 +163,16 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi
@Override
public boolean visit(SQLInsertStatement x) {
WallVisitorUtils.initWallTopStatementContext();
WallVisitorUtils.checkInsert(this, x);
return true;
}
@Override
public void endVisit(SQLInsertStatement x) {
WallVisitorUtils.clearWallTopStatementContext();
}
@Override
public boolean visit(SQLSelectStatement x) {
if (!config.isSelelctAllow()) {
@@ -124,6 +124,11 @@ public class SQLServerWallVisitor extends SQLServerASTVisitorAdapter implements
@Override
public boolean visit(SQLMethodInvokeExpr x) {
if (x.getParent() instanceof SQLExprTableSource) {
WallVisitorUtils.checkFunctionInTableSource(this, x);
}
WallVisitorUtils.checkFunction(this, x);
return true;
@@ -188,10 +193,16 @@ public class SQLServerWallVisitor extends SQLServerASTVisitorAdapter implements
@Override
public boolean visit(SQLInsertStatement x) {
WallVisitorUtils.initWallTopStatementContext();
WallVisitorUtils.checkInsert(this, x);
return true;
}
@Override
public void endVisit(SQLInsertStatement x) {
WallVisitorUtils.clearWallTopStatementContext();
}
@Override
public boolean visit(SQLDeleteStatement x) {
WallVisitorUtils.checkDelete(this, x);
@@ -37,6 +37,7 @@ import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
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.SQLInSubQueryExpr;
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.ast.expr.SQLNCharExpr;
@@ -703,6 +704,17 @@ public class WallVisitorUtils {
return false;
}
private static boolean hasWhere(SQLSelectQuery selectQuery) {
if (selectQuery instanceof SQLSelectQueryBlock) {
return ((SQLSelectQueryBlock) selectQuery).getWhere() != null;
} else if (selectQuery instanceof SQLUnionQuery) {
SQLUnionQuery union = (SQLUnionQuery) selectQuery;
return hasWhere(union.getLeft()) || hasWhere(union.getRight());
}
return false;
}
public static boolean isWhereOrHaving(SQLObject x) {
if (x == null) {
return false;
@@ -715,12 +727,17 @@ public class WallVisitorUtils {
return false;
}
if (parent instanceof SQLUnionQuery) {
SQLUnionQuery union = (SQLUnionQuery) parent;
if (union.getRight() == x && hasWhere(union.getLeft())) {
return true;
}
}
if (parent instanceof SQLSelectQueryBlock) {
SQLSelectQueryBlock query = (SQLSelectQueryBlock) parent;
if (query.getWhere() == x) {
return true;
} else {
return false;
}
}
@@ -1037,6 +1054,25 @@ public class WallVisitorUtils {
return false;
}
public static void checkFunctionInTableSource(WallVisitor visitor, SQLMethodInvokeExpr x) {
final WallTopStatementContext topStatementContext = wallTopStatementContextLocal.get();
if (topStatementContext != null && (topStatementContext.fromSysSchema || topStatementContext.fromSysTable)) {
return;
}
checkSchema(visitor, x.getOwner());
String methodName = x.getMethodName();
if (!visitor.getProvider().checkDenyTable(methodName)) {
if (isTopUpdateStatement(x) || isFirstSelectTableSource(x)) {
if (topStatementContext != null) {
topStatementContext.setFromSysSchema(Boolean.TRUE);
clearViolation(visitor);
}
}
}
}
public static void checkFunction(WallVisitor visitor, SQLMethodInvokeExpr x) {
final WallTopStatementContext topStatementContext = wallTopStatementContextLocal.get();
@@ -1113,6 +1149,14 @@ public class WallVisitorUtils {
}
public static boolean isTopNoneFromSelect(WallVisitor visitor, SQLObject x) {
for (;;) {
if (x.getParent() instanceof SQLExpr) {
x = x.getParent();
} else {
break;
}
}
if (!(x.getParent() instanceof SQLSelectItem)) {
return false;
}
@@ -1152,10 +1196,8 @@ public class WallVisitorUtils {
String owner = ((SQLName) x).getSimleName();
owner = WallVisitorUtils.form(owner);
if (!visitor.getProvider().checkDenySchema(owner)) {
boolean topStatement = isTopSelectStatement(x) || isTopUpdateStatement(x);
boolean isWhereOrHaving = isWhereOrHaving(x);
if (!topStatement && isWhereOrHaving) {
if (!isTopUpdateStatement(x) && !isFirstSelectTableSource(x)) {
SQLObject parent = x.getParent();
while (parent != null && !(parent instanceof SQLStatement)) {
parent = parent.getParent();
@@ -1194,6 +1236,7 @@ public class WallVisitorUtils {
} else {
if (topStatementContext != null) {
topStatementContext.setFromSysSchema(Boolean.TRUE);
clearViolation(visitor);
}
}
return true;
@@ -1213,55 +1256,127 @@ public class WallVisitorUtils {
return true;
}
private static boolean isTopSelectStatement(SQLObject x) {
private static boolean isFirstSelectTableSource(SQLObject x) {
boolean topSelectStatement = false;
for (;;) {
if (x instanceof SQLExpr) {
x = x.getParent();
} else {
break;
}
}
if (!(x instanceof SQLExprTableSource)) {
return false;
}
SQLSelectQueryBlock queryBlock = null;
SQLObject parent = x.getParent();
while (parent != null) {
if (parent instanceof SQLSelectStatement || parent instanceof MySqlShowStatement) {
parent = parent.getParent();
if (parent == null) {
topSelectStatement = true;
if (parent instanceof SQLJoinTableSource) {
SQLJoinTableSource join = (SQLJoinTableSource) parent;
if (join.getRight() == x && hasTableSource(join.getLeft())) {
return false;
}
break;
}
if (parent instanceof SQLUnionQuery) {
SQLUnionQuery union = (SQLUnionQuery) parent;
if (union.getRight() == x) {
break;
}
if (parent instanceof SQLSelectQueryBlock) {
queryBlock = (SQLSelectQueryBlock) parent;
break;
}
x = parent;
parent = x.getParent();
}
return topSelectStatement;
if (queryBlock == null) {
return false;
}
boolean isQueryExpr = false;
do {
x = parent;
parent = parent.getParent();
if (parent instanceof SQLUnionQuery) {
SQLUnionQuery union = (SQLUnionQuery) parent;
if (union.getRight() == x && hasTableSource(union.getLeft())) {
return false;
}
} else if (parent instanceof SQLQueryExpr || parent instanceof SQLInSubQueryExpr) {
isQueryExpr = true;
} else if (isQueryExpr && parent instanceof SQLSelectQueryBlock) {
if (hasTableSource((SQLSelectQueryBlock) parent)) {
return false;
}
}
} while (parent != null);
return true;
}
private static boolean hasTableSource(SQLSelectQuery x) {
if (x instanceof SQLUnionQuery) {
SQLUnionQuery union = (SQLUnionQuery) x;
return hasTableSource(union.getLeft()) || hasTableSource(union.getRight());
} else if (x instanceof SQLSelectQueryBlock) {
return hasTableSource(((SQLSelectQueryBlock) x).getFrom());
}
return false;
}
private static boolean hasTableSource(SQLTableSource x) {
if (x == null) {
return false;
}
if (x instanceof SQLExprTableSource) {
SQLExpr fromExpr = ((SQLExprTableSource) x).getExpr();
if (fromExpr instanceof SQLName) {
String name = fromExpr.toString();
name = form(name);
if (name.equalsIgnoreCase("DUAL")) {
return false;
}
}
return true;
} else if (x instanceof SQLJoinTableSource) {
SQLJoinTableSource join = (SQLJoinTableSource) x;
return hasTableSource(join.getLeft()) || hasTableSource(join.getRight());
} else if (x instanceof SQLSubqueryTableSource) {
return hasTableSource(((SQLSubqueryTableSource) x).getSelect().getQuery());
}
return false;
}
private static boolean isTopUpdateStatement(SQLObject x) {
boolean topUpdateStatement = false;
while (x != null) {
for (;;) {
if (x instanceof SQLExpr) {
x = x.getParent();
} else {
break;
}
}
if (x instanceof SQLExprTableSource) {
x = x.getParent();
if (x instanceof SQLUpdateStatement) {
x = x.getParent();
if (x == null) {
topUpdateStatement = true;
return true;
}
break;
}
x = x.getParent();
}
return topUpdateStatement;
return false;
}
public static boolean check(WallVisitor visitor, SQLExprTableSource x) {
final WallTopStatementContext topStatementContext = wallTopStatementContextLocal.get();
if (topStatementContext != null && (topStatementContext.fromSysSchema || topStatementContext.fromSysTable)) {
return true;
}
SQLExpr expr = x.getExpr();
if (expr instanceof SQLPropertyExpr) {
@@ -1305,18 +1420,21 @@ public class WallVisitorUtils {
}
}
if (visitor.isDenyTable(tableName)) {
boolean topStatement = isTopSelectStatement(x) || isTopUpdateStatement(x);
boolean isWhereOrHaving = isWhereOrHaving(x);
if (topStatementContext != null && (topStatementContext.fromSysSchema || topStatementContext.fromSysTable)) {
return true;
}
if (topStatement || !isWhereOrHaving) {
if (visitor.isDenyTable(tableName)) {
if (isTopUpdateStatement(x) || isFirstSelectTableSource(x)) {
if (topStatementContext != null) {
topStatementContext.setFromSysTable(Boolean.TRUE);
clearViolation(visitor);
}
return false;
}
boolean isTopNoneFrom = isTopSelectStatement(x);
boolean isTopNoneFrom = isTopNoneFromSelect(visitor, x);
if (isTopNoneFrom) {
return false;
}
@@ -1333,6 +1451,10 @@ public class WallVisitorUtils {
visitor.addViolation(new IllegalSQLObjectViolation(errorCode, message, visitor.toSQL(x)));
}
private static void clearViolation(WallVisitor visitor) {
visitor.getViolations().clear();
}
public static void checkUnion(WallVisitor visitor, SQLUnionQuery x) {
if (x.getOperator() == SQLUnionOperator.MINUS && !visitor.getConfig().isMinusAllow()) {
addViolation(visitor, ErrorCode.INTERSET_NOT_ALLOW, "minus not allow", x);