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 2f567e91f6..6aaaf57344 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/SQLExprImpl.java +++ b/src/main/java/com/alibaba/druid/sql/ast/SQLExprImpl.java @@ -25,9 +25,7 @@ public abstract class SQLExprImpl extends SQLObjectImpl implements SQLExpr { public abstract int hashCode(); - public SQLExpr clone() { - throw new UnsupportedOperationException(this.getClass().getName()); - } + public abstract SQLExpr clone(); public SQLDataType computeDataType() { return null; diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLAllExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLAllExpr.java index 8cf8270918..8976974bed 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLAllExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLAllExpr.java @@ -28,8 +28,15 @@ public class SQLAllExpr extends SQLExprImpl { } public SQLAllExpr(SQLSelect select){ + setSubQuery(select); + } - this.subQuery = select; + public SQLAllExpr clone() { + SQLAllExpr x = new SQLAllExpr(); + if (subQuery != null) { + x.setSubQuery(subQuery.clone()); + } + return x; } public SQLSelect getSubQuery() { @@ -37,6 +44,9 @@ public class SQLAllExpr extends SQLExprImpl { } public void setSubQuery(SQLSelect subQuery) { + if (subQuery != null) { + subQuery.setParent(this); + } this.subQuery = subQuery; } diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLAnyExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLAnyExpr.java index a2d35719cb..1e191a9da5 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLAnyExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLAnyExpr.java @@ -33,8 +33,15 @@ public class SQLAnyExpr extends SQLExprImpl { } public SQLAnyExpr(SQLSelect select){ + setSubQuery(select); + } - this.subQuery = select; + public SQLAnyExpr clone() { + SQLAnyExpr x = new SQLAnyExpr(); + if (subQuery != null) { + x.setSubQuery(subQuery.clone()); + } + return x; } public SQLSelect getSubQuery() { @@ -42,6 +49,9 @@ public class SQLAnyExpr extends SQLExprImpl { } public void setSubQuery(SQLSelect subQuery) { + if (subQuery != null) { + subQuery.setParent(this); + } this.subQuery = subQuery; } diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLArrayExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLArrayExpr.java index c66a21f1ee..7f4943001e 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLArrayExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLArrayExpr.java @@ -28,6 +28,19 @@ public class SQLArrayExpr extends SQLExprImpl { private List values = new ArrayList(); + public SQLArrayExpr clone() { + SQLArrayExpr x = new SQLArrayExpr(); + if (expr != null) { + x.setExpr(expr.clone()); + } + for (SQLExpr value : values) { + SQLExpr value2 = value.clone(); + value2.setParent(x); + x.values.add(value2); + } + return x; + } + public SQLExpr getExpr() { return expr; } diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLBetweenExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLBetweenExpr.java index d7a6e1756f..efbedc81ac 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLBetweenExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLBetweenExpr.java @@ -34,6 +34,21 @@ public class SQLBetweenExpr extends SQLExprImpl implements Serializable { } + public SQLBetweenExpr clone() { + SQLBetweenExpr x = new SQLBetweenExpr(); + if (testExpr != null) { + x.setTestExpr(testExpr.clone()); + } + x.not = not; + if (beginExpr != null) { + x.setBeginExpr(beginExpr.clone()); + } + if (endExpr != null) { + x.setEndExpr(endExpr.clone()); + } + return x; + } + public SQLBetweenExpr(SQLExpr testExpr, SQLExpr beginExpr, SQLExpr endExpr){ setTestExpr(testExpr); setBeginExpr(beginExpr); diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLCastExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLCastExpr.java index 4ad6ca99b6..2bfd1726bd 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLCastExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLCastExpr.java @@ -97,4 +97,15 @@ public class SQLCastExpr extends SQLExprImpl { public SQLDataType computeDataType() { return dataType; } + + public SQLCastExpr clone() { + SQLCastExpr x = new SQLCastExpr(); + if (expr != null) { + x.setExpr(expr.clone()); + } + if (dataType != null) { + x.setDataType(dataType.clone()); + } + return x; + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLCurrentOfCursorExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLCurrentOfCursorExpr.java index 65b8dc4056..c347303ba3 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLCurrentOfCursorExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLCurrentOfCursorExpr.java @@ -31,11 +31,22 @@ public class SQLCurrentOfCursorExpr extends SQLExprImpl { this.cursorName = cursorName; } + public SQLCurrentOfCursorExpr clone() { + SQLCurrentOfCursorExpr x = new SQLCurrentOfCursorExpr(); + if (cursorName != null) { + x.setCursorName(cursorName.clone()); + } + return x; + } + public SQLName getCursorName() { return cursorName; } public void setCursorName(SQLName cursorName) { + if (cursorName != null) { + cursorName.setParent(this); + } this.cursorName = cursorName; } diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLGroupingSetExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLGroupingSetExpr.java index dbb43f232d..6f6474bd66 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLGroupingSetExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLGroupingSetExpr.java @@ -20,12 +20,23 @@ import java.util.List; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLExprImpl; +import com.alibaba.druid.sql.ast.statement.SQLExplainStatement; import com.alibaba.druid.sql.visitor.SQLASTVisitor; public class SQLGroupingSetExpr extends SQLExprImpl { private final List parameters = new ArrayList(); + public SQLGroupingSetExpr clone() { + SQLGroupingSetExpr x = new SQLGroupingSetExpr(); + for (SQLExpr p : parameters) { + SQLExpr p2 = p.clone(); + p2.setParent(x); + x.parameters.add(p2); + } + return x; + } + public List getParameters() { return parameters; } diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLSomeExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLSomeExpr.java index baf0704905..ffa00823ec 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLSomeExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLSomeExpr.java @@ -33,8 +33,15 @@ public class SQLSomeExpr extends SQLExprImpl { } public SQLSomeExpr(SQLSelect select){ + this.setSubQuery(select); + } - this.subQuery = select; + public SQLSomeExpr clone() { + SQLSomeExpr x = new SQLSomeExpr(); + if (subQuery != null) { + x.setSubQuery(subQuery.clone()); + } + return x; } public SQLSelect getSubQuery() { @@ -42,6 +49,9 @@ public class SQLSomeExpr extends SQLExprImpl { } public void setSubQuery(SQLSelect subQuery) { + if (subQuery != null) { + subQuery.setParent(this); + } this.subQuery = subQuery; } diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLTimestampExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLTimestampExpr.java index 6eac940894..d045ca8caf 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLTimestampExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLTimestampExpr.java @@ -32,6 +32,14 @@ public class SQLTimestampExpr extends SQLExprImpl { } + public SQLTimestampExpr clone() { + SQLTimestampExpr x = new SQLTimestampExpr(); + x.literal = literal; + x.timeZone = timeZone; + x.withTimeZone = withTimeZone; + return x; + } + public String getLiteral() { return literal; } diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLUnaryExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLUnaryExpr.java index d5c4357c83..5bc6e201ff 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLUnaryExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLUnaryExpr.java @@ -36,6 +36,15 @@ public class SQLUnaryExpr extends SQLExprImpl implements Serializable { this.setExpr(expr); } + public SQLUnaryExpr clone() { + SQLUnaryExpr x = new SQLUnaryExpr(); + if (expr != null) { + x.setExpr(expr.clone()); + } + x.operator = operator; + return x; + } + public SQLUnaryOperator getOperator() { return operator; } 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 2ece15db11..6ffdb34913 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 @@ -139,6 +139,9 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS } public void setSelect(SQLSelect select) { + if (select != null) { + select.setParent(this); + } this.select = select; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlExtractExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlExtractExpr.java index 864c14f3a7..3e80263d0b 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlExtractExpr.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlExtractExpr.java @@ -28,11 +28,23 @@ public class MySqlExtractExpr extends SQLExprImpl implements MySqlExpr { public MySqlExtractExpr(){ } + public MySqlExtractExpr clone() { + MySqlExtractExpr x = new MySqlExtractExpr(); + if (value != null) { + x.setValue(value.clone()); + } + x.unit = unit; + return x; + } + public SQLExpr getValue() { return value; } public void setValue(SQLExpr value) { + if (value != null) { + value.setParent(this); + } this.value = value; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlIntervalExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlIntervalExpr.java index 175e13e1d8..c97249a5d4 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlIntervalExpr.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlIntervalExpr.java @@ -28,6 +28,15 @@ public class MySqlIntervalExpr extends SQLExprImpl implements MySqlExpr { public MySqlIntervalExpr(){ } + public MySqlIntervalExpr clone() { + MySqlIntervalExpr x = new MySqlIntervalExpr(); + if (value != null) { + x.setValue(value.clone()); + } + x.unit = unit; + return x; + } + public SQLExpr getValue() { return value; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlMatchAgainstExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlMatchAgainstExpr.java index 109a5517a4..33da1590d5 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlMatchAgainstExpr.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlMatchAgainstExpr.java @@ -31,6 +31,20 @@ public class MySqlMatchAgainstExpr extends SQLExprImpl implements MySqlExpr { private SearchModifier searchModifier; + public MySqlMatchAgainstExpr clone() { + MySqlMatchAgainstExpr x = new MySqlMatchAgainstExpr(); + for (SQLExpr column : columns) { + SQLExpr column2 = column.clone(); + column2.setParent(x); + x.columns.add(column2); + } + if (against != null) { + x.setAgainst(against.clone()); + } + x.searchModifier = searchModifier; + return x; + } + public List getColumns() { return columns; } @@ -44,6 +58,9 @@ public class MySqlMatchAgainstExpr extends SQLExprImpl implements MySqlExpr { } public void setAgainst(SQLExpr against) { + if (against != null) { + against.setParent(this); + } this.against = against; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlOrderingExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlOrderingExpr.java index 15b439c64d..f75509251d 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlOrderingExpr.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlOrderingExpr.java @@ -32,10 +32,19 @@ public class MySqlOrderingExpr extends SQLExprImpl implements MySqlExpr { public MySqlOrderingExpr(SQLExpr expr, SQLOrderingSpecification type){ super(); - this.expr = expr; + setExpr(expr); this.type = type; } + public MySqlOrderingExpr clone() { + MySqlOrderingExpr x = new MySqlOrderingExpr(); + if (expr != null) { + x.setExpr(expr.clone()); + } + x.type = type; + return x; + } + @Override protected void accept0(SQLASTVisitor visitor) { MySqlASTVisitor mysqlVisitor = (MySqlASTVisitor) visitor; @@ -51,7 +60,9 @@ public class MySqlOrderingExpr extends SQLExprImpl implements MySqlExpr { } public void setExpr(SQLExpr expr) { - expr.setParent(this); + if (expr != null) { + expr.setParent(this); + } this.expr = expr; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSelectQueryBlock.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSelectQueryBlock.java index 4b9ab0b19a..7180e1ffe5 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSelectQueryBlock.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSelectQueryBlock.java @@ -22,6 +22,7 @@ import com.alibaba.druid.sql.ast.*; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.dialect.mysql.ast.MySqlObject; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectQueryBlock; import com.alibaba.druid.sql.visitor.SQLASTVisitor; public class MySqlSelectQueryBlock extends SQLSelectQueryBlock implements MySqlObject { @@ -46,6 +47,34 @@ public class MySqlSelectQueryBlock extends SQLSelectQueryBlock implements MySqlO } + public MySqlSelectQueryBlock clone() { + MySqlSelectQueryBlock x = new MySqlSelectQueryBlock(); + cloneTo(x); + + x.hignPriority = hignPriority; + x.straightJoin = straightJoin; + + x.smallResult = smallResult; + x.bigResult = bigResult; + x.bufferResult = bufferResult; + x.cache = cache; + x.calcFoundRows = calcFoundRows; + + if (procedureName != null) { + x.setProcedureName(procedureName.clone()); + } + if (procedureArgumentList != null) { + for (SQLExpr arg : procedureArgumentList) { + SQLExpr arg_cloned = arg.clone(); + arg_cloned.setParent(this); + x.procedureArgumentList.add(arg_cloned); + } + } + x.lockInShareMode = lockInShareMode; + + return x; + } + public int getHintsSize() { if (hints == null) { return 0; 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 35974d92e9..f72e627da2 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 @@ -16,10 +16,7 @@ package com.alibaba.druid.sql.dialect.mysql.visitor; import com.alibaba.druid.sql.ast.*; -import com.alibaba.druid.sql.ast.expr.SQLAggregateExpr; -import com.alibaba.druid.sql.ast.expr.SQLCharExpr; -import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; -import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; +import com.alibaba.druid.sql.ast.expr.*; import com.alibaba.druid.sql.ast.statement.*; import com.alibaba.druid.sql.dialect.mysql.ast.MySqlForceIndexHint; import com.alibaba.druid.sql.dialect.mysql.ast.MySqlIgnoreIndexHint; @@ -3677,4 +3674,31 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV block.accept(this); return false; } + + @Override + public boolean visit(SQLCommentStatement x) { + SQLCommentStatement.Type type = x.getType(); + + SQLExpr on = x.getOn(); + if (type == SQLCommentStatement.Type.TABLE) { + print0(ucase ? "ALTER TABLE " : "alter table "); + on.accept(this); + print0(ucase ? " COMMENT = " : " comment = "); + x.getComment().accept(this); + } else { + SQLPropertyExpr propertyExpr = (SQLPropertyExpr) on; + + SQLExpr table = propertyExpr.getOwner(); + String column = propertyExpr.getName(); + + print0(ucase ? "ALTER TABLE " : "alter table "); + table.accept(this); + print0(ucase ? " MODIFY COLUMN " : " modify column "); + print(column); + print0(ucase ? " COMMENT " : " comment "); + x.getComment().accept(this); + } + + return false; + } } // diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleCursorExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleCursorExpr.java index 984755c3d0..699bfb9222 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleCursorExpr.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleCursorExpr.java @@ -28,9 +28,16 @@ public class OracleCursorExpr extends SQLExprImpl implements OracleExpr { } + public OracleCursorExpr clone() { + OracleCursorExpr x = new OracleCursorExpr(); + if (query != null) { + x.setQuery(query.clone()); + } + return x; + } + public OracleCursorExpr(SQLSelect query){ - super(); - this.query = query; + setQuery(query); } public SQLSelect getQuery() { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleIsSetExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleIsSetExpr.java index 17200d935a..7e6982c74c 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleIsSetExpr.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleIsSetExpr.java @@ -31,11 +31,22 @@ public class OracleIsSetExpr extends SQLExprImpl implements OracleExpr { this.nestedTable = nestedTable; } + public OracleIsSetExpr clone() { + OracleIsSetExpr x = new OracleIsSetExpr(); + if (nestedTable != null) { + x.setNestedTable(nestedTable.clone()); + } + return x; + } + public SQLExpr getNestedTable() { return nestedTable; } public void setNestedTable(SQLExpr nestedTable) { + if (nestedTable != null) { + nestedTable.setParent(this); + } this.nestedTable = nestedTable; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGBoxExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGBoxExpr.java index 81224dd573..d3d7574a95 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGBoxExpr.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGBoxExpr.java @@ -22,6 +22,14 @@ public class PGBoxExpr extends PGExprImpl { private SQLExpr value; + public PGBoxExpr clone() { + PGBoxExpr x = new PGBoxExpr(); + if (value != null) { + x.setValue(value.clone()); + } + return x; + } + public SQLExpr getValue() { return value; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGCidrExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGCidrExpr.java index bda5bb042a..59fba1934f 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGCidrExpr.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGCidrExpr.java @@ -22,6 +22,14 @@ public class PGCidrExpr extends PGExprImpl { private SQLExpr value; + public PGCidrExpr clone() { + PGCidrExpr x = new PGCidrExpr(); + if (value != null) { + x.setValue(value.clone()); + } + return x; + } + public SQLExpr getValue() { return value; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGCircleExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGCircleExpr.java index 9bda24bb61..f07533e9a5 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGCircleExpr.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGCircleExpr.java @@ -22,6 +22,14 @@ public class PGCircleExpr extends PGExprImpl { private SQLExpr value; + public PGCircleExpr clone() { + PGCircleExpr x = new PGCircleExpr(); + if (value != null) { + x.setValue(value.clone()); + } + return x; + } + public SQLExpr getValue() { return value; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGExtractExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGExtractExpr.java index 029f0bf354..6ffa71b9b0 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGExtractExpr.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGExtractExpr.java @@ -23,6 +23,15 @@ public class PGExtractExpr extends PGExprImpl { private PGDateField field; private SQLExpr source; + public PGExtractExpr clone() { + PGExtractExpr x = new PGExtractExpr(); + x.field = field; + if (source != null) { + x.setSource(source.clone()); + } + return x; + } + public PGDateField getField() { return field; } @@ -36,6 +45,9 @@ public class PGExtractExpr extends PGExprImpl { } public void setSource(SQLExpr source) { + if (source != null) { + source.setParent(this); + } this.source = source; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGInetExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGInetExpr.java index 986c1ad918..85b27ee8ea 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGInetExpr.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGInetExpr.java @@ -22,6 +22,14 @@ public class PGInetExpr extends PGExprImpl { private SQLExpr value; + public PGInetExpr clone() { + PGInetExpr x = new PGInetExpr(); + if (value != null) { + x.setValue(value.clone()); + } + return x; + } + public SQLExpr getValue() { return value; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGLineSegmentsExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGLineSegmentsExpr.java index 6fbf9c8681..fb654905ff 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGLineSegmentsExpr.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGLineSegmentsExpr.java @@ -22,6 +22,14 @@ public class PGLineSegmentsExpr extends PGExprImpl { private SQLExpr value; + public PGLineSegmentsExpr clone() { + PGLineSegmentsExpr x = new PGLineSegmentsExpr(); + if (value != null) { + x.setValue(value.clone()); + } + return x; + } + public SQLExpr getValue() { return value; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGMacAddrExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGMacAddrExpr.java index 6ef98d9cf3..e211f1ba78 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGMacAddrExpr.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGMacAddrExpr.java @@ -23,6 +23,14 @@ public class PGMacAddrExpr extends PGExprImpl { private SQLExpr value; + public PGMacAddrExpr clone() { + PGMacAddrExpr x = new PGMacAddrExpr(); + if (value != null) { + x.setValue(value.clone()); + } + return x; + } + public SQLExpr getValue() { return value; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGPointExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGPointExpr.java index 7924721e9f..ecebd08516 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGPointExpr.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGPointExpr.java @@ -22,6 +22,14 @@ public class PGPointExpr extends PGExprImpl { private SQLExpr value; + public PGPointExpr clone() { + PGPointExpr x = new PGPointExpr(); + if (value != null) { + x.setValue(value.clone()); + } + return x; + } + public SQLExpr getValue() { return value; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGPolygonExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGPolygonExpr.java index 2f12d48c29..16e3d6e874 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGPolygonExpr.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/expr/PGPolygonExpr.java @@ -23,6 +23,14 @@ public class PGPolygonExpr extends PGExprImpl { private SQLExpr value; + public PGPolygonExpr clone() { + PGPolygonExpr x = new PGPolygonExpr(); + if (value != null) { + x.setValue(value.clone()); + } + return x; + } + public SQLExpr getValue() { return value; } diff --git a/src/main/java/com/alibaba/druid/sql/repository/SchemaRepository.java b/src/main/java/com/alibaba/druid/sql/repository/SchemaRepository.java index 574cf405d4..b402e6ca2b 100644 --- a/src/main/java/com/alibaba/druid/sql/repository/SchemaRepository.java +++ b/src/main/java/com/alibaba/druid/sql/repository/SchemaRepository.java @@ -30,6 +30,8 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableReference; import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitorAdapter; import com.alibaba.druid.sql.visitor.SQLASTVisitor; import com.alibaba.druid.sql.visitor.SQLASTVisitorAdapter; +import com.alibaba.druid.support.logging.Log; +import com.alibaba.druid.support.logging.LogFactory; import com.alibaba.druid.util.JdbcConstants; import java.io.IOException; @@ -39,6 +41,7 @@ import java.util.*; * Created by wenshao on 03/06/2017. */ public class SchemaRepository { + private static Log LOG = LogFactory.getLog(SchemaRepository.class); private Schema defaultSchema; protected String dbType; protected SQLASTVisitor consoleVisitor; @@ -804,11 +807,12 @@ public class SchemaRepository { } boolean acceptCreateTable(SQLCreateTableStatement x) { - String schemaName = x.getSchema(); + SQLCreateTableStatement x1 = x.clone(); + String schemaName = x1.getSchema(); Schema schema = findSchema(schemaName, true); - SQLSelect select = x.getSelect(); + SQLSelect select = x1.getSelect(); if (select != null) { select.accept(createResolveVisitor(SchemaResolveVisitor.Option.ResolveAllColumn)); @@ -822,21 +826,21 @@ public class SchemaRepository { column.setName(name); column.setDataType(dataType); column.setDbType(dbType); - x.getTableElementList().add(column); + x1.getTableElementList().add(column); } - x.setSelect(null); + x1.setSelect(null); } } x.setSchema(null); - String name = x.computeName(); + String name = x1.computeName(); SchemaObject table = schema.findTableOrView(name); if (table != null) { - return false; + LOG.info("replaced table '" + name + "'"); } - table = new SchemaObjectImpl(name, SchemaObjectType.Table, x.clone()); + table = new SchemaObjectImpl(name, SchemaObjectType.Table, x1); String name_lower = SQLUtils.normalize(name).toLowerCase(); schema.objects.put(name_lower, table); return true; diff --git a/src/main/java/com/alibaba/druid/util/StringUtils.java b/src/main/java/com/alibaba/druid/util/StringUtils.java index 371f7eebbe..cd17f325b9 100644 --- a/src/main/java/com/alibaba/druid/util/StringUtils.java +++ b/src/main/java/com/alibaba/druid/util/StringUtils.java @@ -122,6 +122,10 @@ public class StringUtils { return a.equalsIgnoreCase(b); } + public static boolean isEmpty(String value) { + return isEmpty((CharSequence) value); + } + public static boolean isEmpty(CharSequence value) { if (value == null || value.length() == 0) { return true; diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlCreateTable_showColumns_repository_test.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlCreateTable_showColumns_repository_test.java index 42ff855097..f615cd0c92 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlCreateTable_showColumns_repository_test.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlCreateTable_showColumns_repository_test.java @@ -459,7 +459,7 @@ public class MySqlCreateTable_showColumns_repository_test extends MysqlTest { ")", repository.console("show create table test5")); repository.console("CREATE TABLE sc01.test6 as select a.id, c_tinyint, 'a' f3, 3 f4 from test2 a"); - assertEquals("CREATE TABLE test6 (\n" + + assertEquals("CREATE TABLE sc01.test6 (\n" + "\tid bigint(20),\n" + "\tc_tinyint tinyint(4),\n" + "\tf3 varchar,\n" + @@ -939,5 +939,34 @@ public class MySqlCreateTable_showColumns_repository_test extends MysqlTest { , repository.console("show create table test1_xx")); + + assertEquals("CREATE TABLE test5 (\n" + + "\tc_decimal_1 INT(11),\n" + + "\tid bigint(20),\n" + + "\tc_tinyint tinyint(4),\n" + + "\tc_smallint smallint(6),\n" + + "\tc_mediumint mediumint(9),\n" + + "\tc_int int(11),\n" + + "\tc_bigint bigint(20),\n" + + "\tc_date date,\n" + + "\tc_datetime datetime,\n" + + "\tc_timestamp timestamp,\n" + + "\tc_time time,\n" + + "\tc_char char(10),\n" + + "\tc_varchar varchar(10),\n" + + "\tc_blob blob,\n" + + "\tc_text text,\n" + + "\tc_mediumtext mediumtext,\n" + + "\tc_longblob longblob\n" + + ")" + + , repository.console("show create table test5")); + + repository.console("create table test5(fid bigint)"); + assertEquals("CREATE TABLE test5 (\n" + + "\tfid bigint\n" + + ")" + + , repository.console("show create table test5")); } } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest34.java b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest34.java new file mode 100644 index 0000000000..fcbf709ad8 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest34.java @@ -0,0 +1,75 @@ +/* + * 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.bvt.sql.odps; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +import java.util.List; + +public class OdpsSelectTest34 extends TestCase { + + public void test_select() throws Exception { + // 1095288847322 + String sql = "select a.city, a.car_id, a.rrc_id, a.brand, a.car_series, a.title\n" + + "from dw_x001_cp_used_car_detail a\n" + + "where status = 'PUBLISHED'\n" + + "and model_id = 4419\n" + + "and abs(datediff(licensed_date, '2013-07-01 00:00:00', 'mm')) <= 5\n" + + "and abs(mileage - 7.01) < 3;";// + assertEquals("SELECT a.city, a.car_id, a.rrc_id, a.brand, a.car_series\n" + + "\t, a.title\n" + + "FROM dw_x001_cp_used_car_detail a\n" + + "WHERE status = 'PUBLISHED'\n" + + "\tAND model_id = 4419\n" + + "\tAND abs(datediff(licensed_date, '2013-07-01 00:00:00', 'mm')) <= 5\n" + + "\tAND abs(mileage - 7.01) < 3;", SQLUtils.formatOdps(sql)); + + assertEquals("select a.city, a.car_id, a.rrc_id, a.brand, a.car_series\n" + + "\t, a.title\n" + + "from dw_x001_cp_used_car_detail a\n" + + "where status = 'PUBLISHED'\n" + + "\tand model_id = 4419\n" + + "\tand abs(datediff(licensed_date, '2013-07-01 00:00:00', 'mm')) <= 5\n" + + "\tand abs(mileage - 7.01) < 3;", SQLUtils.formatOdps(sql, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); + + List statementList = SQLUtils.parseStatements(sql, JdbcConstants.ODPS); + SQLStatement stmt = statementList.get(0); + + assertEquals(1, statementList.size()); + + SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(JdbcConstants.ODPS); + stmt.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); +// System.out.println("coditions : " + visitor.getConditions()); +// System.out.println("orderBy : " + visitor.getOrderByColumns()); + + assertEquals(1, visitor.getTables().size()); + assertEquals(10, visitor.getColumns().size()); + assertEquals(2, visitor.getConditions().size()); + +// System.out.println(SQLUtils.formatOdps(sql)); + +// assertTrue(visitor.getColumns().contains(new Column("abc", "name"))); + } + + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest35.java b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest35.java new file mode 100644 index 0000000000..4caab045cd --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest35.java @@ -0,0 +1,73 @@ +/* + * 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.bvt.sql.odps; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +import java.util.List; + +public class OdpsSelectTest35 extends TestCase { + + public void test_select() throws Exception { + // 1095288847322 + String sql = "SELECT a.city, a.car_id, a.rrc_id, a.brand, a.car_series\n" + + " , a.title\n" + + "FROM dw_x001_cp_used_car_detail a\n" + + "WHERE status = 'PUBLISHED'\n" + + " AND model_id = 4419\n" + + " AND abs(datediff(licensed_date, '2013-07-01 00:00:00', 'mm')) <= 5;";// + assertEquals("SELECT a.city, a.car_id, a.rrc_id, a.brand, a.car_series\n" + + "\t, a.title\n" + + "FROM dw_x001_cp_used_car_detail a\n" + + "WHERE status = 'PUBLISHED'\n" + + "\tAND model_id = 4419\n" + + "\tAND abs(datediff(licensed_date, '2013-07-01 00:00:00', 'mm')) <= 5;", SQLUtils.formatOdps(sql)); + + assertEquals("select a.city, a.car_id, a.rrc_id, a.brand, a.car_series\n" + + "\t, a.title\n" + + "from dw_x001_cp_used_car_detail a\n" + + "where status = 'PUBLISHED'\n" + + "\tand model_id = 4419\n" + + "\tand abs(datediff(licensed_date, '2013-07-01 00:00:00', 'mm')) <= 5;", SQLUtils.formatOdps(sql, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); + + List statementList = SQLUtils.parseStatements(sql, JdbcConstants.ODPS); + SQLStatement stmt = statementList.get(0); + + assertEquals(1, statementList.size()); + + SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(JdbcConstants.ODPS); + stmt.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); +// System.out.println("coditions : " + visitor.getConditions()); +// System.out.println("orderBy : " + visitor.getOrderByColumns()); + + assertEquals(1, visitor.getTables().size()); + assertEquals(9, visitor.getColumns().size()); + assertEquals(2, visitor.getConditions().size()); + +// System.out.println(SQLUtils.formatOdps(sql)); + +// assertTrue(visitor.getColumns().contains(new Column("abc", "name"))); + } + + +} diff --git a/src/test/java/com/alibaba/druid/mysql/MySql_Failover_test.java b/src/test/java/com/alibaba/druid/mysql/MySql_Failover_test.java new file mode 100644 index 0000000000..04c7a7a876 --- /dev/null +++ b/src/test/java/com/alibaba/druid/mysql/MySql_Failover_test.java @@ -0,0 +1,26 @@ +package com.alibaba.druid.mysql; + +import com.alibaba.druid.DbTestCase; +import com.alibaba.druid.util.JdbcConstants; +import com.alibaba.druid.util.JdbcUtils; + +import java.sql.Connection; + +/** + * Created by wenshao on 23/07/2017. + */ +public class MySql_Failover_test extends DbTestCase { + public MySql_Failover_test() { + super("pool_config/mysql_db_failover.properties"); + } + + public void test_oracle() throws Exception { + Connection conn = getConnection(); + + String createTableScript = JdbcUtils.getCreateTableScript(conn, JdbcConstants.MYSQL); + System.out.println(createTableScript); + + + conn.close(); + } +}