diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java index 80a6afd6d1..5c46267177 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java @@ -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); } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsInsertStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsInsertStatement.java index 5e20446289..bca8af50ff 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsInsertStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsInsertStatement.java @@ -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 items = new ArrayList(); @@ -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; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java index d7b1e29570..dedca4506d 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java @@ -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 (;;) { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java index e96efc145b..8213cd6100 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java @@ -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(); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsSchemaStatVisitor.java index 96fc53f955..5c9922f7a5 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsSchemaStatVisitor.java @@ -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 aliasMap = getAliasMap(); + putAliasMap(aliasMap, tableSource.getAlias(), ident); + putAliasMap(aliasMap, ident, ident); + } + + for (SQLAssignItem partition : x.getPartitions()) { + partition.accept(this); + } + + accept(x.getQuery()); + return false; } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/ExportParameterVisitorUtils.java b/src/main/java/com/alibaba/druid/sql/visitor/ExportParameterVisitorUtils.java index f3faebbfd2..55debe4a88 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/ExportParameterVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/ExportParameterVisitorUtils.java @@ -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 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 mergedList = (List) parent.getAttribute(ParameterizedOutputVisitorUtils.ATTR_MERGED); + if (mergedList != null) { + List mergedListParams = new ArrayList(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("?"); } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java b/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java index 4da42b54d5..b60d0cf74d 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java @@ -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 mergedList = (List) object.getAttribute(ATTR_MERGED); + if (mergedList == null) { + mergedList = new ArrayList(); + 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; } } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java index 6deb71bf8f..cee9010cef 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -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) { diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java index 0e9910e87d..b0c46ac6c6 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java @@ -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; diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_33.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_33.java new file mode 100644 index 0000000000..daa1736276 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_33.java @@ -0,0 +1,62 @@ +package com.alibaba.druid.bvt.sql.mysql.param; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.parser.SQLParserUtils; +import com.alibaba.druid.sql.parser.SQLStatementParser; +import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils; +import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by wenshao on 16/8/23. + */ +public class MySqlParameterizedOutputVisitorTest_33 extends TestCase { + public void test_for_parameterize() throws Exception { + final String dbType = JdbcConstants.MYSQL; + + + String sql = "select * from t where id = 1 or id = 2"; + + String psql = ParameterizedOutputVisitorUtils.parameterize(sql, dbType); + assertEquals("SELECT *\n" + + "FROM t\n" + + "WHERE id = ?", psql); + + SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType); + List stmtList = parser.parseStatementList(); + + StringBuilder out = new StringBuilder(); + SQLASTOutputVisitor visitor = SQLUtils.createOutputVisitor(out, JdbcConstants.MYSQL); + List parameters = new ArrayList(); + visitor.setParameterized(true); + visitor.setParameterizedMergeInList(true); + visitor.setParameters(parameters); + visitor.setExportTables(true); + /*visitor.setPrettyFormat(false);*/ + + SQLStatement stmt = stmtList.get(0); + stmt.accept(visitor); + + // System.out.println(parameters); + assertEquals(1, parameters.size()); + + //SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(psql, dbType); + // List stmtList = parser.parseStatementList(); + SQLStatement pstmt = SQLUtils.parseStatements(psql, dbType).get(0); + + StringBuilder buf = new StringBuilder(); + SQLASTOutputVisitor visitor1 = SQLUtils.createOutputVisitor(buf, dbType); + visitor1.addTableMapping("udata", "udata_0888"); + visitor1.setParameters(visitor.getParameters()); + pstmt.accept(visitor1); + + assertEquals("SELECT *\n" + + "FROM t\n" + + "WHERE id IN (1, 2)", buf.toString()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_34.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_34.java new file mode 100644 index 0000000000..d28553c714 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_34.java @@ -0,0 +1,62 @@ +package com.alibaba.druid.bvt.sql.mysql.param; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.parser.SQLParserUtils; +import com.alibaba.druid.sql.parser.SQLStatementParser; +import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils; +import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by wenshao on 16/8/23. + */ +public class MySqlParameterizedOutputVisitorTest_34 extends TestCase { + public void test_for_parameterize() throws Exception { + final String dbType = JdbcConstants.MYSQL; + + + String sql = "select * from t where id = 1 or id = 2 or id = 3"; + + String psql = ParameterizedOutputVisitorUtils.parameterize(sql, dbType); + assertEquals("SELECT *\n" + + "FROM t\n" + + "WHERE id = ?", psql); + + SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType); + List stmtList = parser.parseStatementList(); + + StringBuilder out = new StringBuilder(); + SQLASTOutputVisitor visitor = SQLUtils.createOutputVisitor(out, JdbcConstants.MYSQL); + List parameters = new ArrayList(); + visitor.setParameterized(true); + visitor.setParameterizedMergeInList(true); + visitor.setParameters(parameters); + visitor.setExportTables(true); + /*visitor.setPrettyFormat(false);*/ + + SQLStatement stmt = stmtList.get(0); + stmt.accept(visitor); + + // System.out.println(parameters); + assertEquals(1, parameters.size()); + + //SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(psql, dbType); + // List stmtList = parser.parseStatementList(); + SQLStatement pstmt = SQLUtils.parseStatements(psql, dbType).get(0); + + StringBuilder buf = new StringBuilder(); + SQLASTOutputVisitor visitor1 = SQLUtils.createOutputVisitor(buf, dbType); + visitor1.addTableMapping("udata", "udata_0888"); + visitor1.setParameters(visitor.getParameters()); + pstmt.accept(visitor1); + + assertEquals("SELECT *\n" + + "FROM t\n" + + "WHERE id IN (1, 2, 3)", buf.toString()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsMultiInsertTest2.java b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsMultiInsertTest2.java new file mode 100644 index 0000000000..132ce7fce3 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsMultiInsertTest2.java @@ -0,0 +1,24 @@ +package com.alibaba.druid.bvt.sql.odps; + +import com.alibaba.druid.sql.SQLUtils; +import junit.framework.TestCase; +import org.junit.Assert; + +public class OdpsMultiInsertTest2 extends TestCase { + public void test_for_multi_insert() throws Exception { + String sql = "from sale_detail\n" + + "insert overwrite table sale_detail_multi partition (sale_date='2010', region='china' )\n" + + "select shop_name, customer_id, total_price\n" + + "insert overwrite table sale_detail_multi partition (sale_date='2011', region='china' )\n" + + "select shop_name, customer_id, total_price;\n"; + Assert.assertEquals("FROM sale_detail\n" + + "INSERT OVERWRITE TABLE sale_detail_multi PARTITION (sale_date='2010', region='china')\n" + + "SELECT shop_name\n" + + "\t, customer_id\n" + + "\t, total_price\n" + + "INSERT OVERWRITE TABLE sale_detail_multi PARTITION (sale_date='2011', region='china')\n" + + "SELECT shop_name\n" + + "\t, customer_id\n" + + "\t, total_price;", SQLUtils.formatOdps(sql)); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/schemaStat/SchemaStatTest10.java b/src/test/java/com/alibaba/druid/bvt/sql/schemaStat/SchemaStatTest10.java new file mode 100644 index 0000000000..4f27a967b3 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/schemaStat/SchemaStatTest10.java @@ -0,0 +1,41 @@ +package com.alibaba.druid.bvt.sql.schemaStat; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.parser.SQLParserUtils; +import com.alibaba.druid.sql.parser.SQLStatementParser; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.util.Set; + +public class SchemaStatTest10 extends TestCase { + + public void test_schemaStat() throws Exception { + String sql = "select a.id, b.name from table1 a inner join table2 b on a.id = b.id"; + + String dbType = JdbcConstants.ORACLE; + SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType); + SQLStatement stmt = parser.parseStatementList().get(0); + + SchemaStatVisitor statVisitor = SQLUtils.createSchemaStatVisitor(dbType); + stmt.accept(statVisitor); + + Set relationships = statVisitor.getRelationships(); + for (TableStat.Relationship relationship : relationships) { + System.out.println(relationship); // table1.id = table2.id + } + +// System.out.println(statVisitor.getColumns()); +// System.out.println(statVisitor.getGroupByColumns()); // group by + System.out.println("relationships : " + statVisitor.getRelationships()); // group by +// System.out.println(statVisitor.getConditions()); + + Assert.assertEquals(3, statVisitor.getColumns().size()); + Assert.assertEquals(2, statVisitor.getConditions().size()); + assertEquals(0, statVisitor.getFunctions().size()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/schemaStat/SchemaStatTest11.java b/src/test/java/com/alibaba/druid/bvt/sql/schemaStat/SchemaStatTest11.java new file mode 100644 index 0000000000..08fe643fe5 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/schemaStat/SchemaStatTest11.java @@ -0,0 +1,42 @@ +package com.alibaba.druid.bvt.sql.schemaStat; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.parser.SQLParserUtils; +import com.alibaba.druid.sql.parser.SQLStatementParser; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.util.Set; + +public class SchemaStatTest11 extends TestCase { + + public void test_schemaStat() throws Exception { + String sql = "select a.id, b.name from (select * from table1) a inner join table2 b on a.id = b.id"; + + String dbType = JdbcConstants.ORACLE; + SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType); + SQLStatement stmt = parser.parseStatementList().get(0); + + SchemaStatVisitor statVisitor = SQLUtils.createSchemaStatVisitor(dbType); + stmt.accept(statVisitor); + + Set relationships = statVisitor.getRelationships(); + for (TableStat.Relationship relationship : relationships) { + System.out.println(relationship); // table1.id = table2.id + } + +// System.out.println(statVisitor.getColumns()); +// System.out.println(statVisitor.getGroupByColumns()); // group by + System.out.println("relationships : " + statVisitor.getRelationships()); // group by + System.out.println(statVisitor.getConditions()); + assertEquals(1, relationships.size()); + + Assert.assertEquals(3, statVisitor.getColumns().size()); + Assert.assertEquals(2, statVisitor.getConditions().size()); + assertEquals(0, statVisitor.getFunctions().size()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/schemaStat/SchemaStatTest12.java b/src/test/java/com/alibaba/druid/bvt/sql/schemaStat/SchemaStatTest12.java new file mode 100644 index 0000000000..9cdcde9e92 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/schemaStat/SchemaStatTest12.java @@ -0,0 +1,57 @@ +package com.alibaba.druid.bvt.sql.schemaStat; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.parser.SQLParserUtils; +import com.alibaba.druid.sql.parser.SQLStatementParser; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.util.Set; + +public class SchemaStatTest12 extends TestCase { + + public void test_schemaStat() throws Exception { + String sql = "select work_no , nick_name , name , ifnull(sum(investment_percentage ) / 100 , 0 ) as invest_percent " + + "from ( " + + " select t1.id , t1.work_no , t2.nick_name , t2.name , t2.super_work_no , t2.super_nick_name , t2.super_name " + + " , t3.project_name , t1.investment_percentage , t4.dept_name " + + " from t_pm_aur t2 " + + " left outer join ( " + + " select * from t_pm_rs_acl " + + " where is_deleted = 0 and prj_biz_id is not null and ivt_pt > 0 and iwk = '2016W17' " + + " ) t1 on t2.work_no = t1.work_no " + + " left outer join ( " + + " select * from t_pm_prj_i " + + " where( status not in( 'DEPRECATED' , 'FINISHED' ) or status is null ) and( task_type not in( 'WEEKLY_REPORT' ) or task_type is null ) and is_deleted = 0 " + + " ) t3 on t1.prj_biz_id = t3.biz_id " + + " left outer join t_pm_dpt t4 on t2.dept_no = t4.biz_id " + + " where t4.dept_name like 'MY-XDSYB-JSB%' and t2.emp_type in( 'R' , 'V' ) and t2.is_deleted = 'N' and t2.work_status = 'A' " + + ") t5 group by work_no , nick_name , name having invest_percent < 1.0 "; + + String dbType = JdbcConstants.ORACLE; + SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType); + SQLStatement stmt = parser.parseStatementList().get(0); + + SchemaStatVisitor statVisitor = SQLUtils.createSchemaStatVisitor(dbType); + stmt.accept(statVisitor); + + Set relationships = statVisitor.getRelationships(); + for (TableStat.Relationship relationship : relationships) { + System.out.println(relationship); // table1.id = table2.id + } + +// System.out.println(statVisitor.getColumns()); +// System.out.println(statVisitor.getGroupByColumns()); // group by + System.out.println("relationships : " + statVisitor.getRelationships()); // group by + System.out.println(statVisitor.getConditions()); + assertEquals(3, relationships.size()); + + Assert.assertEquals(21, statVisitor.getColumns().size()); + Assert.assertEquals(20, statVisitor.getConditions().size()); + assertEquals(1, statVisitor.getFunctions().size()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/schemaStat/SchemaStatTest13.java b/src/test/java/com/alibaba/druid/bvt/sql/schemaStat/SchemaStatTest13.java new file mode 100644 index 0000000000..e7eda98128 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/schemaStat/SchemaStatTest13.java @@ -0,0 +1,42 @@ +package com.alibaba.druid.bvt.sql.schemaStat; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.parser.SQLParserUtils; +import com.alibaba.druid.sql.parser.SQLStatementParser; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.util.Set; + +public class SchemaStatTest13 extends TestCase { + + public void test_schemaStat() throws Exception { + String sql = "select a.id, b.name from (select t1.* from table1 t1 left join table3 t3 on cast(t1.id as bigint) = t3.id) a inner join table2 b on a.id = b.id"; + + String dbType = JdbcConstants.ORACLE; + SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType); + SQLStatement stmt = parser.parseStatementList().get(0); + + SchemaStatVisitor statVisitor = SQLUtils.createSchemaStatVisitor(dbType); + stmt.accept(statVisitor); + + Set relationships = statVisitor.getRelationships(); + for (TableStat.Relationship relationship : relationships) { + System.out.println(relationship); // table1.id = table2.id + } + +// System.out.println(statVisitor.getColumns()); +// System.out.println(statVisitor.getGroupByColumns()); // group by + System.out.println("relationships : " + statVisitor.getRelationships()); // group by + System.out.println(statVisitor.getConditions()); + assertEquals(2, relationships.size()); + + Assert.assertEquals(5, statVisitor.getColumns().size()); + Assert.assertEquals(3, statVisitor.getConditions().size()); + assertEquals(0, statVisitor.getFunctions().size()); + } +} diff --git a/src/test/java/com/alibaba/druid/demo/sql/SchemaStatTest_odps.java b/src/test/java/com/alibaba/druid/demo/sql/SchemaStatTest_odps.java new file mode 100644 index 0000000000..713148f013 --- /dev/null +++ b/src/test/java/com/alibaba/druid/demo/sql/SchemaStatTest_odps.java @@ -0,0 +1,51 @@ +package com.alibaba.druid.demo.sql; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.parser.SQLParserUtils; +import com.alibaba.druid.sql.parser.SQLStatementParser; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.junit.Assert; + +import java.io.File; +import java.util.List; +import java.util.Set; + +public class SchemaStatTest_odps extends TestCase { + + public void test_schemaStat() throws Exception { + File file = new File("/Users/wenshao/Downloads/odps_sql.txt"); + String sql = FileUtils.readFileToString(file); + + String dbType = JdbcConstants.ODPS; + SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType); + List stmtList = parser.parseStatementList(); + + System.out.println("stmtList size : " + stmtList.size()); + + SchemaStatVisitor statVisitor = SQLUtils.createSchemaStatVisitor(dbType); + for (SQLStatement stmt : stmtList) { + stmt.accept(statVisitor); + } + + Set relationships = statVisitor.getRelationships(); + for (TableStat.Relationship relationship : relationships) { + System.out.println(relationship); // table1.id = table2.id + } + +// System.out.println(statVisitor.getColumns()); +// System.out.println(statVisitor.getGroupByColumns()); // group by + System.out.println("relationships : " + statVisitor.getRelationships()); // group by + System.out.println(statVisitor.getConditions()); + assertEquals(3, relationships.size()); + + Assert.assertEquals(21, statVisitor.getColumns().size()); + Assert.assertEquals(20, statVisitor.getConditions().size()); + assertEquals(1, statVisitor.getFunctions().size()); + } +}