bug fixed for schema stat

This commit is contained in:
温少
2012-03-18 12:24:40 +08:00
13 changed files with 105 additions and 83 deletions
@@ -127,7 +127,7 @@ public class MappingVisitorUtils {
}
public static void setDataSource(MappingEngine engine, SQLDeleteStatement stmt) {
if (stmt.getTableSource() == null) {
if (stmt.getExprTableSource() == null) {
Entity entity = engine.getFirstEntity();
stmt.setTableSource(new SQLIdentifierExpr(entity.getName()));
}
@@ -23,34 +23,38 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLDeleteStatement extends SQLStatementImpl {
private static final long serialVersionUID = 1L;
protected SQLExprTableSource tableSource;
protected SQLExpr where;
private static final long serialVersionUID = 1L;
protected SQLTableSource tableSource;
protected SQLExpr where;
public SQLDeleteStatement(){
}
public SQLExprTableSource getTableSource() {
public SQLTableSource getTableSource() {
return tableSource;
}
public SQLExprTableSource getExprTableSource() {
return (SQLExprTableSource) getTableSource();
}
public void setTableSource(SQLExpr expr) {
this.setTableSource(new SQLExprTableSource(expr));
}
public void setTableSource(SQLExprTableSource tableSource) {
public void setTableSource(SQLTableSource tableSource) {
this.tableSource = tableSource;
}
public SQLName getTableName() {
return (SQLName) tableSource.getExpr();
return (SQLName) getExprTableSource().getExpr();
}
public void setTableName(SQLName tableName) {
this.setTableSource(new SQLExprTableSource(tableName));
}
public void setTableName(String name) {
setTableName(new SQLIdentifierExpr(name));
}
@@ -15,13 +15,8 @@
*/
package com.alibaba.druid.sql.dialect.mysql.ast.statement;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLOrderBy;
import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock.Limit;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
@@ -30,17 +25,16 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class MySqlDeleteStatement extends SQLDeleteStatement {
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 1L;
private boolean lowPriority = false;
private boolean quick = false;
private boolean ignore = false;
private boolean lowPriority = false;
private boolean quick = false;
private boolean ignore = false;
private SQLTableSource from;
private SQLTableSource using;
private SQLOrderBy orderBy;
private Limit limit;
private final List<SQLExprTableSource> tableSources = new ArrayList<SQLExprTableSource>();
private SQLTableSource from;
private SQLTableSource using;
private SQLOrderBy orderBy;
private Limit limit;
public boolean isLowPriority() {
return lowPriority;
@@ -78,25 +72,6 @@ public class MySqlDeleteStatement extends SQLDeleteStatement {
this.using = using;
}
public SQLName getTableName() {
if (tableSources.size() == 0) {
return null;
}
return (SQLName) tableSources.get(0).getExpr();
}
public void setTableSource(SQLExprTableSource tableSource) {
if (tableSources.size() == 0) {
tableSources.add(tableSource);
} else {
tableSources.set(0, tableSource);
}
}
public List<SQLExprTableSource> getTableSources() {
return tableSources;
}
public void setFrom(SQLTableSource from) {
this.from = from;
}
@@ -132,7 +107,7 @@ public class MySqlDeleteStatement extends SQLDeleteStatement {
protected void accept0(MySqlASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, getTableSources());
acceptChild(visitor, getTableSource());
acceptChild(visitor, getWhere());
acceptChild(visitor, getFrom());
acceptChild(visitor, getUsing());
@@ -21,6 +21,7 @@ import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr;
import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause;
import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOutFileExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectGroupBy;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock;
@@ -262,4 +263,13 @@ public class MySqlSelectParser extends SQLSelectParser {
protected MySqlExprParser createExprParser() {
return new MySqlExprParser(lexer);
}
protected SQLTableSource parseTableSourceRest(SQLTableSource tableSource) throws ParserException {
if (identifierEquals("USING")) {
return tableSource;
}
return super.parseTableSourceRest(tableSource);
}
}
@@ -27,7 +27,6 @@ import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr;
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
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.SQLSelectStatement;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
@@ -58,6 +57,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlStartTransactionSt
import com.alibaba.druid.sql.parser.Lexer;
import com.alibaba.druid.sql.parser.ParserException;
import com.alibaba.druid.sql.parser.SQLExprParser;
import com.alibaba.druid.sql.parser.SQLSelectParser;
import com.alibaba.druid.sql.parser.SQLStatementParser;
import com.alibaba.druid.sql.parser.Token;
@@ -109,17 +109,7 @@ public class MySqlStatementParser extends SQLStatementParser {
}
if (lexer.token() == Token.IDENTIFIER) {
for (;;) {
SQLName name = exprParser.name();
deleteStatement.getTableSources().add(new SQLExprTableSource(name));
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
deleteStatement.setTableSource(createSQLSelectParser().parseTableSource());
if (lexer.token() == Token.FROM) {
lexer.nextToken();
@@ -129,17 +119,7 @@ public class MySqlStatementParser extends SQLStatementParser {
} else {
if (lexer.token() == Token.FROM) {
lexer.nextToken();
}
for (;;) {
SQLName name = exprParser.name();
deleteStatement.getTableSources().add(new SQLExprTableSource(name));
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
deleteStatement.setTableSource(createSQLSelectParser().parseTableSource());
}
}
@@ -1039,4 +1019,8 @@ public class MySqlStatementParser extends SQLStatementParser {
}
return stmt;
}
public SQLSelectParser createSQLSelectParser() {
return new MySqlSelectParser(this.lexer);
}
}
@@ -623,9 +623,9 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
if (x.getFrom() == null) {
print("FROM ");
printAndAccept(x.getTableSources(), ", ");
x.getTableSource().accept(this);
} else {
printAndAccept(x.getTableSources(), ", ");
x.getTableSource().accept(this);
println();
print("FROM ");
x.getFrom().accept(this);
@@ -2,7 +2,6 @@ package com.alibaba.druid.sql.dialect.mysql.visitor;
import java.util.Map;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement;
@@ -66,17 +65,20 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS
setAliasMap();
if (x.getTableSources().size() == 1) {
SQLName tableName = (SQLName) x.getTableSources().get(0).getExpr();
if (x.getTableSource() instanceof SQLExprTableSource) {
SQLName tableName = (SQLName) ((SQLExprTableSource) x.getTableSource()).getExpr();
String ident = tableName.toString();
setCurrentTable(x, ident);
}
for (SQLExprTableSource tableSource : x.getTableSources()) {
SQLExpr tableName = tableSource.getExpr();
String ident = tableName.toString();
TableStat stat = getTableStat(ident);
TableStat stat = this.getTableStat(ident);
stat.incrementDeleteCount();
} else {
MySqlSchemaStatVisitor tableSourceVisitor = new MySqlSchemaStatVisitor();
tableSourceVisitor.accept(x.getTableSource());
for (TableStat.Name name : tableSourceVisitor.getTables().keySet()) {
TableStat stat = this.getTableStat(name.getName());
stat.incrementDeleteCount();
}
}
accept(x.getWhere());
@@ -483,6 +485,6 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS
@Override
public void endVisit(MySqlOutFileExpr x) {
}
}
@@ -232,7 +232,6 @@ public class PGSchemaStatVisitor extends SchemaStatVisitor implements PGASTVisit
@Override
public boolean visit(PGSelectQueryBlock x) {
this.visit((SQLSelectQueryBlock) x);
return false;
return this.visit((SQLSelectQueryBlock) x);
}
}
@@ -235,7 +235,7 @@ public class SQLSelectParser extends SQLParser {
tableReference.setExpr(expr());
}
private SQLTableSource parseTableSourceRest(SQLTableSource tableSource) throws ParserException {
protected SQLTableSource parseTableSourceRest(SQLTableSource tableSource) throws ParserException {
if ((tableSource.getAlias() == null) || (tableSource.getAlias().length() == 0)) {
if (lexer.token() != Token.LEFT && lexer.token() != Token.RIGHT && lexer.token() != Token.FULL) {
tableSource.setAlias(as());
@@ -472,9 +472,16 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
x.getFrom().accept(this);
return false;
}
if (x.getInto() != null) {
SQLName into = (SQLName) x.getInto().getExpr();
String ident = into.toString();
TableStat stat = getTableStat(ident);
stat.incrementInsertCount();
}
String originalTable = getCurrentTable();
if (x.getFrom() instanceof SQLExprTableSource) {
SQLExprTableSource tableSource = (SQLExprTableSource) x.getFrom();
if (tableSource.getExpr() instanceof SQLName) {
@@ -488,7 +495,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
x.putAttribute("_old_local_", originalTable);
}
}
if (x.getFrom() != null) {
x.getFrom().accept(this); // 提前执行,获得aliasMap
String table = (String) x.getFrom().getAttribute(ATTR_TABLE);
@@ -85,6 +85,8 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi
@Override
public boolean visit(MySqlDeleteStatement x) {
WallVisitorUtils.checkReadOnly(this, x.getFrom());
return visit((SQLDeleteStatement) x);
}
@@ -112,7 +112,7 @@ public class WallVisitorUtils {
}
public static void checkDelete(WallVisitor visitor, SQLDeleteStatement x) {
checkReadOnly(visitor, x.getTableSource());
checkReadOnly(visitor, x.getExprTableSource());
if (!visitor.getConfig().isDeleteAllow()) {
addViolation(visitor, x);
@@ -0,0 +1,39 @@
package com.alibaba.druid.bvt.filter.wall;
import junit.framework.TestCase;
import org.junit.Assert;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallUtils;
/**
* 这个场景,检测可疑的Having条件
* @author wenshao
*
*/
public class WallReadOnlyTest extends TestCase {
private WallConfig config = new WallConfig();
protected void setUp() throws Exception {
config.getReadOnlyTables().add("members");
}
private String sql = "SELECT F1, F2 members";
private String insert_sql = "INSERT INTO members (FID, FNAME) VALUES (?, ?)";
private String update_sql = "UPDATE members SET FNAME = ? WHERe FID = ?";
private String delete_sql = "DELETE members WHERE FID = ?";
public void testMySql() throws Exception {
Assert.assertTrue(WallUtils.isValidateMySql(sql, config));
Assert.assertFalse(WallUtils.isValidateMySql(insert_sql, config));
Assert.assertFalse(WallUtils.isValidateMySql(update_sql, config));
Assert.assertFalse(WallUtils.isValidateMySql(delete_sql, config));
}
public void testORACLE() throws Exception {
Assert.assertTrue(WallUtils.isValidateOracle(sql, config));
Assert.assertFalse(WallUtils.isValidateOracle(insert_sql, config));
Assert.assertFalse(WallUtils.isValidateOracle(update_sql, config));
Assert.assertFalse(WallUtils.isValidateOracle(delete_sql, config));
}
}