sql parser schema stat

This commit is contained in:
温少
2012-05-24 13:54:44 +08:00
13 changed files with 302 additions and 16 deletions
@@ -4,9 +4,15 @@ import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.dialect.hive.ast.stmt.HiveCreateTableStatement;
import com.alibaba.druid.sql.dialect.hive.ast.stmt.HiveShowTablesStatement;
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
import com.alibaba.druid.util.JdbcUtils;
public class HiveSchemaStatVisitor extends SchemaStatVisitor implements HiveASTVisitor {
@Override
public String getDbType() {
return JdbcUtils.HIVE;
}
@Override
public void endVisit(HiveCreateTableStatement x) {
@@ -113,6 +113,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement;
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
import com.alibaba.druid.stat.TableStat;
import com.alibaba.druid.stat.TableStat.Mode;
import com.alibaba.druid.util.JdbcUtils;
public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlASTVisitor {
@@ -122,6 +123,11 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS
return true;
}
@Override
public String getDbType() {
return JdbcUtils.MYSQL;
}
// DUAL
public boolean visit(MySqlDeleteStatement x) {
@@ -0,0 +1,64 @@
package com.alibaba.druid.sql.dialect.oracle.visitor;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
import com.alibaba.druid.sql.visitor.SQLEvalVisitorUtils;
public class OracleEvalVisitor extends OracleASTVisitorAdapter implements SQLEvalVisitor {
private List<Object> parameters = new ArrayList<Object>();
private int variantIndex = -1;
private boolean markVariantIndex = true;
public OracleEvalVisitor(){
this(new ArrayList<Object>(1));
}
public OracleEvalVisitor(List<Object> parameters){
this.parameters = parameters;
}
public List<Object> getParameters() {
return parameters;
}
public void setParameters(List<Object> parameters) {
this.parameters = parameters;
}
public boolean visit(SQLCharExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
public int incrementAndGetVariantIndex() {
return ++variantIndex;
}
public int getVariantIndex() {
return variantIndex;
}
public boolean visit(SQLVariantRefExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
public boolean visit(SQLBinaryOpExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
public boolean isMarkVariantIndex() {
return markVariantIndex;
}
public void setMarkVariantIndex(boolean markVariantIndex) {
this.markVariantIndex = markVariantIndex;
}
}
@@ -1,5 +1,7 @@
package com.alibaba.druid.sql.dialect.oracle.visitor;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.alibaba.druid.sql.ast.SQLExpr;
@@ -140,15 +142,26 @@ import com.alibaba.druid.stat.TableStat;
import com.alibaba.druid.stat.TableStat.Column;
import com.alibaba.druid.stat.TableStat.Mode;
import com.alibaba.druid.stat.TableStat.Relationship;
import com.alibaba.druid.util.JdbcUtils;
public class OracleSchemaStatVisitor extends SchemaStatVisitor implements OracleASTVisitor {
public OracleSchemaStatVisitor(){
this (new ArrayList<Object>());
}
public OracleSchemaStatVisitor(List<Object> parameters) {
super (parameters);
this.variants.put("DUAL", null);
this.variants.put("NOTFOUND", null);
this.variants.put("TRUE", null);
this.variants.put("FALSE", null);
}
@Override
public String getDbType() {
return JdbcUtils.ORACLE;
}
protected Column getColumn(SQLExpr expr) {
if (expr instanceof OracleOuterExpr) {
@@ -0,0 +1,64 @@
package com.alibaba.druid.sql.dialect.postgresql.visitor;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
import com.alibaba.druid.sql.visitor.SQLEvalVisitorUtils;
public class PGEvalVisitor extends PGASTVisitorAdapter implements SQLEvalVisitor {
private List<Object> parameters = new ArrayList<Object>();
private int variantIndex = -1;
private boolean markVariantIndex = true;
public PGEvalVisitor(){
this(new ArrayList<Object>(1));
}
public PGEvalVisitor(List<Object> parameters){
this.parameters = parameters;
}
public List<Object> getParameters() {
return parameters;
}
public void setParameters(List<Object> parameters) {
this.parameters = parameters;
}
public boolean visit(SQLCharExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
public int incrementAndGetVariantIndex() {
return ++variantIndex;
}
public int getVariantIndex() {
return variantIndex;
}
public boolean visit(SQLVariantRefExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
public boolean visit(SQLBinaryOpExpr x) {
return SQLEvalVisitorUtils.visit(this, x);
}
public boolean isMarkVariantIndex() {
return markVariantIndex;
}
public void setMarkVariantIndex(boolean markVariantIndex) {
this.markVariantIndex = markVariantIndex;
}
}
@@ -23,9 +23,15 @@ import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGUpdateStatement;
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
import com.alibaba.druid.stat.TableStat;
import com.alibaba.druid.stat.TableStat.Mode;
import com.alibaba.druid.util.JdbcUtils;
public class PGSchemaStatVisitor extends SchemaStatVisitor implements PGASTVisitor {
@Override
public String getDbType() {
return JdbcUtils.POSTGRESQL;
}
@Override
public void endVisit(WindowClause x) {
@@ -5,10 +5,16 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock;
import com.alibaba.druid.sql.dialect.sqlserver.ast.Top;
import com.alibaba.druid.sql.dialect.sqlserver.ast.expr.SQLServerObjectReferenceExpr;
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
import com.alibaba.druid.util.JdbcUtils;
public class SQLServerSchemaStatVisitor extends SchemaStatVisitor implements SQLServerASTVisitor {
@Override
public String getDbType() {
return JdbcUtils.SQL_SERVER;
}
@Override
public boolean visit(SQLServerSelectQueryBlock x) {
return visit((SQLSelectQueryBlock) x);
@@ -22,6 +22,8 @@ import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
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;
import com.alibaba.druid.util.JdbcUtils;
public class SQLEvalVisitorUtils {
@@ -47,15 +49,19 @@ public class SQLEvalVisitorUtils {
return sqlObject.getAttributes().get(EVAL_VALUE);
}
public static Object eval(String dbType, SQLObject sqlObject, List<Object> parameters) {
return eval(dbType, sqlObject, parameters, true);
}
public static Object eval(String dbType, SQLObject sqlObject, List<Object> parameters, boolean throwError) {
SQLEvalVisitor visitor = createEvalVisitor(dbType);
visitor.setParameters(parameters);
sqlObject.accept(visitor);
Object value = getValue(sqlObject);
if (value == null) {
if (!sqlObject.getAttributes().containsKey(EVAL_VALUE)) {
if (throwError && !sqlObject.getAttributes().containsKey(EVAL_VALUE)) {
throw new DruidRuntimeException("eval error : " + SQLUtils.toSQLString(sqlObject, dbType));
}
}
@@ -67,6 +73,14 @@ public class SQLEvalVisitorUtils {
if (JdbcUtils.MYSQL.equals(dbType)) {
return new MySqlEvalVisitorImpl();
}
if (JdbcUtils.ORACLE.equals(dbType)) {
return new OracleEvalVisitor();
}
if (JdbcUtils.POSTGRESQL.equals(dbType)) {
return new PGEvalVisitor();
}
return new SQLEvalVisitorImpl();
}
@@ -1,5 +1,6 @@
package com.alibaba.druid.sql.visitor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
@@ -52,7 +53,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
protected final HashMap<TableStat.Name, TableStat> tableStats = new LinkedHashMap<TableStat.Name, TableStat>();
protected final Set<Column> columns = new LinkedHashSet<Column>();
protected final Set<Condition> conditions = new LinkedHashSet<Condition>();
protected final List<Condition> conditions = new ArrayList<Condition>();
protected final Set<Relationship> relationships = new LinkedHashSet<Relationship>();
protected final Set<Column> orderByColumns = new LinkedHashSet<Column>();
protected final Set<Column> groupByColumns = new LinkedHashSet<Column>();
@@ -68,8 +69,26 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
public final static String ATTR_TABLE = "_table_";
public final static String ATTR_COLUMN = "_column_";
private List<Object> parameters;
private Mode mode;
public SchemaStatVisitor(){
this(new ArrayList<Object>());
}
public SchemaStatVisitor(List<Object> parameters){
this.parameters = parameters;
}
public List<Object> getParameters() {
return parameters;
}
public void setParameters(List<Object> parameters) {
this.parameters = parameters;
}
public TableStat getTableStat(String ident) {
return getTableStat(ident, null);
}
@@ -247,7 +266,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
return groupByColumns;
}
public Set<Condition> getConditions() {
public List<Condition> getConditions() {
return conditions;
}
@@ -267,8 +286,8 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
case NotLike:
case Is:
case IsNot:
handleCondition(x.getLeft(), x.getOperator().name);
handleCondition(x.getRight(), x.getOperator().name);
handleCondition(x.getLeft(), x.getOperator().name, x.getRight());
handleCondition(x.getRight(), x.getOperator().name, x.getLeft());
handleRelationship(x.getLeft(), x.getOperator().name, x.getRight());
break;
@@ -297,16 +316,39 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
this.relationships.add(relationship);
}
protected void handleCondition(SQLExpr expr, String operator) {
protected void handleCondition(SQLExpr expr, String operator, List<SQLExpr> values) {
handleCondition(expr, operator, values.toArray(new SQLExpr[values.size()]));
}
protected void handleCondition(SQLExpr expr, String operator, SQLExpr... valueExprs) {
Column column = getColumn(expr);
if (column == null) {
return;
}
Condition condition = new Condition();
condition.setColumn(column);
condition.setOperator(operator);
this.conditions.add(condition);
Condition condition = null;
for (Condition item : this.getConditions()) {
if (item.getColumn().equals(column) && item.getOperator().equals(operator)) {
condition = item;
break;
}
}
if (condition == null) {
condition = new Condition();
condition.setColumn(column);
condition.setOperator(operator);
this.conditions.add(condition);
}
for (SQLExpr item : valueExprs) {
Object value = SQLEvalVisitorUtils.eval(getDbType(), item, parameters, false);
condition.getValues().add(value);
}
}
public String getDbType() {
return null;
}
protected Column getColumn(SQLExpr expr) {
@@ -820,9 +862,9 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
public boolean visit(SQLInListExpr x) {
if (x.isNot()) {
handleCondition(x.getExpr(), "NOT IN");
handleCondition(x.getExpr(), "NOT IN", x.getTargetList());
} else {
handleCondition(x.getExpr(), "IN");
handleCondition(x.getExpr(), "IN", x.getTargetList());
}
return true;
@@ -901,7 +943,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
public boolean visit(SQLCurrentOfCursorExpr x) {
return false;
}
@Override
public boolean visit(SQLAlterTableAddColumn x) {
SQLAlterTableStatement stmt = (SQLAlterTableStatement) x.getParent();
@@ -15,6 +15,9 @@
*/
package com.alibaba.druid.stat;
import java.util.ArrayList;
import java.util.List;
public class TableStat {
int selectCount = 0;
@@ -268,8 +271,10 @@ public class TableStat {
public static class Condition {
private Column column;
private String operator;
private Column column;
private String operator;
private List<Object> values = new ArrayList<Object>();
public Column getColumn() {
return column;
@@ -287,6 +292,10 @@ public class TableStat {
this.operator = operator;
}
public List<Object> getValues() {
return values;
}
@Override
public int hashCode() {
final int prime = 31;
@@ -64,6 +64,8 @@ public final class JdbcUtils {
public static final String DERBY = "derby";
public static final String HBASE = "hbase";
public static final String HIVE = "hive";
private final static Log LOG = LogFactory.getLog(JdbcUtils.class);