diff --git a/src/main/java/com/alibaba/druid/sql/SQLUtils.java b/src/main/java/com/alibaba/druid/sql/SQLUtils.java index e8154b74c7..edc39ceb25 100644 --- a/src/main/java/com/alibaba/druid/sql/SQLUtils.java +++ b/src/main/java/com/alibaba/druid/sql/SQLUtils.java @@ -479,21 +479,7 @@ public class SQLUtils { } public static List split(SQLBinaryOpExpr x) { - List groupList = new ArrayList(); - groupList.add(x.getRight()); - - SQLExpr left = x.getLeft(); - for (;;) { - if (left instanceof SQLBinaryOpExpr && ((SQLBinaryOpExpr) left).getOperator() == x.getOperator()) { - SQLBinaryOpExpr binaryLeft = (SQLBinaryOpExpr) left; - groupList.add(binaryLeft.getRight()); - left = binaryLeft.getLeft(); - } else { - groupList.add(left); - break; - } - } - return groupList; + return SQLBinaryOpExpr.split(x); } public static String translateOracleToMySql(String sql) { @@ -789,5 +775,40 @@ public class SQLUtils { return new SQLUnaryExpr(SQLUnaryOperator.Not, expr); } + + public static String normalize(String name) { + if (name.length() > 2) { + char c0 = name.charAt(0); + char x0 = name.charAt(name.length() - 1); + if ((c0 == '"' && x0 == '"') || (c0 == '`' && x0 == '`')) { + name = name.substring(1, name.length() - 1); + } + } + + return name; + } + + public static boolean isValue(SQLExpr expr) { + if (expr instanceof SQLLiteralExpr) { + return true; + } + + if (expr instanceof SQLVariantRefExpr) { + return true; + } + + if (expr instanceof SQLBinaryOpExpr) { + SQLBinaryOpExpr binaryOpExpr = (SQLBinaryOpExpr) expr; + SQLBinaryOperator op = binaryOpExpr.getOperator(); + if (op == SQLBinaryOperator.Add + || op == SQLBinaryOperator.Subtract + || op == SQLBinaryOperator.Multiply) { + return isValue(binaryOpExpr.getLeft()) + && isValue(binaryOpExpr.getRight()); + } + } + + return false; + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/SQLExprImpl.java b/src/main/java/com/alibaba/druid/sql/ast/SQLExprImpl.java index 6343a0dc1b..69da273b24 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/SQLExprImpl.java +++ b/src/main/java/com/alibaba/druid/sql/ast/SQLExprImpl.java @@ -26,6 +26,6 @@ public abstract class SQLExprImpl extends SQLObjectImpl implements SQLExpr { public abstract int hashCode(); public SQLExpr clone() { - throw new UnsupportedOperationException(); + throw new UnsupportedOperationException(this.getClass().getName()); } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/SQLLimit.java b/src/main/java/com/alibaba/druid/sql/ast/SQLLimit.java index 7d1442984b..cead4efd85 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/SQLLimit.java +++ b/src/main/java/com/alibaba/druid/sql/ast/SQLLimit.java @@ -71,7 +71,17 @@ public class SQLLimit extends SQLObjectImpl { } public SQLLimit clone() { - throw new UnsupportedOperationException(); + SQLLimit x = new SQLLimit(); + + if (offset != null) { + x.setOffset(offset.clone()); + } + + if (rowCount != null) { + x.setRowCount(rowCount.clone()); + } + + return x; } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/SQLObjectImpl.java b/src/main/java/com/alibaba/druid/sql/ast/SQLObjectImpl.java index 8b69a74b23..13d8152d95 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/SQLObjectImpl.java +++ b/src/main/java/com/alibaba/druid/sql/ast/SQLObjectImpl.java @@ -209,6 +209,6 @@ public abstract class SQLObjectImpl implements SQLObject { } public SQLObject clone() { - throw new UnsupportedOperationException(); + throw new UnsupportedOperationException(this.getClass().getName()); } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/SQLOrderBy.java b/src/main/java/com/alibaba/druid/sql/ast/SQLOrderBy.java index 2a65db9425..071fc10047 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/SQLOrderBy.java +++ b/src/main/java/com/alibaba/druid/sql/ast/SQLOrderBy.java @@ -98,6 +98,16 @@ public class SQLOrderBy extends SQLObjectImpl { } public SQLOrderBy clone() { - throw new UnsupportedOperationException(); + SQLOrderBy x = new SQLOrderBy(); + + for (SQLSelectOrderByItem item : items) { + SQLSelectOrderByItem item1 = item.clone(); + item1.setParent(x); + x.items.add(item1); + } + + x.sibings = sibings; + + return x; } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLAllColumnExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLAllColumnExpr.java index aae81188c6..f434954b1d 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLAllColumnExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLAllColumnExpr.java @@ -40,4 +40,8 @@ public class SQLAllColumnExpr extends SQLExprImpl { public boolean equals(Object o) { return o instanceof SQLAllColumnExpr; } + + public SQLAllColumnExpr clone() { + return new SQLAllColumnExpr(); + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLBinaryOpExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLBinaryOpExpr.java index 04cdd0ecf8..c6761c4a45 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLBinaryOpExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLBinaryOpExpr.java @@ -16,6 +16,8 @@ package com.alibaba.druid.sql.ast.expr; import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLExpr; @@ -152,4 +154,139 @@ public class SQLBinaryOpExpr extends SQLExprImpl implements Serializable { public String toString() { return SQLUtils.toSQLString(this, getDbType()); } + + public static SQLExpr combine(List items, SQLBinaryOperator op) { + if (items == null || op == null) { + return null; + } + + int size = items.size(); + if (size == 0) { + return null; + } + + if (size == 1) { + return items.get(0); + } + + SQLBinaryOpExpr expr = new SQLBinaryOpExpr(items.get(0), op, items.get(1)); + + for (int i = 2; i < size; ++i) { + SQLExpr item = items.get(i); + expr = new SQLBinaryOpExpr(expr, op, item); + } + + return expr; + } + + public static List split(SQLBinaryOpExpr x) { + return split(x, x.getOperator()); + } + + public static List split(SQLBinaryOpExpr x, SQLBinaryOperator op) { + if (x.getOperator() != op) { + List groupList = new ArrayList(1); + groupList.add(x); + return groupList; + } + + List groupList = new ArrayList(); + split(groupList, x, op); + return groupList; + } + + public static void split(List outList, SQLExpr expr, SQLBinaryOperator op) { + if (expr == null) { + return; + } + + if (!(expr instanceof SQLBinaryOpExpr)) { + outList.add(expr); + return; + } + + SQLBinaryOpExpr binaryExpr = (SQLBinaryOpExpr) expr; + + if (binaryExpr.getOperator() != op) { + outList.add(binaryExpr); + return; + } + + List rightList = new ArrayList(); + rightList.add(binaryExpr.getRight()); + for (SQLExpr left = binaryExpr.getLeft();;) { + if (left instanceof SQLBinaryOpExpr) { + SQLBinaryOpExpr leftBinary = (SQLBinaryOpExpr) left; + if (leftBinary.operator == op) { + left = ((SQLBinaryOpExpr) leftBinary).getLeft(); + rightList.add(leftBinary.getRight()); + } else { + outList.add(leftBinary); + break; + } + } else { + outList.add(left); + break; + } + } + + for (int i = rightList.size() - 1; i >= 0; --i) { + SQLExpr right = rightList.get(i); + + if (right instanceof SQLBinaryOpExpr) { + SQLBinaryOpExpr binaryRight = (SQLBinaryOpExpr) right; + if (binaryRight.operator == op) { + { + SQLExpr rightLeft = binaryRight.getLeft(); + if (rightLeft instanceof SQLBinaryOpExpr) { + SQLBinaryOpExpr rightLeftBinary = (SQLBinaryOpExpr) rightLeft; + if (rightLeftBinary.operator == op) { + split(outList, rightLeftBinary, op); + } else { + outList.add(rightLeftBinary); + } + } else { + outList.add(rightLeft); + } + } + { + SQLExpr rightRight = binaryRight.getRight(); + if (rightRight instanceof SQLBinaryOpExpr) { + SQLBinaryOpExpr rightRightBinary = (SQLBinaryOpExpr) rightRight; + if (rightRightBinary.operator == op) { + split(outList, rightRightBinary, op); + } else { + outList.add(rightRightBinary); + } + } else { + outList.add(rightRight); + } + } + } else { + outList.add(binaryRight); + } + } else { + outList.add(right); + } + } + } + + public static SQLExpr and(SQLExpr a, SQLExpr b) { + if (a == null) { + return b; + } + + if (b == null) { + return a; + } + + if (b instanceof SQLBinaryOpExpr) { + SQLBinaryOpExpr bb = (SQLBinaryOpExpr) b; + if (bb.operator == SQLBinaryOperator.BooleanAnd) { + return and(and(a, bb.left), bb.right); + } + } + + return new SQLBinaryOpExpr(a, SQLBinaryOperator.BooleanAnd, b); + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLCaseExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLCaseExpr.java index 1d2c618d2e..11cc17da80 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLCaseExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLCaseExpr.java @@ -147,6 +147,17 @@ public class SQLCaseExpr extends SQLExprImpl implements Serializable { return true; } + + public Item clone() { + Item x = new Item(); + if (conditionExpr != null) { + x.setConditionExpr(conditionExpr.clone()); + } + if (valueExpr != null) { + x.setValueExpr(valueExpr.clone()); + } + return x; + } } @Override @@ -195,4 +206,22 @@ public class SQLCaseExpr extends SQLExprImpl implements Serializable { return true; } + + public SQLCaseExpr clone() { + SQLCaseExpr x = new SQLCaseExpr(); + + for (Item item : items) { + x.addItem(item.clone()); + } + + if (valueExpr != null) { + x.setValueExpr(valueExpr.clone()); + } + + if (elseExpr != null) { + x.setElseExpr(elseExpr.clone()); + } + + return x; + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLNCharExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLNCharExpr.java index aab1712377..af245da2b0 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLNCharExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLNCharExpr.java @@ -42,4 +42,8 @@ public class SQLNCharExpr extends SQLTextLiteralExpr { visitor.visit(this); visitor.endVisit(this); } + + public SQLNCharExpr clone() { + return new SQLNCharExpr(text); + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLNotExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLNotExpr.java index f98753a41c..804f48f2a5 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLNotExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLNotExpr.java @@ -86,4 +86,12 @@ public class SQLNotExpr extends SQLExprImpl implements Serializable { } return true; } + + public SQLNotExpr clone() { + SQLNotExpr x = new SQLNotExpr(); + if (expr != null) { + x.setExpr(expr.clone()); + } + return x; + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLNullExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLNullExpr.java index 7fd0699d71..f6dfeba62a 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLNullExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLNullExpr.java @@ -48,4 +48,8 @@ public class SQLNullExpr extends SQLExprImpl implements SQLLiteralExpr, SQLValua public Object getValue() { return EVAL_VALUE_NULL; } + + public SQLNullExpr clone() { + return new SQLNullExpr(); + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLNumberExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLNumberExpr.java index 64679a5480..5da4ec4b0a 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLNumberExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLNumberExpr.java @@ -76,4 +76,8 @@ public class SQLNumberExpr extends SQLNumericLiteralExpr { } return true; } + + public SQLNumberExpr clone() { + return new SQLNumberExpr(number); + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLPropertyExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLPropertyExpr.java index dcb990efd3..78ddb9b166 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLPropertyExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLPropertyExpr.java @@ -47,6 +47,14 @@ public class SQLPropertyExpr extends SQLExprImpl implements SQLName { return this.owner; } + public String getOwnernName() { + if (owner instanceof SQLIdentifierExpr) { + return ((SQLIdentifierExpr) owner).getName(); + } + + return null; + } + public void setOwner(SQLExpr owner) { if (owner != null) { owner.setParent(this); @@ -123,4 +131,11 @@ public class SQLPropertyExpr extends SQLExprImpl implements SQLName { return propertyExpr; } + public boolean matchOwner(String alias) { + if (owner instanceof SQLIdentifierExpr) { + return ((SQLIdentifierExpr) owner).getName().equalsIgnoreCase(alias); + } + + return false; + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLColumnDefinition.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLColumnDefinition.java index e57fc5c923..33f6f6fd9c 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLColumnDefinition.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLColumnDefinition.java @@ -18,6 +18,7 @@ package com.alibaba.druid.sql.ast.statement; import java.util.ArrayList; import java.util.List; +import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLDataType; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLName; @@ -271,14 +272,6 @@ public class SQLColumnDefinition extends SQLObjectImpl implements SQLTableElemen alias = ((SQLPropertyExpr) name).getName(); } - if (alias.length() > 2) { - char c0 = alias.charAt(0); - char x0 = alias.charAt(alias.length() - 1); - if ((c0 == '"' && x0 == '"') || (c0 == '`' && x0 == '`')) { - alias = alias.substring(1, alias.length() - 1); - } - } - - return alias; + return SQLUtils.normalize(alias); } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java index d857b9230f..c551cd119a 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java @@ -19,9 +19,14 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLStatementImpl; +import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlTableIndex; import com.alibaba.druid.sql.visitor.SQLASTVisitor; +import com.alibaba.druid.stat.TableStat; public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLStatement { @@ -152,5 +157,60 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS return !comments.isEmpty(); } - + + public String computeName() { + if (tableSource == null) { + return null; + } + + SQLExpr expr = tableSource.getExpr(); + if (expr instanceof SQLName) { + String name = ((SQLName) expr).getSimpleName(); + return SQLUtils.normalize(name); + } + + return null; + } + + public SQLColumnDefinition findColumn(String columName) { + for (SQLTableElement element : tableElementList) { + if (element instanceof SQLColumnDefinition) { + SQLColumnDefinition column = (SQLColumnDefinition) element; + String name = column.computeAlias(); + if (columName.equalsIgnoreCase(name)) { + return column; + } + } + } + + return null; + } + + public SQLTableElement findKey(String columnName) { + for (SQLTableElement element : tableElementList) { + List keyColumns = null; + if (element instanceof SQLUniqueConstraint) { + SQLUniqueConstraint unique = (SQLUniqueConstraint) element; + keyColumns = unique.getColumns(); + } else if (element instanceof MySqlTableIndex) { + keyColumns = ((MySqlTableIndex) element).getColumns(); + } + + if (keyColumns == null) { + continue; + } + + for (SQLExpr columnExpr : keyColumns) { + if (columnExpr instanceof SQLIdentifierExpr) { + String keyColumName = ((SQLIdentifierExpr) columnExpr).getName(); + keyColumName = SQLUtils.normalize(keyColumName); + if (keyColumName.equalsIgnoreCase(columnName)) { + return element; + } + } + } + } + + return null; + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLExprTableSource.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLExprTableSource.java index 93b3a10e7b..9c0bcde895 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLExprTableSource.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLExprTableSource.java @@ -18,6 +18,7 @@ package com.alibaba.druid.sql.ast.statement; import java.util.ArrayList; import java.util.List; +import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.visitor.SQLASTVisitor; @@ -117,15 +118,7 @@ public class SQLExprTableSource extends SQLTableSourceImpl { } } - if (alias.length() > 2) { - char c0 = alias.charAt(0); - char x0 = alias.charAt(alias.length() - 1); - if ((c0 == '"' && x0 == '"') || (c0 == '`' && x0 == '`')) { - alias = alias.substring(1, alias.length() - 1); - } - } - - return alias; + return SQLUtils.normalize(alias); } public SQLExprTableSource clone() { @@ -135,6 +128,8 @@ public class SQLExprTableSource extends SQLTableSourceImpl { } public void cloneTo(SQLExprTableSource x) { + x.alias = alias; + if (expr != null) { x.expr = expr.clone(); } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLJoinTableSource.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLJoinTableSource.java index 1a3bb06d3b..c1960de721 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLJoinTableSource.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLJoinTableSource.java @@ -165,4 +165,33 @@ public class SQLJoinTableSource extends SQLTableSourceImpl { return joinType.name; } } + + + public void cloneTo(SQLJoinTableSource x) { + x.alias = alias; + + if (left != null) { + x.setLeft(left.clone()); + } + + x.joinType = joinType; + + if (right != null) { + x.setRight(right.clone()); + } + + for (SQLExpr item : using) { + SQLExpr item2 = item.clone(); + item2.setParent(x); + x.using.add(item2); + } + + x.natural = natural; + } + + public SQLJoinTableSource clone() { + SQLJoinTableSource x = new SQLJoinTableSource(); + cloneTo(x); + return x; + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelect.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelect.java index 2d288950d6..701a6f55da 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelect.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelect.java @@ -33,7 +33,7 @@ public class SQLSelect extends SQLObjectImpl { protected SQLObject restriction; protected boolean forBrowse; - protected List forXmlOptions = new ArrayList(4); + protected List forXmlOptions = null; protected SQLExpr xmlPath; protected SQLExpr rowCount; @@ -148,7 +148,7 @@ public class SQLSelect extends SQLObjectImpl { x.withSubQuery = this.withSubQuery; x.query = this.query; if (orderBy != null) { - x.setOrderBy(this.orderBy); + x.setOrderBy(this.orderBy.clone()); } if (restriction != null) { x.setRestriction(restriction.clone()); @@ -160,9 +160,39 @@ public class SQLSelect extends SQLObjectImpl { } } + x.forBrowse = forBrowse; + + if (forXmlOptions != null) { + x.forXmlOptions = new ArrayList(forXmlOptions); + } + + if (xmlPath != null) { + x.setXmlPath(xmlPath.clone()); + } + + if (rowCount != null) { + x.setRowCount(rowCount.clone()); + } + + if (offset != null) { + x.setOffset(offset.clone()); + } + return x; } + public boolean isSimple() { + return withSubQuery == null + && orderBy == null + && (hints == null || hints.size() == 0) + && restriction == null + && (!forBrowse) + && (forXmlOptions == null || forXmlOptions.size() == 0) + && xmlPath == null + && rowCount == null + && offset == null; + } + public SQLObject getRestriction() { return this.restriction; } @@ -183,11 +213,18 @@ public class SQLSelect extends SQLObjectImpl { } public List getForXmlOptions() { + if (forXmlOptions == null) { + forXmlOptions = new ArrayList(4); + } + return forXmlOptions; } - public void setForXmlOptions(List forXmlOptions) { - this.forXmlOptions = forXmlOptions; + public int getForXmlOptionsSize() { + if (forXmlOptions == null) { + return 0; + } + return forXmlOptions.size(); } public SQLExpr getRowCount() { diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectItem.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectItem.java index 65774dacfc..576596457d 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectItem.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectItem.java @@ -15,6 +15,7 @@ */ package com.alibaba.druid.sql.ast.statement; +import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLObjectImpl; import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; @@ -75,15 +76,7 @@ public class SQLSelectItem extends SQLObjectImpl { } } - if (alias.length() > 2) { - char c0 = alias.charAt(0); - char x0 = alias.charAt(alias.length() - 1); - if ((c0 == '"' && x0 == '"') || (c0 == '`' && x0 == '`')) { - alias = alias.substring(1, alias.length() - 1); - } - } - - return alias; + return SQLUtils.normalize(alias); } public String getAlias() { diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectOrderByItem.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectOrderByItem.java index ce8ebf0b33..dacf07538a 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectOrderByItem.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectOrderByItem.java @@ -119,4 +119,15 @@ public class SQLSelectOrderByItem extends SQLObjectImpl { throw new IllegalArgumentException(); } } + + public SQLSelectOrderByItem clone() { + SQLSelectOrderByItem x = new SQLSelectOrderByItem(); + if (expr != null) { + x.setExpr(expr.clone()); + } + x.collate = collate; + x.type = type; + x.nullsOrderType = nullsOrderType; + return x; + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectQueryBlock.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectQueryBlock.java index 245576a67c..c453e227b5 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectQueryBlock.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectQueryBlock.java @@ -318,11 +318,11 @@ public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery public SQLSelectQueryBlock clone() { SQLSelectQueryBlock x = new SQLSelectQueryBlock(); - clone(x); + cloneTo(x); return x; } - public void clone(SQLSelectQueryBlock x) { + public void cloneTo(SQLSelectQueryBlock x) { x.distionOption = distionOption; diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSubqueryTableSource.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSubqueryTableSource.java index 099251e63e..42bddfffe4 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSubqueryTableSource.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSubqueryTableSource.java @@ -69,6 +69,9 @@ public class SQLSubqueryTableSource extends SQLTableSourceImpl { public SQLSubqueryTableSource clone() { SQLSubqueryTableSource x = new SQLSubqueryTableSource(); + + x.alias = alias; + if (select != null) { x.select = select.clone(); } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLTableSource.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLTableSource.java index 2b5455c385..587bc57a6f 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLTableSource.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLTableSource.java @@ -29,4 +29,6 @@ public interface SQLTableSource extends SQLObject { List getHints(); SQLTableSource clone(); + + String computeAlias(); } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLTableSourceImpl.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLTableSourceImpl.java index ba384ebf77..4a91a47265 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLTableSourceImpl.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLTableSourceImpl.java @@ -64,7 +64,11 @@ public abstract class SQLTableSourceImpl extends SQLObjectImpl implements SQLTab } public SQLTableSource clone() { - throw new UnsupportedOperationException(); + throw new UnsupportedOperationException(this.getClass().getName()); + } + + public String computeAlias() { + return alias; } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectJoin.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectJoin.java index 663e3d52e7..c12cd6a827 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectJoin.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectJoin.java @@ -113,4 +113,19 @@ public class OracleSelectJoin extends SQLJoinTableSource implements OracleSelect public String toString () { return SQLUtils.toOracleString(this); } + + public SQLJoinTableSource clone() { + OracleSelectJoin x = new OracleSelectJoin(); + cloneTo(x); + + if (pivot != null) { + x.setPivot(pivot.clone()); + } + + if (flashback != null) { + x.setFlashback(flashback.clone()); + } + + return x; + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectQueryBlock.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectQueryBlock.java index 5afebb7c4c..f260fcf0eb 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectQueryBlock.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectQueryBlock.java @@ -28,32 +28,36 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor; public class OracleSelectQueryBlock extends SQLSelectQueryBlock { - private final List hints = new ArrayList(1); + private List hints; private ModelClause modelClause; - private final List forUpdateOf = new ArrayList(1); + private List forUpdateOf; private boolean skipLocked = false; public OracleSelectQueryBlock clone() { OracleSelectQueryBlock x = new OracleSelectQueryBlock(); - super.clone(x); + super.cloneTo(x); - for (SQLCommentHint hint : hints) { - SQLCommentHint hint1 = hint.clone(); - hint1.setParent(x); - x.getHints().add(hint1); + if (hints != null) { + for (SQLCommentHint hint : hints) { + SQLCommentHint hint1 = hint.clone(); + hint1.setParent(x); + x.getHints().add(hint1); + } } if (modelClause != null) { x.setModelClause(modelClause.clone()); } - for (SQLExpr item : forUpdateOf) { - SQLExpr item1 = item.clone(); - item1.setParent(x); - forUpdateOf.add(item1); + if (forUpdateOf != null) { + for (SQLExpr item : forUpdateOf) { + SQLExpr item1 = item.clone(); + item1.setParent(x); + forUpdateOf.add(item1); + } } x.skipLocked = skipLocked; @@ -74,13 +78,35 @@ public class OracleSelectQueryBlock extends SQLSelectQueryBlock { } public List getHints() { + if (hints == null) { + hints = new ArrayList(1); + } return this.hints; } + public int getHintsSize() { + if (hints == null) { + return 0; + } + + return hints.size(); + } + public List getForUpdateOf() { + if (forUpdateOf == null) { + forUpdateOf = new ArrayList(1); + } return forUpdateOf; } + public int getForUpdateOfSize() { + if (forUpdateOf == null) { + return 0; + } + + return forUpdateOf.size(); + } + public boolean isSkipLocked() { return skipLocked; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectTableReference.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectTableReference.java index 54f3970133..caa689fac2 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectTableReference.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectTableReference.java @@ -34,31 +34,6 @@ public class OracleSelectTableReference extends SQLExprTableSource implements Or protected FlashbackQueryClause flashback; - public OracleSelectTableReference clone() { - OracleSelectTableReference x = new OracleSelectTableReference(); - cloneTo(x); - - x.only = only; - - if (pivot != null) { - x.setPivot(pivot.clone()); - } - - if (partition != null) { - x.setPartition(partition.clone()); - } - - if (sampleClause != null) { - x.setSampleClause(sampleClause.clone()); - } - - if (flashback != null) { - setFlashback(flashback.clone()); - } - - return x; - } - public OracleSelectTableReference(){ } @@ -167,4 +142,29 @@ public class OracleSelectTableReference extends SQLExprTableSource implements Or return SQLUtils.toOracleString(this); } + + public OracleSelectTableReference clone() { + OracleSelectTableReference x = new OracleSelectTableReference(); + cloneTo(x); + + x.only = only; + + if (pivot != null) { + x.setPivot(pivot.clone()); + } + + if (partition != null) { + x.setPartition(partition.clone()); + } + + if (sampleClause != null) { + x.setSampleClause(sampleClause.clone()); + } + + if (flashback != null) { + setFlashback(flashback.clone()); + } + + return x; + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java index 1738cc1824..5e81dbf773 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java @@ -807,7 +807,7 @@ public class OracleStatementParser extends SQLStatementParser { return stmt; } - SQLBlockStatement block = this.parseBlock(); + SQLStatement block = this.parseBlock(); stmt.setBlock(block); @@ -1460,7 +1460,7 @@ public class OracleStatementParser extends SQLStatementParser { return stmt; } - public SQLBlockStatement parseBlock() { + public SQLStatement parseBlock() { SQLBlockStatement block = new SQLBlockStatement(); block.setDbType(JdbcConstants.ORACLE); @@ -1475,6 +1475,15 @@ public class OracleStatementParser extends SQLStatementParser { } } + if (lexer.token() == Token.PROCEDURE) { + SQLCreateProcedureStatement stmt = this.parseCreateProcedure(); + for (SQLParameter param : block.getParameters()) { + param.setParent(stmt); + stmt.getParameters().add(param); + } + return stmt; + } + accept(Token.BEGIN); parseStatementList(block.getStatementList(), -1, block); @@ -2113,7 +2122,7 @@ public class OracleStatementParser extends SQLStatementParser { return stmt; } - SQLBlockStatement block = this.parseBlock(); + SQLStatement block = this.parseBlock(); stmt.setBlock(block); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java index 7503d7934b..5c05c15503 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java @@ -383,7 +383,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS public boolean visit(OracleSelectQueryBlock x) { print0(ucase ? "SELECT " : "select "); - if (x.getHints().size() > 0) { + if (x.getHintsSize() > 0) { printAndAccept(x.getHints(), ", "); print(' '); } @@ -437,7 +437,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS if (x.isForUpdate()) { println(); print0(ucase ? "FOR UPDATE" : "for update"); - if (x.getForUpdateOf().size() > 0) { + if (x.getForUpdateOfSize() > 0) { print('('); printAndAccept(x.getForUpdateOf(), ", "); print(')'); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerOutputVisitor.java index 09edce5b7c..4829d330a3 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerOutputVisitor.java @@ -423,7 +423,7 @@ public class SQLServerOutputVisitor extends SQLASTOutputVisitor implements SQLSe print0(ucase ? "FOR BROWSE" : "for browse"); } - if (x.getForXmlOptions().size() > 0) { + if (x.getForXmlOptionsSize() > 0) { println(); print0(ucase ? "FOR XML " : "for xml "); for (int i = 0; i < x.getForXmlOptions().size(); ++i) { diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java index 9d2b5366f2..0ca06aad23 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.*; import com.alibaba.druid.sql.ast.expr.*; import com.alibaba.druid.sql.ast.statement.SQLNotNullConstraint; @@ -822,8 +823,10 @@ public class SQLExprParser extends SQLParser { methodInvokeExpr = new SQLMethodInvokeExpr(methodName); } - if (isAggreateFunction(methodName)) { - SQLAggregateExpr aggregateExpr = parseAggregateExpr(methodName); + String aggMethodName = SQLUtils.normalize(methodName); + + if (isAggreateFunction(aggMethodName)) { + SQLAggregateExpr aggregateExpr = parseAggregateExpr(aggMethodName); if (distinct) { aggregateExpr.setOption(SQLAggregateOption.DISTINCT); } 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 6816c6ef25..682254dd25 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java @@ -18,15 +18,8 @@ package com.alibaba.druid.sql.visitor; import java.util.ArrayList; import java.util.List; -import com.alibaba.druid.sql.ast.SQLDataType; -import com.alibaba.druid.sql.ast.SQLExpr; -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.SQLIntegerExpr; -import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr; -import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; +import com.alibaba.druid.sql.ast.*; +import com.alibaba.druid.sql.ast.expr.*; import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition; import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem; import com.alibaba.druid.sql.dialect.db2.visitor.DB2OutputVisitor; @@ -38,6 +31,7 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerTop; import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerOutputVisitor; import com.alibaba.druid.sql.parser.SQLParserUtils; import com.alibaba.druid.sql.parser.SQLStatementParser; +import com.alibaba.druid.util.JdbcConstants; import com.alibaba.druid.util.JdbcUtils; public class ParameterizedOutputVisitorUtils { diff --git a/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedVisitor.java index 6e71a1ef41..4926e68e48 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedVisitor.java @@ -21,4 +21,6 @@ public interface ParameterizedVisitor extends PrintableVisitor { void incrementReplaceCunt(); + String getDbType(); + } 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 d4708a9160..a3610938d0 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -251,16 +251,25 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet protected void printSelectList(List selectList) { incrementIndent(); - for (int i = 0, size = selectList.size(); i < size; ++i) { + for (int i = 0, lineItemCount = 0, size = selectList.size() + ; i < size; ++i, ++lineItemCount) { + SQLSelectItem selectItem = selectList.get(i); + SQLExpr selectItemExpr = selectItem.getExpr(); if (i != 0) { - if (i % selectListNumberOfLine == 0) { + if (lineItemCount == selectListNumberOfLine + || selectItemExpr instanceof SQLQueryExpr) { + lineItemCount = 0; println(); } print0(", "); } - selectList.get(i).accept(this); + if (selectItem.getClass() == SQLSelectItem.class) { + this.visit(selectItem); + } else { + selectItem.accept(this); + } } decrementIndent(); } @@ -623,8 +632,8 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet incrementIndent(); println(); x.getSubQuery().accept(this); - println(); decrementIndent(); + println(); print(')'); return false; } @@ -816,6 +825,23 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet } public boolean visit(SQLIntegerExpr x) { + int val = x.getNumber().intValue(); + if (val == 1 + && JdbcConstants.ORACLE.equals(dbType)) { + SQLObject parent = x.getParent(); + if (parent instanceof SQLBinaryOpExpr) { + SQLBinaryOpExpr binaryOpExpr = (SQLBinaryOpExpr) parent; + SQLExpr left = binaryOpExpr.getLeft(); + if (left instanceof SQLIdentifierExpr + && binaryOpExpr.getOperator() == SQLBinaryOperator.Equality) { + String name = ((SQLIdentifierExpr) left).getName(); + if ("rownum".equals(name)) { + print(1); + return false; + } + } + } + } if (this.parameterized && ParameterizedOutputVisitorUtils.checkParameterize(x)) { if (!ParameterizedOutputVisitorUtils.checkParameterize(x)) { @@ -1074,8 +1100,8 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet incrementIndent(); println(); x.getSubQuery().accept(this); - println(); decrementIndent(); + println(); print(')'); } return false; @@ -1984,22 +2010,28 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet print(' '); SQLTableSource right = x.getRight(); - boolean isSubquery = false; - - if(right instanceof SQLSubqueryTableSource) { - isSubquery = true; - } right.accept(this); - if (x.getCondition() != null) { - if (isSubquery) { + SQLExpr condition = x.getCondition(); + if (condition != null) { + boolean newLine = false; + + if(right instanceof SQLSubqueryTableSource) { + newLine = true; + } else if (condition instanceof SQLBinaryOpExpr) { + SQLBinaryOperator op = ((SQLBinaryOpExpr) condition).getOperator(); + if (op == SQLBinaryOperator.BooleanAnd || op == SQLBinaryOperator.BooleanOr) { + newLine = true; + } + } + if (newLine) { println(); } else { print(' '); } incrementIndent(); print0(ucase ? "ON " : "on "); - x.getCondition().accept(this); + condition.accept(this); decrementIndent(); } @@ -2090,8 +2122,10 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet } incrementIndent(); + println(); x.getSubQuery().accept(this); decrementIndent(); + println(); print(')'); return false; diff --git a/src/main/java/com/alibaba/druid/util/JdbcUtils.java b/src/main/java/com/alibaba/druid/util/JdbcUtils.java index 5bea647226..6c080c1c67 100644 --- a/src/main/java/com/alibaba/druid/util/JdbcUtils.java +++ b/src/main/java/com/alibaba/druid/util/JdbcUtils.java @@ -15,8 +15,10 @@ */ package com.alibaba.druid.util; +import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.support.logging.Log; import com.alibaba.druid.support.logging.LogFactory; +import com.fasterxml.jackson.databind.ObjectMapper; import javax.sql.DataSource; import java.io.Closeable; @@ -740,4 +742,31 @@ public final class JdbcUtils implements JdbcConstants { return sql.toString(); } + + public static void executeQuery(DataSource dataSource + , ResultSetConsumer consumer + , String sql + , Object... parameters) throws SQLException { + Connection conn = null; + PreparedStatement stmt = null; + ResultSet rs = null; + try { + conn = dataSource.getConnection(); + stmt = conn.prepareStatement(sql); + for (int i = 0; i < parameters.length; ++i) { + stmt.setObject(i + 1, parameters[i]); + } + rs = stmt.executeQuery(); + while (rs.next()) { + if (consumer != null) { + T object = consumer.apply(rs); + consumer.accept(object); + } + } + } finally { + close(rs); + close(stmt); + close(conn); + } + } } diff --git a/src/main/java/com/alibaba/druid/util/ResultSetConsumer.java b/src/main/java/com/alibaba/druid/util/ResultSetConsumer.java new file mode 100644 index 0000000000..a28fd1b60c --- /dev/null +++ b/src/main/java/com/alibaba/druid/util/ResultSetConsumer.java @@ -0,0 +1,27 @@ +/* + * Copyright 1999-2017 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.druid.util; + +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * Created by wenshao on 03/06/2017. + */ +public interface ResultSetConsumer { + T apply(ResultSet rs) throws SQLException; + void accept(T object); +} diff --git a/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java b/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java index 4342961819..ab5c48eb33 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java @@ -120,7 +120,7 @@ public class WallVisitorUtils { public static boolean check(WallVisitor visitor, SQLBinaryOpExpr x) { if (x.getOperator() == SQLBinaryOperator.BooleanOr || x.getOperator() == SQLBinaryOperator.BooleanAnd) { - List groupList = SQLUtils.split(x); + List groupList = SQLBinaryOpExpr.split(x); for (SQLExpr item : groupList) { item.accept(visitor); } @@ -128,7 +128,7 @@ public class WallVisitorUtils { } if (x.getOperator() == SQLBinaryOperator.Add || x.getOperator() == SQLBinaryOperator.Concat) { - List groupList = SQLUtils.split(x); + List groupList = SQLBinaryOpExpr.split(x); if (groupList.size() >= 4) { int chrCount = 0; for (int i = 0; i < groupList.size(); ++i) { @@ -922,7 +922,7 @@ public class WallVisitorUtils { public static Object getValue(WallVisitor visitor, SQLBinaryOpExpr x) { if (x.getOperator() == SQLBinaryOperator.BooleanOr) { - List groupList = SQLUtils.split(x); + List groupList = SQLBinaryOpExpr.split(x); boolean allFalse = true; for (int i = groupList.size() - 1; i >= 0; --i) { @@ -951,7 +951,7 @@ public class WallVisitorUtils { if (x.getOperator() == SQLBinaryOperator.BooleanAnd) { - List groupList = SQLUtils.split(x); + List groupList = SQLBinaryOpExpr.split(x); int dalConst = 0; Boolean allTrue = Boolean.TRUE; diff --git a/src/test/java/com/alibaba/druid/bvt/sql/SplitTest.java b/src/test/java/com/alibaba/druid/bvt/sql/SplitTest.java new file mode 100644 index 0000000000..61f58e20af --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/SplitTest.java @@ -0,0 +1,31 @@ +package com.alibaba.druid.bvt.sql; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; +import com.alibaba.druid.sql.parser.SQLExprParser; +import junit.framework.TestCase; + +import java.util.List; + +/** + * Created by wenshao on 04/06/2017. + */ +public class SplitTest extends TestCase { + public void test_0() throws Exception { + String sql = "((1 + 2) + (3 + 4) + 5) + ((6 + 7) + (8 + 9) + 10)"; +// sql = "(1 + 2) + (3 + 4)"; + SQLBinaryOpExpr expr = (SQLBinaryOpExpr) new SQLExprParser(sql).expr(); + + List items = SQLBinaryOpExpr.split(expr); + + System.out.println(sql); + System.out.println(items); + + assertEquals(10, items.size()); + for (int i = 0; i < 10; ++i) { + SQLExpr item = items.get(i); + assertEquals(Integer.toString(i + 1), SQLUtils.toSQLString(item)); + } + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/SplitTest2.java b/src/test/java/com/alibaba/druid/bvt/sql/SplitTest2.java new file mode 100644 index 0000000000..a26310a5bc --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/SplitTest2.java @@ -0,0 +1,40 @@ +package com.alibaba.druid.bvt.sql; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; +import com.alibaba.druid.sql.parser.SQLExprParser; +import junit.framework.TestCase; + +import java.util.List; + +/** + * Created by wenshao on 04/06/2017. + */ +public class SplitTest2 extends TestCase { + public void test_0() throws Exception { + int count = 10; + String sql = ""; + + for (int i = 0; i < count; ++i) { + if (sql.length() != 0) { + sql += " + "; + } + + sql += Integer.toString(i); + } +// sql = "(1 + 2) + (3 + 4)"; + SQLBinaryOpExpr expr = (SQLBinaryOpExpr) new SQLExprParser(sql).expr(); + + List items = SQLBinaryOpExpr.split(expr); + + System.out.println(sql); + System.out.println(items); + + assertEquals(count, items.size()); + for (int i = 0; i < count; ++i) { + SQLExpr item = items.get(i); + assertEquals(Integer.toString(i ), SQLUtils.toSQLString(item)); + } + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/db2/DB2SelectTest_11.java b/src/test/java/com/alibaba/druid/bvt/sql/db2/DB2SelectTest_11.java index 08ef3742b8..a94d1ad135 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/db2/DB2SelectTest_11.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/db2/DB2SelectTest_11.java @@ -69,32 +69,36 @@ public class DB2SelectTest_11 extends DB2Test { // Assert.assertTrue(visitor.getColumns().contains(new Column("mytable", "first_name"))); // Assert.assertTrue(visitor.getColumns().contains(new Column("mytable", "full_name"))); - Assert.assertEquals("SELECT A.F_0201, A.F_0301, A.F_0802, A.F_2100" - + "\nFROM A, B" - + "\nWHERE B.F_2211 = '5'" - + "\n\tAND A.F_0301 = B.F_0301" - + "\n\tAND (Substr(B.F_0815, 1, 4) CONCAT Substr(B.F_0815, 5, 2)) > A.F_0802" - + "\n\tAND A.F_2100 > 0" - + "\nUNION" - + "\nSELECT A.F_0201, A.F_0301, A.F_0802, A.F_2100" - + "\nFROM A" - + "\nWHERE A.F_0301 NOT IN (SELECT F_0301" - + "\n\t\tFROM B)" - + "\n\tAND A.F_2100 > 0", // + Assert.assertEquals("SELECT A.F_0201, A.F_0301, A.F_0802, A.F_2100\n" + + "FROM A, B\n" + + "WHERE B.F_2211 = '5'\n" + + "\tAND A.F_0301 = B.F_0301\n" + + "\tAND (Substr(B.F_0815, 1, 4) CONCAT Substr(B.F_0815, 5, 2)) > A.F_0802\n" + + "\tAND A.F_2100 > 0\n" + + "UNION\n" + + "SELECT A.F_0201, A.F_0301, A.F_0802, A.F_2100\n" + + "FROM A\n" + + "WHERE A.F_0301 NOT IN (\n" + + "\t\tSELECT F_0301\n" + + "\t\tFROM B\n" + + "\t)\n" + + "\tAND A.F_2100 > 0", // SQLUtils.toSQLString(stmt, JdbcConstants.DB2)); - Assert.assertEquals("select A.F_0201, A.F_0301, A.F_0802, A.F_2100" - + "\nfrom A, B" - + "\nwhere B.F_2211 = '5'" - + "\n\tand A.F_0301 = B.F_0301" - + "\n\tand (Substr(B.F_0815, 1, 4) concat Substr(B.F_0815, 5, 2)) > A.F_0802" - + "\n\tand A.F_2100 > 0" - + "\nunion" - + "\nselect A.F_0201, A.F_0301, A.F_0802, A.F_2100" - + "\nfrom A" - + "\nwhere A.F_0301 not in (select F_0301" - + "\n\t\tfrom B)" - + "\n\tand A.F_2100 > 0", // + assertEquals("select A.F_0201, A.F_0301, A.F_0802, A.F_2100\n" + + "from A, B\n" + + "where B.F_2211 = '5'\n" + + "\tand A.F_0301 = B.F_0301\n" + + "\tand (Substr(B.F_0815, 1, 4) concat Substr(B.F_0815, 5, 2)) > A.F_0802\n" + + "\tand A.F_2100 > 0\n" + + "union\n" + + "select A.F_0201, A.F_0301, A.F_0802, A.F_2100\n" + + "from A\n" + + "where A.F_0301 not in (\n" + + "\t\tselect F_0301\n" + + "\t\tfrom B\n" + + "\t)\n" + + "\tand A.F_2100 > 0", // SQLUtils.toSQLString(stmt, JdbcConstants.DB2, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); } } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlDeleteTest_3.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlDeleteTest_3.java index e470a13403..952a663ba4 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlDeleteTest_3.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlDeleteTest_3.java @@ -58,8 +58,8 @@ public class MySqlDeleteTest_3 extends MysqlTest { "\t\t\t\t\tSELECT *\n" + "\t\t\t\t\tFROM t5\n" + "\t\t\t\t) t5)\n" + - "\t\t\t\t)\n" + "\t\t\t)\n" + + "\t\t)\n" + "\t)", SQLUtils.toMySqlString(stmt)); assertEquals("delete from t1\n" + "where s11 > any (\n" + @@ -77,8 +77,8 @@ public class MySqlDeleteTest_3 extends MysqlTest { "\t\t\t\t\tselect *\n" + "\t\t\t\t\tfrom t5\n" + "\t\t\t\t) t5)\n" + - "\t\t\t\t)\n" + "\t\t\t)\n" + + "\t\t)\n" + "\t)", SQLUtils.toMySqlString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); Assert.assertEquals(1, statementList.size()); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlFormatTest2.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlFormatTest2.java index 7b7f89993d..3910b24da8 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlFormatTest2.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlFormatTest2.java @@ -35,7 +35,7 @@ public class MySqlFormatTest2 extends TestCase { + "\n\t\tFROM ce_queue cq2" + "\n\t\tWHERE cq.component_uuid = cq2.component_uuid" + "\n\t\t\tAND cq2.status <> ?" - + "\n\t\t)" + + "\n\t)" + "\nORDER BY cq.created_at ASC, cq.id ASC", SQLUtils.format(text, JdbcUtils.MYSQL)); } } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/SELECT_Syntax_Test.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/SELECT_Syntax_Test.java index e4c5429641..f8376f3a66 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/mysql/SELECT_Syntax_Test.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/SELECT_Syntax_Test.java @@ -117,7 +117,12 @@ public class SELECT_Syntax_Test extends TestCase { String text = output(stmtList); - Assert.assertEquals("SELECT *\nFROM t1\nWHERE column1 = (\n\tSELECT column1\n\tFROM t2\n\t);", text); + assertEquals("SELECT *\n" + + "FROM t1\n" + + "WHERE column1 = (\n" + + "\tSELECT column1\n" + + "\tFROM t2\n" + + ");", text); } public void test_7() throws Exception { @@ -133,7 +138,7 @@ public class SELECT_Syntax_Test extends TestCase { + "\nWHERE EXISTS (" // + "\n\tSELECT *" // + "\n\tFROM t2" - + "\n\t);", text); + + "\n);", text); } public void test_8() throws Exception { @@ -150,7 +155,7 @@ public class SELECT_Syntax_Test extends TestCase { + "\n\tSELECT *" + "\n\tFROM cities_stores" + "\n\tWHERE cities_stores.store_type = stores.store_type" - + "\n\t);", + + "\n);", text); } @@ -209,8 +214,18 @@ public class SELECT_Syntax_Test extends TestCase { List stmtList = parser.parseStatementList(); SQLStatement stmt = stmtList.get(0); - Assert.assertEquals("SELECT s1\nFROM t1\nWHERE s1 NOT IN (SELECT s1\n\tFROM t2)", SQLUtils.toMySqlString(stmt)); - Assert.assertEquals("select s1\nfrom t1\nwhere s1 not in (select s1\n\tfrom t2)", SQLUtils.toMySqlString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); + assertEquals("SELECT s1\n" + + "FROM t1\n" + + "WHERE s1 NOT IN (\n" + + "\tSELECT s1\n" + + "\tFROM t2\n" + + ")", SQLUtils.toMySqlString(stmt)); + assertEquals("select s1\n" + + "from t1\n" + + "where s1 not in (\n" + + "\tselect s1\n" + + "\tfrom t2\n" + + ")", SQLUtils.toMySqlString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); } public void test_13() throws Exception { @@ -220,8 +235,18 @@ public class SELECT_Syntax_Test extends TestCase { List stmtList = parser.parseStatementList(); SQLStatement stmt = stmtList.get(0); - Assert.assertEquals("SELECT s1\nFROM t1\nWHERE s1 IN (SELECT s1\n\tFROM t2)", SQLUtils.toMySqlString(stmt)); - Assert.assertEquals("select s1\nfrom t1\nwhere s1 in (select s1\n\tfrom t2)", SQLUtils.toMySqlString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); + assertEquals("SELECT s1\n" + + "FROM t1\n" + + "WHERE s1 IN (\n" + + "\tSELECT s1\n" + + "\tFROM t2\n" + + ")", SQLUtils.toMySqlString(stmt)); + assertEquals("select s1\n" + + "from t1\n" + + "where s1 in (\n" + + "\tselect s1\n" + + "\tfrom t2\n" + + ")", SQLUtils.toMySqlString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); } public void test_14() throws Exception { diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/create/MySqlCreateViewTest1.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/create/MySqlCreateViewTest1.java index 212bbe2459..b1ac818e88 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/mysql/create/MySqlCreateViewTest1.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/create/MySqlCreateViewTest1.java @@ -53,17 +53,17 @@ public class MySqlCreateViewTest1 extends MysqlTest { "\t\tFROM actvty_audit\n" + "\t\tWHERE enroll_id = a.enroll_id\n" + "\t\t\tAND rankjurisdiction = 1\n" + - "\t\t) > 0 THEN '县站已审核' ELSE NULL END AS 'countyAudit', CASE WHEN (\n" + + "\t) > 0 THEN '县站已审核' ELSE NULL END AS 'countyAudit', CASE WHEN (\n" + "\t\tSELECT audit\n" + "\t\tFROM actvty_audit\n" + "\t\tWHERE enroll_id = a.enroll_id\n" + "\t\t\tAND rankjurisdiction = 2\n" + - "\t\t) > 0 THEN '市馆已审核' ELSE NULL END AS 'cityAudit', CASE WHEN (\n" + + "\t) > 0 THEN '市馆已审核' ELSE NULL END AS 'cityAudit', CASE WHEN (\n" + "\t\tSELECT audit\n" + "\t\tFROM actvty_audit\n" + "\t\tWHERE enroll_id = a.enroll_id\n" + "\t\t\tAND rankjurisdiction = 3\n" + - "\t\t) > 0 THEN '省馆已审核' ELSE NULL END AS 'provinceAudit'\n" + + "\t) > 0 THEN '省馆已审核' ELSE NULL END AS 'provinceAudit'\n" + "FROM actvty_audit a\n" + "GROUP BY a.enroll_id", // SQLUtils.toMySqlString(stmt)); @@ -78,17 +78,17 @@ public class MySqlCreateViewTest1 extends MysqlTest { "\t\tfrom actvty_audit\n" + "\t\twhere enroll_id = a.enroll_id\n" + "\t\t\tand rankjurisdiction = 1\n" + - "\t\t) > 0 then '县站已审核' else null end as 'countyAudit', case when (\n" + + "\t) > 0 then '县站已审核' else null end as 'countyAudit', case when (\n" + "\t\tselect audit\n" + "\t\tfrom actvty_audit\n" + "\t\twhere enroll_id = a.enroll_id\n" + "\t\t\tand rankjurisdiction = 2\n" + - "\t\t) > 0 then '市馆已审核' else null end as 'cityAudit', case when (\n" + + "\t) > 0 then '市馆已审核' else null end as 'cityAudit', case when (\n" + "\t\tselect audit\n" + "\t\tfrom actvty_audit\n" + "\t\twhere enroll_id = a.enroll_id\n" + "\t\t\tand rankjurisdiction = 3\n" + - "\t\t) > 0 then '省馆已审核' else null end as 'provinceAudit'\n" + + "\t) > 0 then '省馆已审核' else null end as 'provinceAudit'\n" + "from actvty_audit a\n" + "group by a.enroll_id", // SQLUtils.toMySqlString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_30.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_30.java index 4195b6a677..6c619777a7 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_30.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_30.java @@ -32,7 +32,8 @@ public class MySqlParameterizedOutputVisitorTest_30 extends TestCase { "\t, `udata`.`status` AS `status`, `udata`.`charging_period` AS `chargingPeriod`, `udata`.`sn` AS `sn`, `udata`.`cpd` AS `chargingPeriodDesc`, `udata`.`task_total_num` AS `taskTotalNum`\n" + "\t, `udata`.`tcn` AS `taCoNu`, `udata`.`task_type` AS `taskType`, `udata`.`ilbu` AS `isLaBiUs`\n" + "FROM udata `udata`\n" + - "WHERE `udata`.`id` IN (SELECT MAX(`udata`.`id`)\n" + + "WHERE `udata`.`id` IN (\n" + + "\t\tSELECT MAX(`udata`.`id`)\n" + "\t\tFROM udata `udata`\n" + "\t\tWHERE `udata`.`uid` = ?\n" + "\t\t\tAND `udata`.`user_type` = ?\n" + @@ -41,7 +42,8 @@ public class MySqlParameterizedOutputVisitorTest_30 extends TestCase { "\t\t\tAND `udata`.`charging_period` = ?\n" + "\t\t\tAND `udata`.`task_type` = ?\n" + "\t\t\tAND `udata`.`task_total_num` <= `udata`.`tcn`\n" + - "\t\tGROUP BY `udata`.`charging_period`, `udata`.`start_period_time`, `udata`.`ept`)\n" + + "\t\tGROUP BY `udata`.`charging_period`, `udata`.`start_period_time`, `udata`.`ept`\n" + + "\t)\n" + "\tAND (`udata`.`uid` = ?\n" + "\t\tAND `udata`.`user_type` = ?)\n" + "ORDER BY `udata`.`start_period_time` DESC\n" + @@ -80,7 +82,8 @@ public class MySqlParameterizedOutputVisitorTest_30 extends TestCase { "\t, `udata`.`status` AS `status`, `udata`.`charging_period` AS `chargingPeriod`, `udata`.`sn` AS `sn`, `udata`.`cpd` AS `chargingPeriodDesc`, `udata`.`task_total_num` AS `taskTotalNum`\n" + "\t, `udata`.`tcn` AS `taCoNu`, `udata`.`task_type` AS `taskType`, `udata`.`ilbu` AS `isLaBiUs`\n" + "FROM udata_0888 `udata`\n" + - "WHERE `udata`.`id` IN (SELECT MAX(`udata`.`id`)\n" + + "WHERE `udata`.`id` IN (\n" + + "\t\tSELECT MAX(`udata`.`id`)\n" + "\t\tFROM udata_0888 `udata`\n" + "\t\tWHERE `udata`.`uid` = 1039100792\n" + "\t\t\tAND `udata`.`user_type` = 2\n" + @@ -89,7 +92,8 @@ public class MySqlParameterizedOutputVisitorTest_30 extends TestCase { "\t\t\tAND `udata`.`charging_period` = 1\n" + "\t\t\tAND `udata`.`task_type` = 1\n" + "\t\t\tAND `udata`.`task_total_num` <= `udata`.`tcn`\n" + - "\t\tGROUP BY `udata`.`charging_period`, `udata`.`start_period_time`, `udata`.`ept`)\n" + + "\t\tGROUP BY `udata`.`charging_period`, `udata`.`start_period_time`, `udata`.`ept`\n" + + "\t)\n" + "\tAND (`udata`.`uid` = '1039100792'\n" + "\t\tAND `udata`.`user_type` = 2)\n" + "ORDER BY `udata`.`start_period_time` DESC\n" + diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_31.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_31.java index b023bd1046..ab1218b03d 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_31.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_31.java @@ -29,7 +29,8 @@ public class MySqlParameterizedOutputVisitorTest_31 extends TestCase { "\t, `udata`.`status` AS `status`, `udata`.`charging_period` AS `chargingPeriod`, `udata`.`sn` AS `sn`, `udata`.`cpd` AS `chargingPeriodDesc`, `udata`.`task_total_num` AS `taskTotalNum`\n" + "\t, `udata`.`tcn` AS `taCoNu`, `udata`.`task_type` AS `taskType`, `udata`.`ilbu` AS `isLaBiUs`\n" + "FROM udata `udata`\n" + - "WHERE `udata`.`id` IN (SELECT MAX(`udata`.`id`)\n" + + "WHERE `udata`.`id` IN (\n" + + "\t\tSELECT MAX(`udata`.`id`)\n" + "\t\tFROM udata `udata`\n" + "\t\tWHERE `udata`.`uid` = ?\n" + "\t\t\tAND `udata`.`user_type` = ?\n" + @@ -38,7 +39,8 @@ public class MySqlParameterizedOutputVisitorTest_31 extends TestCase { "\t\t\tAND `udata`.`charging_period` = ?\n" + "\t\t\tAND `udata`.`task_type` = ?\n" + "\t\t\tAND `udata`.`task_total_num` <= `udata`.`tcn`\n" + - "\t\tGROUP BY `udata`.`charging_period`, `udata`.`start_period_time`, `udata`.`ept`)\n" + + "\t\tGROUP BY `udata`.`charging_period`, `udata`.`start_period_time`, `udata`.`ept`\n" + + "\t)\n" + "\tAND (`udata`.`uid` = ?\n" + "\t\tAND `udata`.`user_type` = ?)\n" + "ORDER BY `udata`.`start_period_time` DESC\n" + @@ -77,7 +79,8 @@ public class MySqlParameterizedOutputVisitorTest_31 extends TestCase { "\t, `udata`.`status` AS `status`, `udata`.`charging_period` AS `chargingPeriod`, `udata`.`sn` AS `sn`, `udata`.`cpd` AS `chargingPeriodDesc`, `udata`.`task_total_num` AS `taskTotalNum`\n" + "\t, `udata`.`tcn` AS `taCoNu`, `udata`.`task_type` AS `taskType`, `udata`.`ilbu` AS `isLaBiUs`\n" + "FROM udata_0888 `udata`\n" + - "WHERE `udata`.`id` IN (SELECT MAX(`udata`.`id`)\n" + + "WHERE `udata`.`id` IN (\n" + + "\t\tSELECT MAX(`udata`.`id`)\n" + "\t\tFROM udata_0888 `udata`\n" + "\t\tWHERE `udata`.`uid` = 1039100792\n" + "\t\t\tAND `udata`.`user_type` = 2\n" + @@ -86,7 +89,8 @@ public class MySqlParameterizedOutputVisitorTest_31 extends TestCase { "\t\t\tAND `udata`.`charging_period` = 1\n" + "\t\t\tAND `udata`.`task_type` = 1\n" + "\t\t\tAND `udata`.`task_total_num` <= `udata`.`tcn`\n" + - "\t\tGROUP BY `udata`.`charging_period`, `udata`.`start_period_time`, `udata`.`ept`)\n" + + "\t\tGROUP BY `udata`.`charging_period`, `udata`.`start_period_time`, `udata`.`ept`\n" + + "\t)\n" + "\tAND (`udata`.`uid` = '1039100792'\n" + "\t\tAND `udata`.`user_type` = 2)\n" + "ORDER BY `udata`.`start_period_time` DESC\n" + diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_14.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_14.java index a9e78ac472..bb9b683eb4 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_14.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_14.java @@ -61,12 +61,12 @@ public class MySqlSelectTest_14 extends MysqlTest { Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("t2"))); String output = SQLUtils.toMySqlString(stmt); - Assert.assertEquals("SELECT *" // - + "\nFROM t1"// - + "\nWHERE column1 = ("// - + "\n\tSELECT column1"// - + "\n\tFROM t2"// - + "\n\t)", // + Assert.assertEquals("SELECT *\n" + + "FROM t1\n" + + "WHERE column1 = (\n" + + "\tSELECT column1\n" + + "\tFROM t2\n" + + ")", // output); String output_lcase = SQLUtils.toMySqlString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION); @@ -75,7 +75,7 @@ public class MySqlSelectTest_14 extends MysqlTest { + "\nwhere column1 = ("// + "\n\tselect column1"// + "\n\tfrom t2"// - + "\n\t)", // + + "\n)", // output_lcase); } } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_29.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_29.java index 0d1b4ff49e..c4a01e104b 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_29.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_29.java @@ -55,24 +55,28 @@ public class MySqlSelectTest_29 extends MysqlTest { { String output = SQLUtils.toMySqlString(stmt); - Assert.assertEquals("SELECT *" - + "\nFROM Function" - + "\nWHERE Id IN (SELECT FunctionId" - + "\n\t\tFROM RoleFunction" - + "\n\t\tWHERE RoleId = '001'" - + "\n\t\t\tAND LogicalDel = 0)" - + "\n\tAND LogicalDel = 0", // + assertEquals("SELECT *\n" + + "FROM Function\n" + + "WHERE Id IN (\n" + + "\t\tSELECT FunctionId\n" + + "\t\tFROM RoleFunction\n" + + "\t\tWHERE RoleId = '001'\n" + + "\t\t\tAND LogicalDel = 0\n" + + "\t)\n" + + "\tAND LogicalDel = 0", // output); } { String output = SQLUtils.toMySqlString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION); - Assert.assertEquals("select *" - + "\nfrom Function" - + "\nwhere Id in (select FunctionId" - + "\n\t\tfrom RoleFunction" - + "\n\t\twhere RoleId = '001'" - + "\n\t\t\tand LogicalDel = 0)" - + "\n\tand LogicalDel = 0", // + assertEquals("select *\n" + + "from Function\n" + + "where Id in (\n" + + "\t\tselect FunctionId\n" + + "\t\tfrom RoleFunction\n" + + "\t\twhere RoleId = '001'\n" + + "\t\t\tand LogicalDel = 0\n" + + "\t)\n" + + "\tand LogicalDel = 0", // output); } } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest17.java b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest17.java index a5f80d3cee..69e1a501b3 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest17.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest17.java @@ -42,13 +42,14 @@ public class OdpsSelectTest17 extends TestCase { ") top )\n" + "ORDER BY cnt DESC\n" + "LIMIT 800";// - Assert.assertEquals("SELECT prov\n" + + assertEquals("SELECT prov\n" + "\t, name\n" + "\t, cnt\n" + "FROM mock_app.adl_mock_v_fct\n" + "WHERE ds = 20160920\n" + "\tAND name != 'none'\n" + - "\tAND prov IN (SELECT prov\n" + + "\tAND prov IN (\n" + + "\t\tSELECT prov\n" + "\t\tFROM (\n" + "\t\t\tSELECT prov\n" + "\t\t\t\t, SUM(cnt) AS cnt\n" + @@ -57,16 +58,18 @@ public class OdpsSelectTest17 extends TestCase { "\t\t\tGROUP BY prov\n" + "\t\t\tORDER BY cnt DESC\n" + "\t\t\tLIMIT 5\n" + - "\t\t) top)\n" + + "\t\t) top\n" + + "\t)\n" + "ORDER BY cnt DESC\n" + "LIMIT 800", SQLUtils.formatOdps(sql)); - Assert.assertEquals("select prov\n" + + assertEquals("select prov\n" + "\t, name\n" + "\t, cnt\n" + "from mock_app.adl_mock_v_fct\n" + "where ds = 20160920\n" + "\tand name != 'none'\n" + - "\tand prov in (select prov\n" + + "\tand prov in (\n" + + "\t\tselect prov\n" + "\t\tfrom (\n" + "\t\t\tselect prov\n" + "\t\t\t\t, sum(cnt) as cnt\n" + @@ -75,7 +78,8 @@ public class OdpsSelectTest17 extends TestCase { "\t\t\tgroup by prov\n" + "\t\t\torder by cnt desc\n" + "\t\t\tlimit 5\n" + - "\t\t) top)\n" + + "\t\t) top\n" + + "\t)\n" + "order by cnt desc\n" + "limit 800", SQLUtils.formatOdps(sql, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest18.java b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest18.java index eb986de5ee..aa6cf18b3c 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest18.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest18.java @@ -28,20 +28,24 @@ public class OdpsSelectTest18 extends TestCase { public void test_select() throws Exception { String sql = "select a, b, c from tableA where a in ( select a from tableB limit 10 )";// - Assert.assertEquals("SELECT a\n" + + assertEquals("SELECT a\n" + "\t, b\n" + "\t, c\n" + "FROM tableA\n" + - "WHERE a IN (SELECT a\n" + + "WHERE a IN (\n" + + "\tSELECT a\n" + "\tFROM tableB\n" + - "\tLIMIT 10)", SQLUtils.formatOdps(sql)); - Assert.assertEquals("select a\n" + + "\tLIMIT 10\n" + + ")", SQLUtils.formatOdps(sql)); + assertEquals("select a\n" + "\t, b\n" + "\t, c\n" + "from tableA\n" + - "where a in (select a\n" + + "where a in (\n" + + "\tselect a\n" + "\tfrom tableB\n" + - "\tlimit 10)", SQLUtils.formatOdps(sql, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); + "\tlimit 10\n" + + ")", SQLUtils.formatOdps(sql, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); List statementList = SQLUtils.parseStatements(sql, JdbcConstants.ODPS); SQLStatement stmt = statementList.get(0); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSubqueryFactoringTest.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSubqueryFactoringTest.java index 4873c29aa8..8e8f774c00 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSubqueryFactoringTest.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSubqueryFactoringTest.java @@ -53,7 +53,7 @@ public class OracleSubqueryFactoringTest extends TestCase { + "WHERE dept_total > (\n" // + "\tSELECT avg\n" // + "\tFROM avg_cost\n" // - + "\t)\n" // + + ")\n" // + "ORDER BY department_name;"; OracleStatementParser parser = new OracleStatementParser(sql); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateViewTest3.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateViewTest3.java index 2bb53d3526..1e7637064a 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateViewTest3.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/create/OracleCreateViewTest3.java @@ -104,7 +104,7 @@ public class OracleCreateViewTest3 extends OracleTest { "\t\tAND outer.dbinc_key = bdf.dbinc_key\n" + "\t\tAND outer.file# = file#\n" + "\t\tAND outer.stamp < bs.stamp\n" + - "\t)",// + ")",// SQLUtils.toSQLString(stmt, JdbcConstants.ORACLE)); OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/param/Oracle_param_0.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/param/Oracle_param_0.java new file mode 100644 index 0000000000..d837df9c06 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/param/Oracle_param_0.java @@ -0,0 +1,51 @@ +package com.alibaba.druid.bvt.sql.oracle.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.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 Oracle_param_0 extends TestCase { + public void test_for_parameterize() throws Exception { + final String dbType = JdbcConstants.MYSQL; + + String sql = "select * from t where rownum = 1"; + + SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType); + List stmtList = parser.parseStatementList(); + + StringBuilder out = new StringBuilder(); + SQLASTOutputVisitor visitor = SQLUtils.createOutputVisitor(out, JdbcConstants.ORACLE); + 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(0, parameters.size()); + + StringBuilder buf = new StringBuilder(); + SQLASTOutputVisitor visitor1 = SQLUtils.createOutputVisitor(buf, dbType); + visitor1.addTableMapping("a_entry", "a_entry_2664"); + visitor1.setParameters(visitor.getParameters()); + stmt.accept(visitor1); + + assertEquals("SELECT *\n" + + "FROM t\n" + + "WHERE rownum = 1", buf.toString()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest38.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest38.java index 9d2b423ebd..ac8a5cc171 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest38.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest38.java @@ -54,81 +54,85 @@ public class OracleSelectTest38 extends OracleTest { { String result = SQLUtils.toOracleString(stmt); - Assert.assertEquals("SELECT *" - + "\nFROM (" - + "\n\tWITH" - + "\n\t\tvw_kreis_statics_t" - + "\n\t\tAS" - + "\n\t\t(" - + "\n\t\t\tSELECT substr(xzqh, 1, 6) AS xzqh, swrslx, SUM(swrs_count) AS acd_totle" - + "\n\t\t\tFROM (" - + "\n\t\t\t\tSELECT xzqh, sglx, CASE WHEN swrs7 < 3 THEN '1' WHEN swrs7 < 5 THEN '2' WHEN swrs7 <= 9 THEN '3' ELSE '4' END AS swrslx, 1 AS swrs_count" - + "\n\t\t\t\tFROM acduser.vw_acd_info" - + "\n\t\t\t\tWHERE sglx = '1'" - + "\n\t\t\t\t\tAND sgfssj >= ?" - + "\n\t\t\t)" - + "\n\t\t\tGROUP BY substr(xzqh, 1, 6), swrslx" - + "\n\t\t)" - + "\n\tSELECT e.\"XZQH\", e.\"LESS3\", e.\"F3TO5\", e.\"F5TO9\", e.\"MORE9\"" - + "\n\t\t, kreis_code, kreis_name, px1, py1, px2" - + "\n\t\t, py2" - + "\n\tFROM (" - + "\n\t\tSELECT xzqh, nvl(MAX(decode(swrslx, '1', acd_totle)), 0) AS less3, nvl(MAX(decode(swrslx, '2', acd_totle)), 0) AS f3to5, nvl(MAX(decode(swrslx, '3', acd_totle)), 0) AS f5to9, nvl(MAX(decode(swrslx, '4', acd_totle)), 0) AS more9" - + "\n\t\tFROM (" - + "\n\t\t\tSELECT *" - + "\n\t\t\tFROM acduser.vw_kreis_statics_t" - + "\n\t\t)" - + "\n\t\tGROUP BY xzqh" - + "\n\t) e" - + "\n\t\tLEFT JOIN acduser.vw_sc_kreis_code_lv2 f ON e.xzqh = f.short_kreis_code " - + "\n)" - + "\nWHERE kreis_code IN (SELECT *" - + "\n\tFROM (" - + "\n\t\tSELECT tbek_code" - + "\n\t\tFROM acduser.vw_kreis_code" - + "\n\t\tSTART WITH tbek_code = ?" - + "\n\t\tCONNECT BY PRIOR tbek_pk = tbek_parent" - + "\n\t)" - + "\n\tWHERE tbek_code != ?)", result); + Assert.assertEquals("SELECT *\n" + + "FROM (\n" + + "\tWITH\n" + + "\t\tvw_kreis_statics_t\n" + + "\t\tAS\n" + + "\t\t(\n" + + "\t\t\tSELECT substr(xzqh, 1, 6) AS xzqh, swrslx, SUM(swrs_count) AS acd_totle\n" + + "\t\t\tFROM (\n" + + "\t\t\t\tSELECT xzqh, sglx, CASE WHEN swrs7 < 3 THEN '1' WHEN swrs7 < 5 THEN '2' WHEN swrs7 <= 9 THEN '3' ELSE '4' END AS swrslx, 1 AS swrs_count\n" + + "\t\t\t\tFROM acduser.vw_acd_info\n" + + "\t\t\t\tWHERE sglx = '1'\n" + + "\t\t\t\t\tAND sgfssj >= ?\n" + + "\t\t\t)\n" + + "\t\t\tGROUP BY substr(xzqh, 1, 6), swrslx\n" + + "\t\t)\n" + + "\tSELECT e.\"XZQH\", e.\"LESS3\", e.\"F3TO5\", e.\"F5TO9\", e.\"MORE9\"\n" + + "\t\t, kreis_code, kreis_name, px1, py1, px2\n" + + "\t\t, py2\n" + + "\tFROM (\n" + + "\t\tSELECT xzqh, nvl(MAX(decode(swrslx, '1', acd_totle)), 0) AS less3, nvl(MAX(decode(swrslx, '2', acd_totle)), 0) AS f3to5, nvl(MAX(decode(swrslx, '3', acd_totle)), 0) AS f5to9, nvl(MAX(decode(swrslx, '4', acd_totle)), 0) AS more9\n" + + "\t\tFROM (\n" + + "\t\t\tSELECT *\n" + + "\t\t\tFROM acduser.vw_kreis_statics_t\n" + + "\t\t)\n" + + "\t\tGROUP BY xzqh\n" + + "\t) e\n" + + "\t\tLEFT JOIN acduser.vw_sc_kreis_code_lv2 f ON e.xzqh = f.short_kreis_code \n" + + ")\n" + + "WHERE kreis_code IN (\n" + + "\tSELECT *\n" + + "\tFROM (\n" + + "\t\tSELECT tbek_code\n" + + "\t\tFROM acduser.vw_kreis_code\n" + + "\t\tSTART WITH tbek_code = ?\n" + + "\t\tCONNECT BY PRIOR tbek_pk = tbek_parent\n" + + "\t)\n" + + "\tWHERE tbek_code != ?\n" + + ")", result); } { String result = SQLUtils.toOracleString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION); - Assert.assertEquals("select *" - + "\nfrom (" - + "\n\twith" - + "\n\t\tvw_kreis_statics_t" - + "\n\t\tas" - + "\n\t\t(" - + "\n\t\t\tselect substr(xzqh, 1, 6) as xzqh, swrslx, sum(swrs_count) as acd_totle" - + "\n\t\t\tfrom (" - + "\n\t\t\t\tselect xzqh, sglx, case when swrs7 < 3 then '1' when swrs7 < 5 then '2' when swrs7 <= 9 then '3' else '4' end as swrslx, 1 as swrs_count" - + "\n\t\t\t\tfrom acduser.vw_acd_info" - + "\n\t\t\t\twhere sglx = '1'" - + "\n\t\t\t\t\tand sgfssj >= ?" - + "\n\t\t\t)" - + "\n\t\t\tgroup by substr(xzqh, 1, 6), swrslx" - + "\n\t\t)" - + "\n\tselect e.\"XZQH\", e.\"LESS3\", e.\"F3TO5\", e.\"F5TO9\", e.\"MORE9\"" - + "\n\t\t, kreis_code, kreis_name, px1, py1, px2" - + "\n\t\t, py2" - + "\n\tfrom (" - + "\n\t\tselect xzqh, nvl(max(decode(swrslx, '1', acd_totle)), 0) as less3, nvl(max(decode(swrslx, '2', acd_totle)), 0) as f3to5, nvl(max(decode(swrslx, '3', acd_totle)), 0) as f5to9, nvl(max(decode(swrslx, '4', acd_totle)), 0) as more9" - + "\n\t\tfrom (" - + "\n\t\t\tselect *" - + "\n\t\t\tfrom acduser.vw_kreis_statics_t" - + "\n\t\t)" - + "\n\t\tgroup by xzqh" - + "\n\t) e" - + "\n\t\tleft join acduser.vw_sc_kreis_code_lv2 f on e.xzqh = f.short_kreis_code " - + "\n)" - + "\nwhere kreis_code in (select *" - + "\n\tfrom (" - + "\n\t\tselect tbek_code" - + "\n\t\tfrom acduser.vw_kreis_code" - + "\n\t\tstart with tbek_code = ?" - + "\n\t\tconnect by prior tbek_pk = tbek_parent" - + "\n\t)" - + "\n\twhere tbek_code != ?)", result); + assertEquals("select *\n" + + "from (\n" + + "\twith\n" + + "\t\tvw_kreis_statics_t\n" + + "\t\tas\n" + + "\t\t(\n" + + "\t\t\tselect substr(xzqh, 1, 6) as xzqh, swrslx, sum(swrs_count) as acd_totle\n" + + "\t\t\tfrom (\n" + + "\t\t\t\tselect xzqh, sglx, case when swrs7 < 3 then '1' when swrs7 < 5 then '2' when swrs7 <= 9 then '3' else '4' end as swrslx, 1 as swrs_count\n" + + "\t\t\t\tfrom acduser.vw_acd_info\n" + + "\t\t\t\twhere sglx = '1'\n" + + "\t\t\t\t\tand sgfssj >= ?\n" + + "\t\t\t)\n" + + "\t\t\tgroup by substr(xzqh, 1, 6), swrslx\n" + + "\t\t)\n" + + "\tselect e.\"XZQH\", e.\"LESS3\", e.\"F3TO5\", e.\"F5TO9\", e.\"MORE9\"\n" + + "\t\t, kreis_code, kreis_name, px1, py1, px2\n" + + "\t\t, py2\n" + + "\tfrom (\n" + + "\t\tselect xzqh, nvl(max(decode(swrslx, '1', acd_totle)), 0) as less3, nvl(max(decode(swrslx, '2', acd_totle)), 0) as f3to5, nvl(max(decode(swrslx, '3', acd_totle)), 0) as f5to9, nvl(max(decode(swrslx, '4', acd_totle)), 0) as more9\n" + + "\t\tfrom (\n" + + "\t\t\tselect *\n" + + "\t\t\tfrom acduser.vw_kreis_statics_t\n" + + "\t\t)\n" + + "\t\tgroup by xzqh\n" + + "\t) e\n" + + "\t\tleft join acduser.vw_sc_kreis_code_lv2 f on e.xzqh = f.short_kreis_code \n" + + ")\n" + + "where kreis_code in (\n" + + "\tselect *\n" + + "\tfrom (\n" + + "\t\tselect tbek_code\n" + + "\t\tfrom acduser.vw_kreis_code\n" + + "\t\tstart with tbek_code = ?\n" + + "\t\tconnect by prior tbek_pk = tbek_parent\n" + + "\t)\n" + + "\twhere tbek_code != ?\n" + + ")", result); } Assert.assertEquals(1, statementList.size()); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest56.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest56.java index aaa15b4540..2f7c6da067 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest56.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest56.java @@ -77,17 +77,19 @@ public class OracleSelectTest56 extends OracleTest { { String text = SQLUtils.toOracleString(stmt); - Assert.assertEquals("SELECT AA.ID, AA.CODE, AA.TYPE, AA.STATUS, AA.EMPLOYEENAME\n" + + assertEquals("SELECT AA.ID, AA.CODE, AA.TYPE, AA.STATUS, AA.EMPLOYEENAME\n" + "\t, AA.CREATORNAME, AA.OPERATIONTYPE, AA.CREATEDATE, AA.REMARK, W.NAME\n" + "\t, DD.DESC\n" + "FROM a AA, w W, d DD\n" + - "WHERE AA.employeeNo IN (SELECT employeeno\n" + + "WHERE AA.employeeNo IN (\n" + + "\t\tSELECT employeeno\n" + "\t\tFROM employeeauditor ea\n" + "\t\tWHERE auditorno = 1\n" + "\t\tGROUP BY employeeno\n" + "\t\tUNION ALL\n" + "\t\tSELECT 1\n" + - "\t\tFROM dual)\n" + + "\t\tFROM dual\n" + + "\t)\n" + "\tAND AA.WNO = W.WNO(+)\n" + "\tAND AA.DEPTNO = DD.DEPTNO(+)", text); } @@ -95,17 +97,19 @@ public class OracleSelectTest56 extends OracleTest { { String text = SQLUtils.toOracleString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION); - Assert.assertEquals("select AA.ID, AA.CODE, AA.TYPE, AA.STATUS, AA.EMPLOYEENAME\n" + + assertEquals("select AA.ID, AA.CODE, AA.TYPE, AA.STATUS, AA.EMPLOYEENAME\n" + "\t, AA.CREATORNAME, AA.OPERATIONTYPE, AA.CREATEDATE, AA.REMARK, W.NAME\n" + "\t, DD.DESC\n" + "from a AA, w W, d DD\n" + - "where AA.employeeNo in (select employeeno\n" + + "where AA.employeeNo in (\n" + + "\t\tselect employeeno\n" + "\t\tfrom employeeauditor ea\n" + "\t\twhere auditorno = 1\n" + "\t\tgroup by employeeno\n" + "\t\tunion all\n" + "\t\tselect 1\n" + - "\t\tfrom dual)\n" + + "\t\tfrom dual\n" + + "\t)\n" + "\tand AA.WNO = W.WNO(+)\n" + "\tand AA.DEPTNO = DD.DEPTNO(+)", text); } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/select/PGSelectTest25.java b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/select/PGSelectTest25.java index 06b1647a69..5f75007eeb 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/select/PGSelectTest25.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/select/PGSelectTest25.java @@ -38,14 +38,14 @@ public class PGSelectTest25 extends PGTest { + "\n\t\tSELECT project_deduct_mandays" + "\n\t\tFROM mytable_01" + "\n\t\tLIMIT 1" - + "\n\t\t))" + + "\n\t))" + "\nFROM t", SQLUtils.toPGString(stmt)); Assert.assertEquals("select COALESCE((" + "\n\t\tselect project_deduct_mandays" + "\n\t\tfrom mytable_01" + "\n\t\tlimit 1" - + "\n\t\t))" + + "\n\t))" + "\nfrom t", SQLUtils.toPGString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); Assert.assertEquals(1, statementList.size()); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/select/PGSelectTest43.java b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/select/PGSelectTest43.java index 6201b7907f..140b39cdff 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/select/PGSelectTest43.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/select/PGSelectTest43.java @@ -33,19 +33,23 @@ public class PGSelectTest43 extends PGTest { List statementList = parser.parseStatementList(); SQLStatement stmt = statementList.get(0); - Assert.assertEquals("SELECT task_id\n" + + assertEquals("SELECT task_id\n" + "FROM mod_period_time\n" + - "WHERE task_id IN (SELECT task_id AS b\n" + + "WHERE task_id IN (\n" + + "\tSELECT task_id AS b\n" + "\tFROM mod_period_time\n" + "\tORDER BY task_id DESC\n" + - "\tLIMIT 1)", SQLUtils.toPGString(stmt)); + "\tLIMIT 1\n" + + ")", SQLUtils.toPGString(stmt)); - Assert.assertEquals("select task_id\n" + + assertEquals("select task_id\n" + "from mod_period_time\n" + - "where task_id in (select task_id as b\n" + + "where task_id in (\n" + + "\tselect task_id as b\n" + "\tfrom mod_period_time\n" + "\torder by task_id desc\n" + - "\tlimit 1)", SQLUtils.toPGString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); + "\tlimit 1\n" + + ")", SQLUtils.toPGString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); Assert.assertEquals(1, statementList.size()); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerInsertTest7.java b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerInsertTest7.java index a2f20cd989..2c252b5dc5 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerInsertTest7.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerInsertTest7.java @@ -56,19 +56,20 @@ public class SQLServerInsertTest7 extends TestCase { SQLServerSchemaStatVisitor visitor = new SQLServerSchemaStatVisitor(); stmt.accept(visitor); - String formatSql = "INSERT INTO MMS_SETTLEMENT_COM" - + "\n\t(handler, handleTime, MID, MERCHANTNAME, TOTALAMT" - + "\n\t, ACTUALAMT, paymentMoney, STATUS, SERIAL_NUM, REMARKS)" - + "\nSELECT 'admin', getdate(), MID, MERCHANTNAME, SUM(CONVERT(DECIMAL(18, 2), isnull(TOTALAMT, 0))) AS TOTALAMT" - + "\n\t, SUM(CONVERT(DECIMAL(18, 2), isnull(ACTUALAMT, 0))) AS ACTUALAMT, SUM(CONVERT(DECIMAL(18, 2), isnull(paymentMoney, 0))) AS paymentMoney, 2, 126, (" - + "\n\t\tSELECT REMARKS + ''" - + "\n\t\tFROM MMS_SETTLEMENT_COM" - + "\n\t\tWHERE MID = A.MID" - + "\n\t\tFOR XML PATH('')" - + "\n\t\t) AS REMARKS" - + "\nFROM MMS_SETTLEMENT_COM A" - + "\nWHERE ID IN (304, 305, 306, 297, 108, 184)" - + "\nGROUP BY MID, MERCHANTNAME"; + String formatSql = "INSERT INTO MMS_SETTLEMENT_COM\n" + + "\t(handler, handleTime, MID, MERCHANTNAME, TOTALAMT\n" + + "\t, ACTUALAMT, paymentMoney, STATUS, SERIAL_NUM, REMARKS)\n" + + "SELECT 'admin', getdate(), MID, MERCHANTNAME, SUM(CONVERT(DECIMAL(18, 2), isnull(TOTALAMT, 0))) AS TOTALAMT\n" + + "\t, SUM(CONVERT(DECIMAL(18, 2), isnull(ACTUALAMT, 0))) AS ACTUALAMT, SUM(CONVERT(DECIMAL(18, 2), isnull(paymentMoney, 0))) AS paymentMoney, 2, 126\n" + + "\t, (\n" + + "\t\tSELECT REMARKS + ''\n" + + "\t\tFROM MMS_SETTLEMENT_COM\n" + + "\t\tWHERE MID = A.MID\n" + + "\t\tFOR XML PATH('')\n" + + "\t) AS REMARKS\n" + + "FROM MMS_SETTLEMENT_COM A\n" + + "WHERE ID IN (304, 305, 306, 297, 108, 184)\n" + + "GROUP BY MID, MERCHANTNAME"; Assert.assertEquals(formatSql, SQLUtils.toSQLServerString(insertStmt)); } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerSelectTest13.java b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerSelectTest13.java index 33a8b04add..792bde721e 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerSelectTest13.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerSelectTest13.java @@ -76,7 +76,7 @@ public class SQLServerSelectTest13 extends TestCase { "\t\t\tFROM config.sys_params t\n" + "\t\t\tWHERE t.param_type = ?\n" + "\t\t\t\tAND t.param_value = a.tran_type\n" + - "\t\t\t) AS tranTypeName\n" + + "\t\t) AS tranTypeName\n" + "\tFROM bussiness.account_detail a\n" + "\tWHERE 1 = 1\n" + "\t\tAND a.time_add >= ?\n" + diff --git a/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerSelectTest14.java b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerSelectTest14.java index 396f88d73c..ceda0ef8c8 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerSelectTest14.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerSelectTest14.java @@ -75,7 +75,7 @@ public class SQLServerSelectTest14 extends TestCase { "\t\t\tFROM config.sys_params t\n" + "\t\t\tWHERE t.param_type = 2\n" + "\t\t\t\tAND t.param_value = a.tran_type\n" + - "\t\t\t) AS tranTypeName\n" + + "\t\t) AS tranTypeName\n" + "\tFROM bussiness.account_detail a\n" + "\tWHERE 1 = 1\n" + "\t\tAND a.time_add >= 2\n" + diff --git a/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerSelectTest7.java b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerSelectTest7.java index 8018c7104c..3695e582bb 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerSelectTest7.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerSelectTest7.java @@ -62,49 +62,50 @@ public class SQLServerSelectTest7 extends TestCase { "\n )" + "\n order by t.sort_order"; - String expect = "WITH" + - "\n\tmenu_view" + - "\n\tAS" + - "\n\t(" + - "\n\t\tSELECT t.*, 1 AS level" + - "\n\t\tFROM sec_portal_menu t" + - "\n\t\tWHERE t.parent_id = ?" + - "\n\t\tUNION ALL" + - "\n\t\tSELECT t.*, level + 1" + - "\n\t\tFROM sec_portal_menu t, menu_view x" + - "\n\t\tWHERE t.parent_id = x.menu_id" + - "\n\t)" + - "\nSELECT t.menu_id AS \"id\", t.menu_name AS \"name\", t.parent_id AS \"pId\", CASE t.level WHEN 1 THEN 'true' ELSE 'false' END AS \"open\", t.link_type AS \"linkType\"" + - "\nFROM menu_view t" + - "\nWHERE 1 = 1" + - "\n\tAND t.deleted = 0" + - "\n\tAND t.link_type IN ('simple', 'link')" + - "\n\tAND (EXISTS (" + - "\n\t\t\tSELECT p.entity_code" + - "\n\t\t\tFROM sec_role_auth p" + - "\n\t\t\tWHERE p.entity_code = t.menu_id" + - "\n\t\t\t\tAND p.entity_type = 'menu'" + - "\n\t\t\t\tAND p.role_id IN (SELECT r.role_code" + - "\n\t\t\t\t\tFROM sec_role_member rm, sec_role r" + - "\n\t\t\t\t\tWHERE rm.entity_type = 'user'" + - "\n\t\t\t\t\t\tAND entity_code = ?" + - "\n\t\t\t\t\t\tAND r.role_id = rm.role_id" + - "\n\t\t\t\t\t\tAND r.enabled = 1" + - "\n\t\t\t\t\t\tAND r.deleted = 0)"+ - "\n\t\t\t)" + - "\n\t\tOR '1' = ?" + - "\n\t\tOR t.need_control = 0)" + - "\n\tAND (t.enabled = 1" + - "\n\t\tOR '1' = ?" + - "\n\t\tOR t.need_control = 0)" + - "\nORDER BY t.sort_order"; SQLServerStatementParser parser = new SQLServerStatementParser(sql); SQLStatement stmt = parser.parseStatementList().get(0); String text = TestUtils.outputSqlServer(stmt); - Assert.assertEquals(expect, text); + assertEquals("WITH\n" + + "\tmenu_view\n" + + "\tAS\n" + + "\t(\n" + + "\t\tSELECT t.*, 1 AS level\n" + + "\t\tFROM sec_portal_menu t\n" + + "\t\tWHERE t.parent_id = ?\n" + + "\t\tUNION ALL\n" + + "\t\tSELECT t.*, level + 1\n" + + "\t\tFROM sec_portal_menu t, menu_view x\n" + + "\t\tWHERE t.parent_id = x.menu_id\n" + + "\t)\n" + + "SELECT t.menu_id AS \"id\", t.menu_name AS \"name\", t.parent_id AS \"pId\", CASE t.level WHEN 1 THEN 'true' ELSE 'false' END AS \"open\", t.link_type AS \"linkType\"\n" + + "FROM menu_view t\n" + + "WHERE 1 = 1\n" + + "\tAND t.deleted = 0\n" + + "\tAND t.link_type IN ('simple', 'link')\n" + + "\tAND (EXISTS (\n" + + "\t\t\tSELECT p.entity_code\n" + + "\t\t\tFROM sec_role_auth p\n" + + "\t\t\tWHERE p.entity_code = t.menu_id\n" + + "\t\t\t\tAND p.entity_type = 'menu'\n" + + "\t\t\t\tAND p.role_id IN (\n" + + "\t\t\t\t\tSELECT r.role_code\n" + + "\t\t\t\t\tFROM sec_role_member rm, sec_role r\n" + + "\t\t\t\t\tWHERE rm.entity_type = 'user'\n" + + "\t\t\t\t\t\tAND entity_code = ?\n" + + "\t\t\t\t\t\tAND r.role_id = rm.role_id\n" + + "\t\t\t\t\t\tAND r.enabled = 1\n" + + "\t\t\t\t\t\tAND r.deleted = 0\n" + + "\t\t\t\t)\n" + + "\t\t)\n" + + "\t\tOR '1' = ?\n" + + "\t\tOR t.need_control = 0)\n" + + "\tAND (t.enabled = 1\n" + + "\t\tOR '1' = ?\n" + + "\t\tOR t.need_control = 0)\n" + + "ORDER BY t.sort_order", text); // System.out.println(text); } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerUpdateTest3.java b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerUpdateTest3.java index 4a525fb950..7331538fc5 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerUpdateTest3.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerUpdateTest3.java @@ -45,10 +45,10 @@ public class SQLServerUpdateTest3 extends TestCase { "\n\t\t\tSELECT MAX(OrderDate)" + "\n\t\t\tFROM Sales.SalesOrderHeader so2" + "\n\t\t\tWHERE so2.SalesPersonID = so.SalesPersonID" + - "\n\t\t\t)" + + "\n\t\t)" + "\n\t\tAND Sales.SalesPerson.SalesPersonID = so.SalesPersonID" + "\n\tGROUP BY so.SalesPersonID" + - "\n\t)"; + "\n)"; SQLServerStatementParser parser = new SQLServerStatementParser(sql); SQLStatement stmt = parser.parseStatementList().get(0); diff --git a/src/test/resources/bvt/parser/mysql-9.txt b/src/test/resources/bvt/parser/mysql-9.txt index cb1682acad..7333dce213 100644 --- a/src/test/resources/bvt/parser/mysql-9.txt +++ b/src/test/resources/bvt/parser/mysql-9.txt @@ -5,7 +5,8 @@ SELECT a.id AS "appId", a.name AS "appName", b.number AS "instanceNumber", b.hos , d.id AS "alarmRuleStatusId", d.name AS "alarmRuleName", d.current_status AS "alarmRuleStatus", d.last_change_time AS "lastChangeTimeOfAlarmRule" FROM mi_alarm_rule_status d LEFT JOIN monitor_item_status c ON d.mi_status_id = c.id - LEFT JOIN instance b ON b.number = c.inst_num + LEFT JOIN instance b + ON b.number = c.inst_num AND b.app_num = c.app_num AND b.hostname = c.hostname LEFT JOIN app a ON a.number = b.app_num @@ -103,11 +104,12 @@ SELECT a.id AS "appId", a.name AS "appName", b.number AS "instanceNumber", b.hos , d.id AS "alarmRuleStatusId", d.name AS "alarmRuleName", d.current_status AS "alarmRuleStatus", d.last_change_time AS "lastChangeTimeOfAlarmRule" FROM mi_alarm_rule_status d LEFT JOIN monitor_item_status c ON d.mi_status_id = c.id - LEFT JOIN instance b ON b.number = c.inst_num + LEFT JOIN instance b + ON b.number = c.inst_num AND b.app_num = c.app_num AND b.hostname = c.hostname LEFT JOIN app a ON a.number = b.app_num WHERE 1 = 0 OR a.id = ? ORDER BY lastChangeTimeOfAlarmRule DESC -LIMIT ?, ? +LIMIT ?, ? \ No newline at end of file