mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
bug fixed for sql SchemaStatVisitor
This commit is contained in:
@@ -681,20 +681,8 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
int index = x.getIndex();
|
||||
|
||||
if (index >= 0 && index < parametersSize) {
|
||||
Object param = this.getParameters().get(index);
|
||||
if (param instanceof Collection && x.getParent() instanceof SQLInListExpr) {
|
||||
boolean first = true;
|
||||
for (Object item : (Collection) param) {
|
||||
if (!first) {
|
||||
print0(", ");
|
||||
}
|
||||
printParameter(item);
|
||||
first = false;
|
||||
}
|
||||
} else {
|
||||
printParameter(param);
|
||||
}
|
||||
return false;
|
||||
|
||||
return super.visit(x);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,13 +21,14 @@ import java.util.List;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.SQLStatementImpl;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
|
||||
import com.alibaba.druid.sql.dialect.odps.visitor.OdpsASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
|
||||
public class OdpsInsertStatement extends SQLStatementImpl implements SQLStatement {
|
||||
|
||||
private SQLSubqueryTableSource from;
|
||||
private SQLTableSource from;
|
||||
|
||||
private List<OdpsInsert> items = new ArrayList<OdpsInsert>();
|
||||
|
||||
@@ -35,11 +36,11 @@ public class OdpsInsertStatement extends SQLStatementImpl implements SQLStatemen
|
||||
super (JdbcConstants.ODPS);
|
||||
}
|
||||
|
||||
public void setFrom(SQLSubqueryTableSource from) {
|
||||
public void setFrom(SQLTableSource from) {
|
||||
this.from = from;
|
||||
}
|
||||
|
||||
public SQLSubqueryTableSource getFrom() {
|
||||
public SQLTableSource getFrom() {
|
||||
return from;
|
||||
}
|
||||
|
||||
|
||||
@@ -226,19 +226,26 @@ public class OdpsStatementParser extends SQLStatementParser {
|
||||
|
||||
if (lexer.token() == Token.FROM) {
|
||||
lexer.nextToken();
|
||||
accept(Token.LPAREN);
|
||||
|
||||
SQLSelectParser selectParser = createSQLSelectParser();
|
||||
SQLSelect select = selectParser.select();
|
||||
if (lexer.token() == Token.IDENTIFIER) {
|
||||
SQLName tableName = this.exprParser.name();
|
||||
SQLExprTableSource from = new SQLExprTableSource(tableName);
|
||||
stmt.setFrom(from);
|
||||
} else {
|
||||
accept(Token.LPAREN);
|
||||
|
||||
accept(Token.RPAREN);
|
||||
SQLSelectParser selectParser = createSQLSelectParser();
|
||||
SQLSelect select = selectParser.select();
|
||||
|
||||
String alias = lexer.stringVal();
|
||||
accept(Token.IDENTIFIER);
|
||||
accept(Token.RPAREN);
|
||||
|
||||
SQLSubqueryTableSource from = new SQLSubqueryTableSource(select, alias);
|
||||
String alias = lexer.stringVal();
|
||||
accept(Token.IDENTIFIER);
|
||||
|
||||
stmt.setFrom(from);
|
||||
SQLSubqueryTableSource from = new SQLSubqueryTableSource(select, alias);
|
||||
|
||||
stmt.setFrom(from);
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
|
||||
@@ -27,14 +27,8 @@ import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLCaseExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLAssignItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.*;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource.JoinType;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTableElement;
|
||||
import com.alibaba.druid.sql.dialect.odps.ast.OdpsAddStatisticStatement;
|
||||
import com.alibaba.druid.sql.dialect.odps.ast.OdpsAnalyzeTableStatement;
|
||||
import com.alibaba.druid.sql.dialect.odps.ast.OdpsCreateTableStatement;
|
||||
@@ -194,15 +188,22 @@ public class OdpsOutputVisitor extends SQLASTOutputVisitor implements OdpsASTVis
|
||||
|
||||
@Override
|
||||
public boolean visit(OdpsInsertStatement x) {
|
||||
SQLTableSource from = x.getFrom();
|
||||
if (x.getFrom() != null) {
|
||||
print0(ucase ? "FROM (" : "from (");
|
||||
incrementIndent();
|
||||
println();
|
||||
x.getFrom().getSelect().accept(this);
|
||||
decrementIndent();
|
||||
println();
|
||||
print0(") ");
|
||||
print0(x.getFrom().getAlias());
|
||||
if (from instanceof SQLSubqueryTableSource) {
|
||||
SQLSelect select = ((SQLSubqueryTableSource) from).getSelect();
|
||||
print0(ucase ? "FROM (" : "from (");
|
||||
incrementIndent();
|
||||
println();
|
||||
select.accept(this);
|
||||
decrementIndent();
|
||||
println();
|
||||
print0(") ");
|
||||
print0(x.getFrom().getAlias());
|
||||
} else {
|
||||
print0(ucase ? "FROM " : "from ");
|
||||
from.accept(this);
|
||||
}
|
||||
println();
|
||||
}
|
||||
|
||||
|
||||
+32
-4
@@ -15,9 +15,9 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.odps.visitor;
|
||||
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLGrantStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.statement.*;
|
||||
import com.alibaba.druid.sql.dialect.odps.ast.OdpsAddStatisticStatement;
|
||||
import com.alibaba.druid.sql.dialect.odps.ast.OdpsAnalyzeTableStatement;
|
||||
import com.alibaba.druid.sql.dialect.odps.ast.OdpsCreateTableStatement;
|
||||
@@ -37,6 +37,9 @@ import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowStatisticStmt;
|
||||
import com.alibaba.druid.sql.dialect.odps.ast.OdpsStatisticClause;
|
||||
import com.alibaba.druid.sql.dialect.odps.ast.OdpsUDTFSQLSelectItem;
|
||||
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
|
||||
import com.alibaba.druid.stat.TableStat;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class OdpsSchemaStatVisitor extends SchemaStatVisitor implements OdpsASTVisitor {
|
||||
|
||||
@@ -57,7 +60,7 @@ public class OdpsSchemaStatVisitor extends SchemaStatVisitor implements OdpsASTV
|
||||
|
||||
@Override
|
||||
public boolean visit(OdpsInsertStatement x) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -67,6 +70,31 @@ public class OdpsSchemaStatVisitor extends SchemaStatVisitor implements OdpsASTV
|
||||
|
||||
@Override
|
||||
public boolean visit(OdpsInsert x) {
|
||||
setMode(x, TableStat.Mode.Insert);
|
||||
|
||||
setAliasMap();
|
||||
|
||||
SQLExprTableSource tableSource = x.getTableSource();
|
||||
SQLExpr tableName = tableSource.getExpr();
|
||||
|
||||
if (tableName instanceof SQLName) {
|
||||
String ident = ((SQLName) tableName).toString();
|
||||
setCurrentTable(ident);
|
||||
|
||||
TableStat stat = getTableStat(ident);
|
||||
stat.incrementInsertCount();
|
||||
|
||||
Map<String, String> aliasMap = getAliasMap();
|
||||
putAliasMap(aliasMap, tableSource.getAlias(), ident);
|
||||
putAliasMap(aliasMap, ident, ident);
|
||||
}
|
||||
|
||||
for (SQLAssignItem partition : x.getPartitions()) {
|
||||
partition.accept(this);
|
||||
}
|
||||
|
||||
accept(x.getQuery());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,9 +15,11 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.visitor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLObject;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLBetweenExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLBooleanExpr;
|
||||
@@ -86,21 +88,46 @@ public final class ExportParameterVisitorUtils {
|
||||
}
|
||||
|
||||
public static SQLExpr exportParameter(final List<Object> parameters, final SQLExpr param) {
|
||||
Object value = null;
|
||||
boolean replace = false;
|
||||
|
||||
if (param instanceof SQLCharExpr) {
|
||||
Object value = ((SQLCharExpr) param).getText();
|
||||
parameters.add(value);
|
||||
return new SQLVariantRefExpr("?");
|
||||
value = ((SQLCharExpr) param).getText();
|
||||
replace = true;
|
||||
}
|
||||
|
||||
if (param instanceof SQLBooleanExpr) {
|
||||
Object value = ((SQLBooleanExpr) param).getValue();
|
||||
parameters.add(value);
|
||||
return new SQLVariantRefExpr("?");
|
||||
value = ((SQLBooleanExpr) param).getValue();
|
||||
replace = true;
|
||||
}
|
||||
|
||||
if (param instanceof SQLNumericLiteralExpr) {
|
||||
Object value = ((SQLNumericLiteralExpr) param).getNumber();
|
||||
value = ((SQLNumericLiteralExpr) param).getNumber();
|
||||
replace = true;
|
||||
}
|
||||
|
||||
if (replace) {
|
||||
SQLObject parent = param.getParent();
|
||||
if (parent != null) {
|
||||
List<SQLObject> mergedList = (List<SQLObject>) parent.getAttribute(ParameterizedOutputVisitorUtils.ATTR_MERGED);
|
||||
if (mergedList != null) {
|
||||
List<Object> mergedListParams = new ArrayList<Object>(mergedList.size() + 1);
|
||||
for (int i = 0; i < mergedList.size(); ++i) {
|
||||
SQLObject item = mergedList.get(i);
|
||||
if (item instanceof SQLBinaryOpExpr) {
|
||||
SQLBinaryOpExpr binaryOpItem = (SQLBinaryOpExpr) item;
|
||||
exportParameter(mergedListParams, binaryOpItem.getRight());
|
||||
}
|
||||
}
|
||||
if (mergedListParams.size() > 0) {
|
||||
mergedListParams.add(0, value);
|
||||
value = mergedListParams;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parameters.add(value);
|
||||
|
||||
return new SQLVariantRefExpr("?");
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.visitor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLDataType;
|
||||
@@ -23,10 +24,8 @@ import com.alibaba.druid.sql.ast.SQLObject;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLNullExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem;
|
||||
@@ -154,6 +153,16 @@ public class ParameterizedOutputVisitorUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
public final static String ATTR_MERGED = "parameterized.mergedList";
|
||||
static void putMergedArribute(SQLObject object, SQLObject item) {
|
||||
List<SQLObject> mergedList = (List<SQLObject>) object.getAttribute(ATTR_MERGED);
|
||||
if (mergedList == null) {
|
||||
mergedList = new ArrayList<SQLObject>();
|
||||
object.putAttribute(ATTR_MERGED, mergedList);
|
||||
}
|
||||
mergedList.add(item);
|
||||
}
|
||||
|
||||
public static SQLBinaryOpExpr merge(ParameterizedVisitor v, SQLBinaryOpExpr x) {
|
||||
SQLExpr left = x.getLeft();
|
||||
SQLExpr right = x.getRight();
|
||||
@@ -201,10 +210,11 @@ public class ParameterizedOutputVisitorUtils {
|
||||
if (x.getLeft() instanceof SQLBinaryOpExpr) {
|
||||
SQLExpr mergedLeft = merge(v, (SQLBinaryOpExpr) x.getLeft());
|
||||
if (mergedLeft != x.getLeft()) {
|
||||
x = new SQLBinaryOpExpr(mergedLeft, x.getOperator(), x.getRight());
|
||||
SQLBinaryOpExpr tmp = new SQLBinaryOpExpr(mergedLeft, x.getOperator(), x.getRight());
|
||||
tmp.setParent(parent);
|
||||
x = tmp;
|
||||
v.incrementReplaceCunt();
|
||||
}
|
||||
x.setParent(parent);
|
||||
}
|
||||
|
||||
// ID = ? OR ID = ? => ID = ?
|
||||
@@ -215,6 +225,8 @@ public class ParameterizedOutputVisitorUtils {
|
||||
|
||||
if (mergeEqual(leftBinary, rightBinary)) {
|
||||
v.incrementReplaceCunt();
|
||||
leftBinary.setParent(x.getParent());
|
||||
putMergedArribute(leftBinary, rightBinary);
|
||||
return leftBinary;
|
||||
}
|
||||
|
||||
@@ -222,6 +234,7 @@ public class ParameterizedOutputVisitorUtils {
|
||||
&& leftBinary.getOperator() == SQLBinaryOperator.BooleanOr) {
|
||||
if (mergeEqual(leftBinary.getRight(), x.getRight())) {
|
||||
v.incrementReplaceCunt();
|
||||
putMergedArribute(leftBinary, rightBinary);
|
||||
return leftBinary;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,6 +318,25 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
x = ParameterizedOutputVisitorUtils.merge(this, x);
|
||||
}
|
||||
|
||||
if (parameters != null
|
||||
&& parameters.size() > 0
|
||||
&& x.getOperator() == SQLBinaryOperator.Equality
|
||||
&& x.getRight() instanceof SQLVariantRefExpr
|
||||
) {
|
||||
SQLVariantRefExpr right = (SQLVariantRefExpr) x.getRight();
|
||||
int index = right.getIndex();
|
||||
if (index >= 0 && index < parameters.size()) {
|
||||
Object param = parameters.get(index);
|
||||
if (param instanceof Collection) {
|
||||
x.getLeft().accept(this);
|
||||
print0(" IN (");
|
||||
right.accept(this);
|
||||
print(')');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SQLObject parent = x.getParent();
|
||||
boolean isRoot = parent instanceof SQLSelectQueryBlock;
|
||||
boolean relational = x.getOperator() == SQLBinaryOperator.BooleanAnd
|
||||
@@ -1259,7 +1278,23 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
|
||||
Object param = parameters.get(index);
|
||||
|
||||
if (param instanceof Collection && x.getParent() instanceof SQLInListExpr) {
|
||||
SQLObject parent = x.getParent();
|
||||
|
||||
boolean in;
|
||||
if (parent instanceof SQLInListExpr) {
|
||||
in = true;
|
||||
} else if (parent instanceof SQLBinaryOpExpr) {
|
||||
SQLBinaryOpExpr binaryOpExpr = (SQLBinaryOpExpr) parent;
|
||||
if (binaryOpExpr.getOperator() == SQLBinaryOperator.Equality) {
|
||||
in = true;
|
||||
} else {
|
||||
in = false;
|
||||
}
|
||||
} else {
|
||||
in = false;
|
||||
}
|
||||
|
||||
if (in && param instanceof Collection) {
|
||||
boolean first = true;
|
||||
for (Object item : (Collection) param) {
|
||||
if (!first) {
|
||||
|
||||
@@ -62,6 +62,7 @@ import com.alibaba.druid.stat.TableStat.Condition;
|
||||
import com.alibaba.druid.stat.TableStat.Mode;
|
||||
import com.alibaba.druid.stat.TableStat.Relationship;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
import com.alibaba.druid.util.StringUtils;
|
||||
|
||||
public class SchemaStatVisitor extends SQLASTVisitorAdapter {
|
||||
|
||||
@@ -518,6 +519,10 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
|
||||
}
|
||||
|
||||
for (SQLExpr item : valueExprs) {
|
||||
Column valueColumn = getColumn(item);
|
||||
if (valueColumn != null) {
|
||||
continue;
|
||||
}
|
||||
Object value = SQLEvalVisitorUtils.eval(getDbType(), item, parameters, false);
|
||||
condition.getValues().add(value);
|
||||
}
|
||||
@@ -541,6 +546,10 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
if (expr instanceof SQLCastExpr) {
|
||||
expr = ((SQLCastExpr) expr).getExpr();
|
||||
}
|
||||
|
||||
if (expr instanceof SQLPropertyExpr) {
|
||||
SQLExpr owner = ((SQLPropertyExpr) expr).getOwner();
|
||||
String column = ((SQLPropertyExpr) expr).getName();
|
||||
@@ -854,6 +863,8 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
|
||||
}
|
||||
|
||||
if (selectList != null) {
|
||||
boolean allColumn = false;
|
||||
String allColumnOwner = null;
|
||||
for (SQLSelectItem item : selectList) {
|
||||
if (!item.getClass().equals(SQLSelectItem.class)) {
|
||||
continue;
|
||||
@@ -885,7 +896,52 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (itemExpr instanceof SQLAllColumnExpr) {
|
||||
allColumn = true;
|
||||
} else if (itemExpr instanceof SQLPropertyExpr) {
|
||||
SQLPropertyExpr propertyExpr = (SQLPropertyExpr) itemExpr;
|
||||
if (propertyExpr.getName().equals("*")) {
|
||||
SQLExpr owner = propertyExpr.getOwner();
|
||||
if (owner instanceof SQLIdentifierExpr) {
|
||||
allColumnOwner = ((SQLIdentifierExpr) owner).getName();
|
||||
allColumn = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (allColumn) {
|
||||
|
||||
SQLTableSource from = queryBlock.getFrom();
|
||||
String tableName = getTable(from, allColumnOwner);
|
||||
if (tableName != null) {
|
||||
return new Column(tableName, alias);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getTable(SQLTableSource from, String tableAlias) {
|
||||
if (from instanceof SQLExprTableSource) {
|
||||
boolean aliasEq = StringUtils.equals(from.getAlias(), tableAlias);
|
||||
SQLExpr tableSourceExpr = ((SQLExprTableSource) from).getExpr();
|
||||
if (tableSourceExpr instanceof SQLName) {
|
||||
String tableName = ((SQLName) tableSourceExpr).toString();
|
||||
if (tableAlias == null || aliasEq) {
|
||||
return tableName;
|
||||
}
|
||||
}
|
||||
} else if (from instanceof SQLJoinTableSource) {
|
||||
SQLJoinTableSource joinTableSource = (SQLJoinTableSource) from;
|
||||
String leftMatchTableName = getTable(joinTableSource.getLeft(), tableAlias);
|
||||
if (leftMatchTableName != null) {
|
||||
return leftMatchTableName;
|
||||
}
|
||||
|
||||
return getTable(joinTableSource.getRight(), tableAlias);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user