diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCommentStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCommentStatement.java new file mode 100644 index 0000000000..878af4d6d0 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCommentStatement.java @@ -0,0 +1,53 @@ +package com.alibaba.druid.sql.ast.statement; + +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLObjectImpl; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.visitor.SQLASTVisitor; + +public class SQLCommentStatement extends SQLObjectImpl implements SQLStatement { + + private static final long serialVersionUID = 1L; + + public static enum Type { + TABLE, COLUMN + } + + private SQLExpr on; + private Type type; + private SQLExpr comment; + + public SQLExpr getComment() { + return comment; + } + + public void setComment(SQLExpr comment) { + this.comment = comment; + } + + public Type getType() { + return type; + } + + public void setType(Type type) { + this.type = type; + } + + public SQLExpr getOn() { + return on; + } + + public void setOn(SQLExpr on) { + this.on = on; + } + + @Override + protected void accept0(SQLASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, on); + acceptChild(visitor, comment); + } + visitor.endVisit(this); + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUpdateSetItem.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUpdateSetItem.java index d78d987bc7..beb51e014c 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUpdateSetItem.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUpdateSetItem.java @@ -16,7 +16,6 @@ package com.alibaba.druid.sql.ast.statement; import com.alibaba.druid.sql.ast.SQLExpr; -import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLObjectImpl; import com.alibaba.druid.sql.visitor.SQLASTVisitor; @@ -24,18 +23,18 @@ public class SQLUpdateSetItem extends SQLObjectImpl { private static final long serialVersionUID = 1L; - private SQLName column; + private SQLExpr column; private SQLExpr value; public SQLUpdateSetItem(){ } - public SQLName getColumn() { + public SQLExpr getColumn() { return column; } - public void setColumn(SQLName column) { + public void setColumn(SQLExpr column) { this.column = column; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/SampleClause.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/SampleClause.java index 5dcfbb934b..5dda78d74c 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/SampleClause.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/SampleClause.java @@ -1,5 +1,8 @@ package com.alibaba.druid.sql.dialect.oracle.ast.clause; +import java.util.ArrayList; +import java.util.List; + import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl; import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; @@ -10,7 +13,7 @@ public class SampleClause extends OracleSQLObjectImpl { private boolean block = false; - private int percent; + private List percent = new ArrayList(); private SQLExpr seedValue; @@ -22,11 +25,11 @@ public class SampleClause extends OracleSQLObjectImpl { this.block = block; } - public int getPercent() { + public List getPercent() { return percent; } - public void setPercent(int percent) { + public void setPercent(List percent) { this.percent = percent; } @@ -42,6 +45,7 @@ public class SampleClause extends OracleSQLObjectImpl { public void accept0(OracleASTVisitor visitor) { if (visitor.visit(this)) { acceptChild(visitor, seedValue); + acceptChild(visitor, percent); } visitor.endVisit(this); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleAggregateExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleAggregateExpr.java index 77a2125b46..70f1d581a4 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleAggregateExpr.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleAggregateExpr.java @@ -25,10 +25,19 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor; public class OracleAggregateExpr extends SQLAggregateExpr implements Serializable, OracleExpr { + private boolean unique = false; private static final long serialVersionUID = 1L; private OracleAnalytic over; private boolean ignoreNulls = false; + public boolean isUnique() { + return unique; + } + + public void setUnique(boolean unique) { + this.unique = unique; + } + public boolean isIgnoreNulls() { return this.ignoreNulls; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleArgumentExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleArgumentExpr.java new file mode 100644 index 0000000000..f3eca91a12 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleArgumentExpr.java @@ -0,0 +1,46 @@ +package com.alibaba.druid.sql.dialect.oracle.ast.expr; + +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; + +public class OracleArgumentExpr extends OracleSQLObjectImpl implements SQLExpr { + + private static final long serialVersionUID = 1L; + private String argumentName; + private SQLExpr value; + + public OracleArgumentExpr(){ + + } + + public OracleArgumentExpr(String argumentName, SQLExpr value){ + this.argumentName = argumentName; + this.value = value; + } + + public String getArgumentName() { + return argumentName; + } + + public void setArgumentName(String argumentName) { + this.argumentName = argumentName; + } + + public SQLExpr getValue() { + return value; + } + + public void setValue(SQLExpr value) { + this.value = value; + } + + @Override + public void accept0(OracleASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, value); + } + visitor.endVisit(this); + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleSysdateExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleSysdateExpr.java new file mode 100644 index 0000000000..0337384738 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleSysdateExpr.java @@ -0,0 +1,26 @@ +package com.alibaba.druid.sql.dialect.oracle.ast.expr; + +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; + +public class OracleSysdateExpr extends OracleSQLObjectImpl implements SQLExpr { + + private static final long serialVersionUID = 1L; + + private String option; + + public String getOption() { + return option; + } + + public void setOption(String option) { + this.option = option; + } + + @Override + public void accept0(OracleASTVisitor visitor) { + visitor.visit(this); + visitor.endVisit(this); + } +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleAlterProcedureStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleAlterProcedureStatement.java new file mode 100644 index 0000000000..cb5fac89c7 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleAlterProcedureStatement.java @@ -0,0 +1,47 @@ +package com.alibaba.druid.sql.dialect.oracle.ast.stmt; + +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; + +public class OracleAlterProcedureStatement extends OracleStatementImpl { + + private SQLExpr name; + + private boolean compile = false; + private boolean reuseSettings = false; + + private static final long serialVersionUID = 1L; + + @Override + public void accept0(OracleASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, name); + } + visitor.endVisit(this); + } + + public SQLExpr getName() { + return name; + } + + public void setName(SQLExpr name) { + this.name = name; + } + + public boolean isCompile() { + return compile; + } + + public void setCompile(boolean compile) { + this.compile = compile; + } + + public boolean isReuseSettings() { + return reuseSettings; + } + + public void setReuseSettings(boolean reuseSettings) { + this.reuseSettings = reuseSettings; + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleAlterTableDropPartition.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleAlterTableDropPartition.java new file mode 100644 index 0000000000..3b7cec2a80 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleAlterTableDropPartition.java @@ -0,0 +1,28 @@ +package com.alibaba.druid.sql.dialect.oracle.ast.stmt; + +import com.alibaba.druid.sql.ast.SQLName; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; + +public class OracleAlterTableDropPartition extends OracleAlterTableItem { + + private static final long serialVersionUID = 1L; + + private SQLName name; + + @Override + public void accept0(OracleASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, name); + } + visitor.endVisit(this); + } + + public SQLName getName() { + return name; + } + + public void setName(SQLName name) { + this.name = name; + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleAlterTableItem.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleAlterTableItem.java new file mode 100644 index 0000000000..7b122a0d88 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleAlterTableItem.java @@ -0,0 +1,9 @@ +package com.alibaba.druid.sql.dialect.oracle.ast.stmt; + +import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl; + +public abstract class OracleAlterTableItem extends OracleSQLObjectImpl { + + private static final long serialVersionUID = 1L; + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleAlterTableSplitPartition.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleAlterTableSplitPartition.java new file mode 100644 index 0000000000..953ede43fb --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleAlterTableSplitPartition.java @@ -0,0 +1,161 @@ +package com.alibaba.druid.sql.dialect.oracle.ast.stmt; + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLName; +import com.alibaba.druid.sql.ast.SQLObject; +import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; + +public class OracleAlterTableSplitPartition extends OracleAlterTableItem { + + private static final long serialVersionUID = 1L; + + private SQLName name; + private List at = new ArrayList(); + private List values = new ArrayList(); + private List into = new ArrayList(); + + private UpdateIndexesClause updateIndexes = null; + + @Override + public void accept0(OracleASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, name); + acceptChild(visitor, at); + acceptChild(visitor, values); + acceptChild(visitor, updateIndexes); + } + visitor.endVisit(this); + } + + public UpdateIndexesClause getUpdateIndexes() { + return updateIndexes; + } + + public void setUpdateIndexes(UpdateIndexesClause updateIndexes) { + this.updateIndexes = updateIndexes; + } + + public SQLName getName() { + return name; + } + + public void setName(SQLName name) { + this.name = name; + } + + public List getAt() { + return at; + } + + public void setAt(List at) { + this.at = at; + } + + public List getInto() { + return into; + } + + public void setInto(List into) { + this.into = into; + } + + public List getValues() { + return values; + } + + public void setValues(List values) { + this.values = values; + } + + public static class NestedTablePartitionSpec extends OracleSQLObjectImpl { + + private static final long serialVersionUID = 1L; + + private SQLName partition; + + private List segmentAttributeItems = new ArrayList(); + + @Override + public void accept0(OracleASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, partition); + acceptChild(visitor, segmentAttributeItems); + } + visitor.endVisit(this); + } + + public SQLName getPartition() { + return partition; + } + + public void setPartition(SQLName partition) { + this.partition = partition; + } + + public List getSegmentAttributeItems() { + return segmentAttributeItems; + } + + public void setSegmentAttributeItems(List segmentAttributeItems) { + this.segmentAttributeItems = segmentAttributeItems; + } + + } + + public static class TableSpaceItem extends OracleSQLObjectImpl { + + private static final long serialVersionUID = 1L; + private SQLName tablespace; + + public TableSpaceItem(){ + + } + + public TableSpaceItem(SQLName tablespace){ + this.tablespace = tablespace; + } + + @Override + public void accept0(OracleASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, tablespace); + } + visitor.endVisit(this); + } + + public SQLName getTablespace() { + return tablespace; + } + + public void setTablespace(SQLName tablespace) { + this.tablespace = tablespace; + } + } + + public static class UpdateIndexesClause extends OracleSQLObjectImpl { + + private static final long serialVersionUID = 1L; + private List items = new ArrayList(); + + @Override + public void accept0(OracleASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, items); + } + visitor.endVisit(this); + } + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } + + } +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleAlterTableStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleAlterTableStatement.java new file mode 100644 index 0000000000..b5c5bc3ba7 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleAlterTableStatement.java @@ -0,0 +1,40 @@ +package com.alibaba.druid.sql.dialect.oracle.ast.stmt; + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.druid.sql.ast.SQLName; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; + +public class OracleAlterTableStatement extends OracleStatementImpl { + + private static final long serialVersionUID = 1L; + private SQLName name; + private List items = new ArrayList(); + + @Override + public void accept0(OracleASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, name); + acceptChild(visitor, items); + } + visitor.endVisit(this); + } + + public SQLName getName() { + return name; + } + + public void setName(SQLName name) { + this.name = name; + } + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleAlterTableTruncatePartition.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleAlterTableTruncatePartition.java new file mode 100644 index 0000000000..a4658c5c81 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleAlterTableTruncatePartition.java @@ -0,0 +1,28 @@ +package com.alibaba.druid.sql.dialect.oracle.ast.stmt; + +import com.alibaba.druid.sql.ast.SQLName; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; + +public class OracleAlterTableTruncatePartition extends OracleAlterTableItem { + + private static final long serialVersionUID = 1L; + + private SQLName name; + + @Override + public void accept0(OracleASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, name); + } + visitor.endVisit(this); + } + + public SQLName getName() { + return name; + } + + public void setName(SQLName name) { + this.name = name; + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleDeleteStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleDeleteStatement.java index 45a1fc9cf0..114c27f0bb 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleDeleteStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleDeleteStatement.java @@ -20,6 +20,7 @@ import java.util.List; import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; import com.alibaba.druid.sql.dialect.oracle.ast.OracleHint; +import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleReturningClause; import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; import com.alibaba.druid.sql.visitor.SQLASTVisitor; @@ -30,11 +31,20 @@ public class OracleDeleteStatement extends SQLDeleteStatement { private boolean only = false; private String alias; private final List hints = new ArrayList(); + private OracleReturningClause returning = null; public OracleDeleteStatement(){ } + public OracleReturningClause getReturning() { + return returning; + } + + public void setReturning(OracleReturningClause returning) { + this.returning = returning; + } + public List getHints() { return this.hints; } @@ -48,6 +58,7 @@ public class OracleDeleteStatement extends SQLDeleteStatement { acceptChild(visitor, this.hints); acceptChild(visitor, this.getTableName()); acceptChild(visitor, this.getWhere()); + acceptChild(visitor, returning); } visitor.endVisit(this); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleExceptionStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleExceptionStatement.java new file mode 100644 index 0000000000..6f71b42af8 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleExceptionStatement.java @@ -0,0 +1,64 @@ +package com.alibaba.druid.sql.dialect.oracle.ast.stmt; + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; + +public class OracleExceptionStatement extends OracleSQLObjectImpl implements OracleStatement { + + private static final long serialVersionUID = 1L; + private List items = new ArrayList(); + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } + + public static class Item extends OracleSQLObjectImpl { + + private static final long serialVersionUID = 1L; + private SQLExpr when; + private SQLStatement statement; + + public SQLExpr getWhen() { + return when; + } + + public void setWhen(SQLExpr when) { + this.when = when; + } + + public SQLStatement getStatement() { + return statement; + } + + public void setStatement(SQLStatement statement) { + this.statement = statement; + } + + @Override + public void accept0(OracleASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, when); + acceptChild(visitor, statement); + } + visitor.endVisit(this); + } + + } + + @Override + public void accept0(OracleASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, items); + } + visitor.endVisit(this); + } +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleExplainStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleExplainStatement.java new file mode 100644 index 0000000000..472cee0429 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleExplainStatement.java @@ -0,0 +1,50 @@ +package com.alibaba.druid.sql.dialect.oracle.ast.stmt; + +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.ast.expr.SQLCharExpr; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; + +public class OracleExplainStatement extends OracleStatementImpl { + + private static final long serialVersionUID = 1L; + + private SQLCharExpr statementId; + private SQLExpr into; + private SQLStatement forStatement; + + @Override + public void accept0(OracleASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, statementId); + acceptChild(visitor, into); + acceptChild(visitor, forStatement); + } + visitor.endVisit(this); + } + + public SQLCharExpr getStatementId() { + return statementId; + } + + public void setStatementId(SQLCharExpr statementId) { + this.statementId = statementId; + } + + public SQLExpr getInto() { + return into; + } + + public void setInto(SQLExpr into) { + this.into = into; + } + + public SQLStatement getForStatement() { + return forStatement; + } + + public void setForStatement(SQLStatement forStatement) { + this.forStatement = forStatement; + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleGrantStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleGrantStatement.java new file mode 100644 index 0000000000..73eeec0c85 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleGrantStatement.java @@ -0,0 +1,42 @@ +package com.alibaba.druid.sql.dialect.oracle.ast.stmt; + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; + +public class OracleGrantStatement extends OracleSQLObjectImpl implements OracleStatement { + + private static final long serialVersionUID = 1L; + + private List privileges = new ArrayList(); + + private SQLExpr on; + + public SQLExpr getOn() { + return on; + } + + public void setOn(SQLExpr on) { + this.on = on; + } + + public List getPrivileges() { + return privileges; + } + + public void setPrivileges(List privileges) { + this.privileges = privileges; + } + + @Override + public void accept0(OracleASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, on); + } + visitor.endVisit(this); + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectForUpdate.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectForUpdate.java index 2f734c37fe..8ceed065c1 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectForUpdate.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectForUpdate.java @@ -29,13 +29,42 @@ public class OracleSelectForUpdate extends OracleSQLObjectImpl { private final List of = new ArrayList(); + private boolean notWait = false; + private SQLExpr wait; + private boolean skipLocked = false; + public OracleSelectForUpdate(){ } + public boolean isNotWait() { + return notWait; + } + + public void setNotWait(boolean notWait) { + this.notWait = notWait; + } + + public SQLExpr getWait() { + return wait; + } + + public void setWait(SQLExpr wait) { + this.wait = wait; + } + + public boolean isSkipLocked() { + return skipLocked; + } + + public void setSkipLocked(boolean skipLocked) { + this.skipLocked = skipLocked; + } + public void accept0(OracleASTVisitor visitor) { if (visitor.visit(this)) { acceptChild(visitor, this.of); + acceptChild(visitor, this.wait); } visitor.endVisit(this); 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 c822f85411..3df80469aa 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 @@ -20,6 +20,7 @@ import java.util.List; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource; +import com.alibaba.druid.sql.dialect.oracle.ast.OracleHint; import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause; import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; import com.alibaba.druid.sql.visitor.SQLASTVisitor; @@ -31,6 +32,7 @@ public class OracleSelectJoin extends SQLJoinTableSource implements OracleSelect private final List using = new ArrayList(); protected OracleSelectPivotBase pivot; protected FlashbackQueryClause flashback; + private List hints = new ArrayList(); public OracleSelectJoin(String alias){ super(alias); @@ -40,6 +42,14 @@ public class OracleSelectJoin extends SQLJoinTableSource implements OracleSelect } + public List getHints() { + return hints; + } + + public void setHints(List hints) { + this.hints = hints; + } + public FlashbackQueryClause getFlashback() { return flashback; } 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 f368d0693e..a651d32e28 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 @@ -18,6 +18,7 @@ package com.alibaba.druid.sql.dialect.oracle.ast.stmt; import java.util.ArrayList; import java.util.List; +import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLSetQuantifier; import com.alibaba.druid.sql.ast.statement.SQLSelectItem; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; @@ -34,10 +35,20 @@ public class OracleSelectQueryBlock extends SQLSelectQueryBlock { private OracleSelectHierachicalQueryClause hierachicalQueryClause; private ModelClause modelClause; + private SQLExpr into; public OracleSelectQueryBlock(){ } + + public SQLExpr getInto() { + return into; + } + + public void setInto(SQLExpr into) { + this.into = into; + } + public ModelClause getModelClause() { return modelClause; @@ -68,6 +79,7 @@ public class OracleSelectQueryBlock extends SQLSelectQueryBlock { if (visitor.visit(this)) { acceptChild(visitor, this.selectList); + acceptChild(visitor, this.into); acceptChild(visitor, this.from); acceptChild(visitor, this.where); acceptChild(visitor, this.groupBy); @@ -79,6 +91,7 @@ public class OracleSelectQueryBlock extends SQLSelectQueryBlock { if (visitor.visit(this)) { acceptChild(visitor, this.hints); acceptChild(visitor, this.selectList); + acceptChild(visitor, this.into); acceptChild(visitor, this.from); acceptChild(visitor, this.where); acceptChild(visitor, this.hierachicalQueryClause); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectSubqueryTableSource.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectSubqueryTableSource.java index c13c05a3b8..4c8f73a6f4 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectSubqueryTableSource.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectSubqueryTableSource.java @@ -15,8 +15,12 @@ */ package com.alibaba.druid.sql.dialect.oracle.ast.stmt; +import java.util.ArrayList; +import java.util.List; + import com.alibaba.druid.sql.ast.statement.SQLSelect; import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource; +import com.alibaba.druid.sql.dialect.oracle.ast.OracleHint; import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause; import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; import com.alibaba.druid.sql.visitor.SQLASTVisitor; @@ -29,10 +33,20 @@ public class OracleSelectSubqueryTableSource extends SQLSubqueryTableSource impl protected FlashbackQueryClause flashback; + private List hints = new ArrayList(); + public OracleSelectSubqueryTableSource(){ } + public List getHints() { + return hints; + } + + public void setHints(List hints) { + this.hints = hints; + } + public FlashbackQueryClause getFlashback() { return flashback; } 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 e17f8507a0..4d7d6d74ac 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 @@ -15,7 +15,11 @@ */ package com.alibaba.druid.sql.dialect.oracle.ast.stmt; +import java.util.ArrayList; +import java.util.List; + import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; +import com.alibaba.druid.sql.dialect.oracle.ast.OracleHint; import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.PartitionExtensionClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.SampleClause; @@ -33,11 +37,20 @@ public class OracleSelectTableReference extends SQLExprTableSource implements Or protected SampleClause sampleClause; protected FlashbackQueryClause flashback; + private List hints = new ArrayList(); public OracleSelectTableReference(){ } + public List getHints() { + return hints; + } + + public void setHints(List hints) { + this.hints = hints; + } + public FlashbackQueryClause getFlashback() { return flashback; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectTableSource.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectTableSource.java index c0ad9b7dd0..9ef0ae4550 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectTableSource.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectTableSource.java @@ -15,7 +15,10 @@ */ package com.alibaba.druid.sql.dialect.oracle.ast.stmt; +import java.util.List; + import com.alibaba.druid.sql.ast.statement.SQLTableSource; +import com.alibaba.druid.sql.dialect.oracle.ast.OracleHint; import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause; public interface OracleSelectTableSource extends SQLTableSource { @@ -27,4 +30,6 @@ public interface OracleSelectTableSource extends SQLTableSource { FlashbackQueryClause getFlashback(); void setFlashback(FlashbackQueryClause flashback); + + List getHints(); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSetTransactionStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSetTransactionStatement.java new file mode 100644 index 0000000000..9126cf9a94 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSetTransactionStatement.java @@ -0,0 +1,29 @@ +package com.alibaba.druid.sql.dialect.oracle.ast.stmt; + +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; + +public class OracleSetTransactionStatement extends OracleSQLObjectImpl implements OracleStatement { + + private static final long serialVersionUID = 1L; + + private SQLExpr name; + + @Override + public void accept0(OracleASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, name); + } + visitor.endVisit(this); + } + + public SQLExpr getName() { + return name; + } + + public void setName(SQLExpr name) { + this.name = name; + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleUpdateStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleUpdateStatement.java index 317bc04ae1..d4ca2c05c3 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleUpdateStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleUpdateStatement.java @@ -19,18 +19,17 @@ import java.util.ArrayList; import java.util.List; import com.alibaba.druid.sql.ast.SQLExpr; -import com.alibaba.druid.sql.ast.SQLStatementImpl; +import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; import com.alibaba.druid.sql.dialect.oracle.ast.OracleHint; import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; import com.alibaba.druid.sql.visitor.SQLASTVisitor; -public class OracleUpdateStatement extends SQLStatementImpl { +public class OracleUpdateStatement extends SQLUpdateStatement implements OracleStatement { private static final long serialVersionUID = 1L; private final List hints = new ArrayList(1); private boolean only = false; - private SQLExpr table; private String alias; private OracleUpdateSetClause setClause; private SQLExpr where; @@ -49,12 +48,12 @@ public class OracleUpdateStatement extends SQLStatementImpl { super.accept(visitor); } - protected void accept0(OracleASTVisitor visitor) { + public void accept0(OracleASTVisitor visitor) { if (visitor.visit(this)) { acceptChild(visitor, this.hints); - acceptChild(visitor, this.table); - acceptChild(visitor, this.setClause); - acceptChild(visitor, this.where); + acceptChild(visitor, tableSource); + acceptChild(visitor, items); + acceptChild(visitor, where); } visitor.endVisit(this); @@ -95,12 +94,4 @@ public class OracleUpdateStatement extends SQLStatementImpl { public List getHints() { return this.hints; } - - public SQLExpr getTable() { - return this.table; - } - - public void setTable(SQLExpr table) { - this.table = table; - } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleDeleteParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleDeleteParser.java deleted file mode 100644 index aef4a0fe47..0000000000 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleDeleteParser.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 1999-2011 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.sql.dialect.oracle.parser; - -import com.alibaba.druid.sql.ast.SQLName; -import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement; -import com.alibaba.druid.sql.parser.Lexer; -import com.alibaba.druid.sql.parser.ParserException; -import com.alibaba.druid.sql.parser.SQLStatementParser; -import com.alibaba.druid.sql.parser.Token; - -public class OracleDeleteParser extends SQLStatementParser { - - public OracleDeleteParser(String sql){ - super(sql); - this.exprParser = new OracleExprParser(lexer); - } - - public OracleDeleteParser(Lexer lexer){ - super(lexer); - this.exprParser = new OracleExprParser(lexer); - } - - - public OracleDeleteStatement parseDelete() throws ParserException { - accept(Token.DELETE); - - OracleDeleteStatement deleteStatement = new OracleDeleteStatement(); - - parseHints(deleteStatement); - - if (lexer.token() == (Token.FROM)) { - lexer.nextToken(); - } - - if (identifierEquals("ONLY")) { - lexer.nextToken(); - accept(Token.LPAREN); - - SQLName tableName = exprParser.name(); - deleteStatement.setTableName(tableName); - - accept(Token.RPAREN); - } else { - SQLName tableName = exprParser.name(); - deleteStatement.setTableName(tableName); - } - - deleteStatement.setAlias(as()); - - if (lexer.token() == (Token.WHERE)) { - lexer.nextToken(); - deleteStatement.setWhere(this.exprParser.expr()); - } - - if (identifierEquals("RETURN") || identifierEquals("RETURNING")) { - throw new ParserException("TODO"); - } - - if (identifierEquals("LOG")) { - throw new ParserException("TODO"); - } - - return deleteStatement; - } - - private void parseHints(OracleDeleteStatement parseInsert) throws ParserException { - if (lexer.token() == Token.HINT) throw new ParserException("TODO"); - } -} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java index 91e262aa4d..ed77e9c20e 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java @@ -37,6 +37,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.OracleOrderBy; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAggregateExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalytic; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalyticWindowing; +import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleArgumentExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleBinaryDoubleExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleBinaryFloatExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleCursorExpr; @@ -49,6 +50,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIntervalExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIntervalType; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIsSetExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleOuterExpr; +import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleSysdateExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleTimestampExpr; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleOrderByItem; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelect; @@ -61,6 +63,7 @@ public class OracleExprParser extends SQLExprParser { + public boolean allowStringAdditive = false; /** @@ -93,6 +96,16 @@ public class OracleExprParser extends SQLExprParser { SQLExpr sqlExpr = null; switch (tok) { + case SYSDATE: + lexer.nextToken(); + OracleSysdateExpr sysdate = new OracleSysdateExpr(); + if (lexer.token() == Token.MONKEYS_AT) { + lexer.nextToken(); + accept(Token.BANG); + sysdate.setOption("!"); + } + sqlExpr = sysdate; + return primaryRest(sqlExpr); case PRIOR: lexer.nextToken(); sqlExpr = expr(); @@ -124,7 +137,7 @@ public class OracleExprParser extends SQLExprParser { accept(Token.LPAREN); - extract.setUnit(OracleDateTimeUnit.valueOf(lexer.stringVal())); + extract.setUnit(OracleDateTimeUnit.valueOf(lexer.stringVal().toUpperCase())); lexer.nextToken(); accept(Token.FROM); @@ -212,12 +225,13 @@ public class OracleExprParser extends SQLExprParser { sqlExpr = new OracleBinaryDoubleExpr(Double.parseDouble(lexer.numberString()) * -1); lexer.nextToken(); break; + case VARIANT: case IDENTIFIER: sqlExpr = expr(); sqlExpr = new SQLUnaryExpr(SQLUnaryOperator.Negative, sqlExpr); break; default: - throw new ParserException("TODO"); + throw new ParserException("TODO " + lexer.token()); } return primaryRest(sqlExpr); @@ -236,6 +250,19 @@ public class OracleExprParser extends SQLExprParser { return super.primary(); } } + + @Override + protected SQLExpr methodRest(SQLExpr expr, boolean acceptLPAREN) { + if (acceptLPAREN) { + accept(Token.LPAREN); + if (lexer.token() == Token.PLUS) { + lexer.nextToken(); + accept(Token.RPAREN); + return new OracleOuterExpr(expr); + } + } + return super.methodRest(expr, false); + } public SQLExpr primaryRest(SQLExpr expr) throws ParserException { if (lexer.token() == Token.MONKEYS_AT) { @@ -299,12 +326,19 @@ public class OracleExprParser extends SQLExprParser { } if (lexer.token() == Token.AT) { + char mark_ch = lexer.current(); + int mark_bp = lexer.bp(); lexer.nextToken(); if (lexer.token() == Token.LOCAL) { lexer.nextToken(); expr = new OracleDatetimeExpr(expr, new SQLIdentifierExpr("LOCAL")); } else { - accept(Token.TIME); + if (lexer.token() == Token.TIME) { + lexer.nextToken(); + } else { + lexer.reset(mark_bp, mark_ch, Token.AT); + return expr; + } accept(Token.ZONE); SQLExpr timeZone = primary(); @@ -338,7 +372,11 @@ public class OracleExprParser extends SQLExprParser { String name = '"' + lexer.stringVal() + '"'; lexer.nextToken(); expr = new SQLPropertyExpr(expr, name); - expr = primaryRest(expr); + + if (lexer.token() == Token.DOT) { + lexer.nextToken(); + expr = dotRest(expr); + } return expr; } @@ -358,8 +396,12 @@ public class OracleExprParser extends SQLExprParser { return timestamp; } - public OracleTimestampExpr parseTimestamp() { + public SQLExpr parseTimestamp() { accept(Token.TIMESTAMP); + + if (lexer.token() != Token.LITERAL_ALIAS) { + return new SQLIdentifierExpr("TIMESTAMP"); + } OracleTimestampExpr timestamp = new OracleTimestampExpr(); @@ -408,6 +450,13 @@ public class OracleExprParser extends SQLExprParser { } protected OracleAggregateExpr parseAggregateExpr(String method_name) { + boolean unique = false; + + if (lexer.token() == Token.UNIQUE) { + lexer.nextToken(); + unique = true; + } + OracleAggregateExpr aggregateExpr; if (lexer.token() == (Token.ALL)) { aggregateExpr = new OracleAggregateExpr(method_name, 1); @@ -418,6 +467,7 @@ public class OracleExprParser extends SQLExprParser { } else { aggregateExpr = new OracleAggregateExpr(method_name, 1); } + aggregateExpr.setUnique(unique); exprList(aggregateExpr.getArguments()); if (lexer.stringVal().equalsIgnoreCase("IGNORE")) { @@ -543,10 +593,10 @@ public class OracleExprParser extends SQLExprParser { protected SQLExpr parseInterval() { accept(Token.INTERVAL); - + OracleIntervalExpr interval = new OracleIntervalExpr(); if (lexer.token() != Token.LITERAL_CHARS) { - throw new ParserException("syntax error : " + lexer.token()); + return new SQLIdentifierExpr("INTERVAL"); } interval.setValue(new SQLCharExpr(lexer.stringVal())); lexer.nextToken(); @@ -644,4 +694,33 @@ public class OracleExprParser extends SQLExprParser { return name; } + + public SQLExpr equalityRest(SQLExpr expr) throws ParserException { + SQLExpr rightExp; + if (lexer.token() == Token.EQ) { + lexer.nextToken(); + + if (lexer.token() == Token.GT) { + lexer.nextToken(); + rightExp = expr(); + String argumentName = ((SQLIdentifierExpr) expr).getName(); + return new OracleArgumentExpr(argumentName, rightExp); + } + + rightExp = shift(); + + rightExp = equalityRest(rightExp); + + expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Equality, rightExp); + } else if (lexer.token() == Token.BANGEQ) { + lexer.nextToken(); + rightExp = shift(); + + rightExp = equalityRest(rightExp); + + expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotEqual, rightExp); + } + + return expr; + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleLexer.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleLexer.java index 0b3ea8dd7c..bd20f47f47 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleLexer.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleLexer.java @@ -94,6 +94,7 @@ public class OracleLexer extends Lexer { map.put("EXTRACT", Token.EXTRACT); map.put("DATE", Token.DATE); map.put("TIMESTAMP", Token.TIMESTAMP); + map.put("COLUMN", Token.COLUMN); map.put("CURSOR", Token.CURSOR); @@ -121,10 +122,16 @@ public class OracleLexer extends Lexer { map.put("WAIT", Token.WAIT); map.put("NOWAIT", Token.NOWAIT); map.put("SESSION", Token.SESSION); + map.put("PROCEDURE", Token.PROCEDURE); map.put("AT", Token.AT); map.put("LOCAL", Token.LOCAL); map.put("TIME", Token.TIME); map.put("ZONE", Token.ZONE); + map.put("SYSDATE", Token.SYSDATE); + map.put("DECLARE", Token.DECLARE); + map.put("EXCEPTION", Token.EXCEPTION); + map.put("GRANT", Token.GRANT); + map.put("COMMENT", Token.COMMENT); DEFAULT_ORACLE_KEYWORDS = new Keywords(map); } @@ -156,6 +163,13 @@ public class OracleLexer extends Lexer { sp = 1; char ch; + boolean quoteFlag = false; + if (buf[bp + 1] == '"') { + hash = 31 * hash + '"'; + bp++; + sp++; + quoteFlag = true; + } for (;;) { ch = buf[++bp]; @@ -168,6 +182,14 @@ public class OracleLexer extends Lexer { sp++; continue; } + if (quoteFlag) { + if (ch != '"') { + throw new SQLParseException("syntax error"); + } + hash = 31 * hash + '"'; + ++bp; + sp++; + } this.ch = buf[bp]; @@ -181,7 +203,7 @@ public class OracleLexer extends Lexer { } public void scanComment() { - if (ch != '/') { + if (ch != '/' && ch != '-') { throw new IllegalStateException(); } @@ -231,7 +253,7 @@ public class OracleLexer extends Lexer { return; } - if (ch == '/') { + if (ch == '/' || ch == '-') { scanChar(); sp++; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java index 7f806dbdc8..f11aff84ae 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java @@ -22,6 +22,7 @@ import com.alibaba.druid.sql.ast.SQLSetQuantifier; import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator; import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; +import com.alibaba.druid.sql.ast.expr.SQLListExpr; import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause; import com.alibaba.druid.sql.ast.statement.SQLSelectQuery; import com.alibaba.druid.sql.ast.statement.SQLTableSource; @@ -167,15 +168,21 @@ public class OracleSelectParser extends SQLSelectParser { OracleSelectForUpdate forUpdate = new OracleSelectForUpdate(); - if (identifierEquals("OF")) { + if (lexer.token() == Token.OF) { lexer.nextToken(); this.createExprParser().exprList(forUpdate.getOf()); - - if (identifierEquals("WAIT")) throw new ParserException("TODO"); - if (identifierEquals("NOWAIT")) throw new ParserException("TODO"); - if (identifierEquals("SKIP")) { - throw new ParserException("TODO"); - } + } + + if (lexer.token() == Token.NOWAIT) { + lexer.nextToken(); + forUpdate.setNotWait(true); + } else if (lexer.token() == Token.WAIT) { + lexer.nextToken(); + forUpdate.setWait(this.createExprParser().primary()); + } else if (identifierEquals("SKIP")) { + lexer.nextToken(); + acceptIdentifier("LOCKED"); + forUpdate.setSkipLocked(true); } select.setForUpdate(forUpdate); @@ -250,6 +257,8 @@ public class OracleSelectParser extends SQLSelectParser { this.createExprParser().parseHints(queryBlock.getHints()); parseSelectList(queryBlock); + + parseInto(queryBlock); parseFrom(queryBlock); @@ -703,12 +712,13 @@ public class OracleSelectParser extends SQLSelectParser { parseTableSourceQueryTableExpr(tableReference); parsePivot(tableReference); } - + return parseTableSourceRest(tableReference); } private void parseTableSourceQueryTableExpr(OracleSelectTableReference tableReference) { tableReference.setExpr(this.createExprParser().expr()); + { FlashbackQueryClause clause = flashback(); tableReference.setFlashback(clause); @@ -721,16 +731,11 @@ public class OracleSelectParser extends SQLSelectParser { if (identifierEquals("BLOCK")) { sample.setBlock(true); + lexer.nextToken(); } accept(Token.LPAREN); - - if (lexer.token() != Token.LITERAL_INT) { - throw new ParserException("syntax error : " + lexer.token()); - } - sample.setPercent(lexer.integerValue().intValue()); - lexer.nextToken(); - + this.createExprParser().exprList(sample.getPercent()); accept(Token.RPAREN); if (identifierEquals("SEED")) { @@ -827,7 +832,7 @@ public class OracleSelectParser extends SQLSelectParser { accept(Token.TIMESTAMP); clause.setType(AsOfFlashbackQueryClause.Type.TIMESTAMP); } - clause.setExpr(createExprParser().primary()); + clause.setExpr(createExprParser().expr()); return clause; } @@ -849,6 +854,10 @@ public class OracleSelectParser extends SQLSelectParser { tableSource.setAlias(as()); } } + + if (lexer.token() == Token.HINT) { + this.createExprParser().parseHints(tableSource.getHints()); + } OracleSelectJoin.JoinType joinType = null; @@ -910,8 +919,8 @@ public class OracleSelectParser extends SQLSelectParser { this.createExprParser().exprList(join.getUsing()); accept(Token.RPAREN); } - - return join; + + return parseTableSourceRest(join); } return tableSource; @@ -1058,6 +1067,24 @@ public class OracleSelectParser extends SQLSelectParser { tableSource.setPivot(unPivot); } } + + protected void parseInto(OracleSelectQueryBlock x) { + if (lexer.token() == Token.INTO) { + lexer.nextToken(); + SQLExpr expr = expr(); + if (lexer.token() != Token.COMMA) { + x.setInto(expr); + return; + } + SQLListExpr list = new SQLListExpr(); + list.getItems().add(expr); + while (lexer.token() == Token.COMMA) { + lexer.nextToken(); + list.getItems().add(expr()); + } + x.setInto(list); + } + } private void parseHints(OracleSelectQueryBlock queryBlock) { this.createExprParser().parseHints(queryBlock.getHints()); 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 4f8b6a2522..e92e261beb 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 @@ -19,9 +19,11 @@ import java.util.ArrayList; import java.util.List; import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator; +import com.alibaba.druid.sql.ast.expr.SQLCharExpr; import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; import com.alibaba.druid.sql.ast.statement.SQLInsertInto; import com.alibaba.druid.sql.ast.statement.SQLSelect; @@ -32,8 +34,20 @@ import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem; import com.alibaba.druid.sql.dialect.oracle.ast.OracleHint; import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleErrorLoggingClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleReturningClause; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterProcedureStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterSessionStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableDropPartition; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableSplitPartition; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableSplitPartition.NestedTablePartitionSpec; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableSplitPartition.TableSpaceItem; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableSplitPartition.UpdateIndexesClause; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableTruncatePartition; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleBlockStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExceptionStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExplainStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleGrantStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleInsertStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLockTableStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLockTableStatement.LockMode; @@ -41,6 +55,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMethodInvokeStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OraclePLSQLCommitStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSetTransactionStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleStatement; import com.alibaba.druid.sql.parser.Lexer; import com.alibaba.druid.sql.parser.ParserException; @@ -76,7 +91,17 @@ public class OracleStatementParser extends SQLStatementParser { @Override public void parseStatementList(List statementList) throws ParserException { + parseStatementList(statementList, -1); + } + + public void parseStatementList(List statementList, int max) throws ParserException { for (;;) { + if (max != -1) { + if (statementList.size() >= max) { + return; + } + } + if (lexer.token() == Token.EOF) { return; } @@ -111,7 +136,7 @@ public class OracleStatementParser extends SQLStatementParser { } if (lexer.token() == (Token.DELETE)) { - statementList.add(new OracleDeleteParser(this.lexer).parseDelete()); + statementList.add(parseDelete()); continue; } @@ -142,7 +167,12 @@ public class OracleStatementParser extends SQLStatementParser { } if (lexer.token() == Token.BEGIN) { - statementList.add(this.parseBegin()); + statementList.add(this.parseBlock()); + continue; + } + + if (lexer.token() == Token.DECLARE) { + statementList.add(this.parseBlock()); continue; } @@ -150,7 +180,7 @@ public class OracleStatementParser extends SQLStatementParser { statementList.add(this.parseLock()); continue; } - + if (lexer.token() == Token.TRUNCATE) { statementList.add(this.parseTruncate()); continue; @@ -173,22 +203,125 @@ public class OracleStatementParser extends SQLStatementParser { statementList.add(stmt); continue; } - + + if (lexer.token() == Token.EXCEPTION) { + statementList.add(this.parseException()); + continue; + } + if (lexer.token() == Token.IDENTIFIER) { + if (identifierEquals("EXPLAIN")) { + statementList.add(this.parseExplain()); + continue; + } + SQLExpr expr = exprParser.expr(); if (expr instanceof SQLMethodInvokeExpr) { OracleMethodInvokeStatement stmt = new OracleMethodInvokeStatement((SQLMethodInvokeExpr) expr); statementList.add(stmt); continue; + } else if (expr instanceof SQLName) { + SQLMethodInvokeExpr methodInvokeExpr = new SQLMethodInvokeExpr(((SQLName) expr).toString()); + statementList.add(new OracleMethodInvokeStatement(methodInvokeExpr)); + continue; } else { throw new ParserException("expr : " + expr); } } + if (lexer.token() == Token.LPAREN) { + char ch = lexer.current(); + int bp = lexer.bp(); + lexer.nextToken(); + + if (lexer.token() == Token.SELECT) { + lexer.reset(bp, ch, Token.LPAREN); + statementList.add(this.parseSelect()); + continue; + } else { + throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + } + } + + if (lexer.token() == Token.SET) { + statementList.add(this.parseSet()); + continue; + } + + if (lexer.token() == Token.GRANT) { + statementList.add(this.parseGrant()); + continue; + } + if (lexer.token() == Token.COMMENT) { + statementList.add(this.parseComment()); + continue; + } + throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); } } - + + public SQLStatement parseGrant() { + accept(Token.GRANT); + OracleGrantStatement stmt = new OracleGrantStatement(); + + for (;;) { + if (lexer.token() == Token.ALL) { + lexer.nextToken(); + if (identifierEquals("PRIVILEGES")) { + lexer.nextToken(); + } + stmt.getPrivileges().add("ALL"); + } else if (lexer.token() == Token.SELECT) { + stmt.getPrivileges().add("SELECT"); + lexer.nextToken(); + } else if (lexer.token() == Token.UPDATE) { + stmt.getPrivileges().add("UPDATE"); + lexer.nextToken(); + } else if (lexer.token() == Token.DELETE) { + stmt.getPrivileges().add("DELETE"); + lexer.nextToken(); + } else if (lexer.token() == Token.INSERT) { + stmt.getPrivileges().add("INSERT"); + lexer.nextToken(); + } else if (lexer.token() == Token.CREATE) { + lexer.nextToken(); + + if (lexer.token() == Token.TABLE) { + stmt.getPrivileges().add("CREATE TABLE"); + lexer.nextToken(); + } else if (identifierEquals("SYNONYM")) { + stmt.getPrivileges().add("CREATE SYNONYM"); + lexer.nextToken(); + } else { + throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + } + } + + if (lexer.token() == Token.COMMA) { + lexer.nextToken(); + continue; + } + break; + } + + if (lexer.token() == Token.ON) { + lexer.nextToken(); + stmt.setOn(this.exprParser.expr()); + } + + return stmt; + } + + public SQLStatement parseSet() { + accept(Token.SET); + acceptIdentifier("TRANSACTION"); + acceptIdentifier("NAME"); + OracleSetTransactionStatement stmt = new OracleSetTransactionStatement(); + stmt.setName(this.exprParser.expr()); + return stmt; + } + public SQLStatement parseTruncate() { return super.parseTruncate(); } @@ -197,16 +330,150 @@ public class OracleStatementParser extends SQLStatementParser { accept(Token.ALTER); if (lexer.token() == Token.SESSION) { lexer.nextToken(); - + OracleAlterSessionStatement stmt = new OracleAlterSessionStatement(); if (lexer.token() == Token.SET) { lexer.nextToken(); parseAssignItems(stmt.getItems()); } else { - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); } + return stmt; + } else if (lexer.token() == Token.PROCEDURE) { + lexer.nextToken(); + OracleAlterProcedureStatement stmt = new OracleAlterProcedureStatement(); + stmt.setName(this.exprParser.name()); + if (identifierEquals("COMPILE")) { + lexer.nextToken(); + stmt.setCompile(true); + } + + if (identifierEquals("REUSE")) { + lexer.nextToken(); + acceptIdentifier("SETTINGS"); + stmt.setReuseSettings(true); + } + + return stmt; + } else if (lexer.token() == Token.TABLE) { + lexer.nextToken(); + OracleAlterTableStatement stmt = new OracleAlterTableStatement(); + stmt.setName(this.exprParser.name()); + + for (;;) { + if (identifierEquals("ADD")) { + throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + } else if (identifierEquals("MOVE")) { + throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + } else if (identifierEquals("RENAME")) { + throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + } else if (identifierEquals("MODIFY")) { + throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + } else if (identifierEquals("SPLIT")) { + lexer.nextToken(); + if (identifierEquals("PARTITION")) { + lexer.nextToken(); + OracleAlterTableSplitPartition item = new OracleAlterTableSplitPartition(); + item.setName(this.exprParser.name()); + + if (lexer.token() == Token.AT) { + lexer.nextToken(); + accept(Token.LPAREN); + this.exprParser.exprList(item.getAt()); + accept(Token.RPAREN); + } else { + throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + } + + if (lexer.token() == Token.INTO) { + lexer.nextToken(); + accept(Token.LPAREN); + + for (;;) { + NestedTablePartitionSpec spec = new NestedTablePartitionSpec(); + acceptIdentifier("PARTITION"); + spec.setPartition(this.exprParser.name()); + + for (;;) { + if (identifierEquals("TABLESPACE")) { + lexer.nextToken(); + SQLName tablespace = this.exprParser.name(); + spec.getSegmentAttributeItems().add(new TableSpaceItem(tablespace)); + continue; + } else if (identifierEquals("PCTREE")) { + throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + } else if (identifierEquals("PCTUSED")) { + throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + } else if (identifierEquals("INITRANS")) { + throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + + } else if (identifierEquals("STORAGE")) { + throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + + } else if (identifierEquals("LOGGING")) { + throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + } else if (identifierEquals("NOLOGGING")) { + throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + } else if (identifierEquals("FILESYSTEM_LIKE_LOGGING")) { + throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + + + } + + break; + } + + item.getInto().add(spec); + + if (lexer.token() == Token.COMMA) { + lexer.nextToken(); + continue; + } + break; + } + accept(Token.RPAREN); + } + + if (lexer.token() == Token.UPDATE) { + lexer.nextToken(); + acceptIdentifier("INDEXES"); + UpdateIndexesClause updateIndexes = new UpdateIndexesClause(); + item.setUpdateIndexes(updateIndexes); + } + stmt.getItems().add(item); + } else { + throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + } + } else if (lexer.token() == Token.TRUNCATE) { + lexer.nextToken(); + if (identifierEquals("PARTITION")) { + lexer.nextToken(); + OracleAlterTableTruncatePartition item = new OracleAlterTableTruncatePartition(); + item.setName(this.exprParser.name()); + stmt.getItems().add(item); + } else { + throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + } + continue; + } else if (lexer.token() == Token.DROP) { + lexer.nextToken(); + if (identifierEquals("PARTITION")) { + lexer.nextToken(); + OracleAlterTableDropPartition item = new OracleAlterTableDropPartition(); + item.setName(this.exprParser.name()); + stmt.getItems().add(item); + } else { + throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + } + continue; + } + + break; + } + return stmt; } + throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); } @@ -236,7 +503,11 @@ public class OracleStatementParser extends SQLStatementParser { return stmt; } - public OracleStatement parseBegin() { + public OracleStatement parseBlock() { + if (lexer.token() == Token.DECLARE) { + throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + } + accept(Token.BEGIN); OracleBlockStatement block = new OracleBlockStatement(); @@ -329,9 +600,12 @@ public class OracleStatementParser extends SQLStatementParser { accept(Token.MATCHED); accept(Token.THEN); accept(Token.INSERT); - accept(Token.LPAREN); - exprParser.exprList(insertClause.getColumns()); - accept(Token.RPAREN); + + if (lexer.token() == Token.LPAREN) { + accept(Token.LPAREN); + exprParser.exprList(insertClause.getColumns()); + accept(Token.RPAREN); + } accept(Token.VALUES); accept(Token.LPAREN); exprParser.exprList(insertClause.getValues()); @@ -355,13 +629,13 @@ public class OracleStatementParser extends SQLStatementParser { accept(Token.INSERT); List hints = new ArrayList(); - + this.createExprParser().parseHints(hints); - + if (lexer.token() == Token.INTO) { OracleInsertStatement stmt = new OracleInsertStatement(); stmt.setHints(hints); - + parseInsert0(stmt); stmt.setReturning(parseReturningClause()); @@ -430,6 +704,28 @@ public class OracleStatementParser extends SQLStatementParser { return stmt; } + private OracleExceptionStatement parseException() { + accept(Token.EXCEPTION); + OracleExceptionStatement stmt = new OracleExceptionStatement(); + + for (;;) { + accept(Token.WHEN); + OracleExceptionStatement.Item item = new OracleExceptionStatement.Item(); + item.setWhen(this.exprParser.expr()); + accept(Token.THEN); + List statements = new ArrayList(); + parseStatementList(statements, 1); + item.setStatement(statements.get(0)); + + stmt.getItems().add(item); + + if (lexer.token() != Token.WHEN) { + break; + } + } + return stmt; + } + private OracleErrorLoggingClause parseErrorLoggingClause() { if (lexer.token() == Token.LOG) { OracleErrorLoggingClause errorClause = new OracleErrorLoggingClause(); @@ -458,7 +754,7 @@ public class OracleStatementParser extends SQLStatementParser { return null; } - private OracleReturningClause parseReturningClause() { + public OracleReturningClause parseReturningClause() { OracleReturningClause clause = null; if (lexer.token() == Token.RETURNING) { @@ -487,4 +783,81 @@ public class OracleStatementParser extends SQLStatementParser { } return clause; } + + public SQLStatement parseStatement() { + List list = new ArrayList(); + + this.parseStatementList(list, 1); + + return list.get(0); + } + + public OracleExplainStatement parseExplain() { + acceptIdentifier("EXPLAIN"); + acceptIdentifier("PLAN"); + OracleExplainStatement stmt = new OracleExplainStatement(); + + if (lexer.token() == Token.SET) { + lexer.nextToken(); + acceptIdentifier("STATEMENT_ID"); + accept(Token.EQ); + stmt.setStatementId((SQLCharExpr) this.exprParser.primary()); + } + + if (lexer.token() == Token.INTO) { + lexer.nextToken(); + stmt.setInto(this.exprParser.name()); + } + + accept(Token.FOR); + stmt.setForStatement(parseStatement()); + + return stmt; + } + + public OracleDeleteStatement parseDelete() throws ParserException { + accept(Token.DELETE); + + OracleDeleteStatement deleteStatement = new OracleDeleteStatement(); + + this.createExprParser().parseHints(deleteStatement.getHints()); + + if (lexer.token() == (Token.FROM)) { + lexer.nextToken(); + } + + if (identifierEquals("ONLY")) { + lexer.nextToken(); + accept(Token.LPAREN); + + SQLName tableName = exprParser.name(); + deleteStatement.setTableName(tableName); + + accept(Token.RPAREN); + } else { + SQLName tableName = exprParser.name(); + deleteStatement.setTableName(tableName); + } + + deleteStatement.setAlias(as()); + + if (lexer.token() == (Token.WHERE)) { + lexer.nextToken(); + deleteStatement.setWhere(this.exprParser.expr()); + } + + if (lexer.token() == Token.RETURNING) { + OracleReturningClause clause = this.parseReturningClause(); + deleteStatement.setReturning(clause); + } + if (identifierEquals("RETURN") || identifierEquals("RETURNING")) { + throw new ParserException("TODO"); + } + + if (identifierEquals("LOG")) { + throw new ParserException("TODO"); + } + + return deleteStatement; + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleUpdateParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleUpdateParser.java index e147d69eca..030761fe87 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleUpdateParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleUpdateParser.java @@ -15,8 +15,9 @@ */ package com.alibaba.druid.sql.dialect.oracle.parser; -import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleUpdateSetListClause; -import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleUpdateSetListSingleColumnItem; +import com.alibaba.druid.sql.ast.expr.SQLListExpr; +import com.alibaba.druid.sql.ast.statement.SQLTableSource; +import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleUpdateStatement; import com.alibaba.druid.sql.parser.Lexer; import com.alibaba.druid.sql.parser.ParserException; @@ -44,7 +45,8 @@ public class OracleUpdateParser extends SQLStatementParser { update.setOnly(true); } - update.setTable(this.exprParser.expr()); + SQLTableSource tableSource = this.exprParser.createSelectParser().parseTableSource(); + update.setTableSource(tableSource); if ((update.getAlias() == null) || (update.getAlias().length() == 0)) { update.setAlias(as()); @@ -87,27 +89,28 @@ public class OracleUpdateParser extends SQLStatementParser { private void parseSet(OracleUpdateStatement update) throws ParserException { accept(Token.SET); - if (identifierEquals("VALUE")) { - throw new ParserException("TODO"); - } - - OracleUpdateSetListClause setListClause = new OracleUpdateSetListClause(); - while (true) { + for (;;) { + SQLUpdateSetItem item = new SQLUpdateSetItem(); + if (lexer.token() == (Token.LPAREN)) { - throw new ParserException("TODO"); + lexer.nextToken(); + SQLListExpr list = new SQLListExpr(); + this.exprParser.exprList(list.getItems()); + accept(Token.RPAREN); + item.setColumn(list); + } else { + item.setColumn(this.exprParser.primary()); } - - OracleUpdateSetListSingleColumnItem item = new OracleUpdateSetListSingleColumnItem(); - item.setColumn(this.exprParser.primary()); accept(Token.EQ); item.setValue(this.exprParser.expr()); - setListClause.getItems().add(item); + update.getItems().add(item); - if (!(lexer.token() == (Token.COMMA))) break; + if (lexer.token() != Token.COMMA) { + break; + } + lexer.nextToken(); } - - update.setSetClause(setListClause); } protected SQLExprParser createExprParser() { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVIsitorAdapter.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVIsitorAdapter.java index 466d9e71c6..cc4faebb10 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVIsitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVIsitorAdapter.java @@ -26,6 +26,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.clause.SubqueryFactoringClause.E import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAggregateExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalytic; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalyticWindowing; +import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleArgumentExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleBinaryDoubleExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleBinaryFloatExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleCursorExpr; @@ -36,11 +37,20 @@ import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleExtractExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIntervalExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIsSetExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleOuterExpr; +import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleSysdateExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleTimestampExpr; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterProcedureStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterSessionStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableDropPartition; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableSplitPartition; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableTruncatePartition; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleBlockStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleConstraintState; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExceptionStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExplainStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleGrantStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleInsertStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLockTableStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement; @@ -65,6 +75,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectRestriction.Rea import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectSubqueryTableSource; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableReference; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectUnPivot; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSetTransactionStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleTableExpr; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleUpdateSetListClause; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleUpdateSetListMultiColumnItem; @@ -821,6 +832,156 @@ public class OracleASTVIsitorAdapter extends SQLASTVisitorAdapter implements Ora @Override public void endVisit(OracleDatetimeExpr x) { + + } + + @Override + public boolean visit(OracleSysdateExpr x) { + return true; + } + + @Override + public void endVisit(OracleSysdateExpr x) { + + } + + @Override + public boolean visit(OracleExceptionStatement x) { + return true; + } + + @Override + public void endVisit(OracleExceptionStatement x) { + + } + + @Override + public boolean visit(OracleExceptionStatement.Item x) { + return true; + } + + @Override + public void endVisit(OracleExceptionStatement.Item x) { + + } + + @Override + public boolean visit(OracleArgumentExpr x) { + return true; + } + + @Override + public void endVisit(OracleArgumentExpr x) { + + } + + @Override + public boolean visit(OracleSetTransactionStatement x) { + return true; + } + + @Override + public void endVisit(OracleSetTransactionStatement x) { + + } + + @Override + public boolean visit(OracleGrantStatement x) { + return true; + } + + @Override + public void endVisit(OracleGrantStatement x) { + + } + + @Override + public boolean visit(OracleExplainStatement x) { + return true; + } + + @Override + public void endVisit(OracleExplainStatement x) { + + } + + @Override + public boolean visit(OracleAlterProcedureStatement x) { + return true; + } + + @Override + public void endVisit(OracleAlterProcedureStatement x) { + + } + + @Override + public boolean visit(OracleAlterTableDropPartition x) { + return true; + } + + @Override + public void endVisit(OracleAlterTableDropPartition x) { + + } + + @Override + public boolean visit(OracleAlterTableTruncatePartition x) { + return true; + } + + @Override + public void endVisit(OracleAlterTableTruncatePartition x) { + + } + + @Override + public boolean visit(OracleAlterTableStatement x) { + return true; + } + + @Override + public void endVisit(OracleAlterTableStatement x) { + + } + + @Override + public boolean visit(OracleAlterTableSplitPartition.TableSpaceItem x) { + return true; + } + + @Override + public void endVisit(OracleAlterTableSplitPartition.TableSpaceItem x) { + + } + + @Override + public boolean visit(OracleAlterTableSplitPartition.UpdateIndexesClause x) { + return true; + } + + @Override + public void endVisit(OracleAlterTableSplitPartition.UpdateIndexesClause x) { + + } + + @Override + public boolean visit(OracleAlterTableSplitPartition.NestedTablePartitionSpec x) { + return true; + } + + @Override + public void endVisit(OracleAlterTableSplitPartition.NestedTablePartitionSpec x) { + + } + + @Override + public boolean visit(OracleAlterTableSplitPartition x) { + return true; + } + + @Override + public void endVisit(OracleAlterTableSplitPartition x) { } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVisitor.java index 5251dd8576..197ccc61e0 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleASTVisitor.java @@ -32,6 +32,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.clause.SubqueryFactoringClause; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAggregateExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalytic; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalyticWindowing; +import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleArgumentExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleBinaryDoubleExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleBinaryFloatExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleCursorExpr; @@ -42,11 +43,20 @@ import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleExtractExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIntervalExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIsSetExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleOuterExpr; +import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleSysdateExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleTimestampExpr; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterProcedureStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterSessionStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableDropPartition; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableSplitPartition; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableTruncatePartition; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleBlockStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleConstraintState; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExceptionStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExplainStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleGrantStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleInsertStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLockTableStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement; @@ -67,6 +77,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectRestriction; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectSubqueryTableSource; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableReference; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectUnPivot; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSetTransactionStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleTableExpr; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleUpdateSetListClause; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleUpdateSetListMultiColumnItem; @@ -296,68 +307,128 @@ public interface OracleASTVisitor extends SQLASTVisitor { boolean visit(ModelClause x); void endVisit(ModelClause x); - + boolean visit(OracleMergeStatement x); - + void endVisit(OracleMergeStatement x); - + boolean visit(OracleMergeStatement.MergeUpdateClause x); - + void endVisit(OracleMergeStatement.MergeUpdateClause x); - + boolean visit(OracleMergeStatement.MergeInsertClause x); - + void endVisit(OracleMergeStatement.MergeInsertClause x); - + boolean visit(OracleErrorLoggingClause x); - + void endVisit(OracleErrorLoggingClause x); - + boolean visit(OracleReturningClause x); - + void endVisit(OracleReturningClause x); - + boolean visit(OracleInsertStatement x); - + void endVisit(OracleInsertStatement x); - + boolean visit(InsertIntoClause x); - + void endVisit(InsertIntoClause x); - + boolean visit(OracleMultiInsertStatement x); - + void endVisit(OracleMultiInsertStatement x); - + boolean visit(ConditionalInsertClause x); - + void endVisit(ConditionalInsertClause x); - + boolean visit(ConditionalInsertClauseItem x); - + void endVisit(ConditionalInsertClauseItem x); - + boolean visit(OracleSelectQueryBlock x); - + void endVisit(OracleSelectQueryBlock x); - + boolean visit(OracleBlockStatement x); - + void endVisit(OracleBlockStatement x); - + boolean visit(OracleLockTableStatement x); - + void endVisit(OracleLockTableStatement x); - + boolean visit(OracleAlterSessionStatement x); - + void endVisit(OracleAlterSessionStatement x); - + boolean visit(OracleMethodInvokeStatement x); - + void endVisit(OracleMethodInvokeStatement x); - + boolean visit(OracleDatetimeExpr x); - + void endVisit(OracleDatetimeExpr x); + + boolean visit(OracleSysdateExpr x); + + void endVisit(OracleSysdateExpr x); + + boolean visit(OracleExceptionStatement x); + + void endVisit(OracleExceptionStatement x); + + boolean visit(OracleExceptionStatement.Item x); + + void endVisit(OracleExceptionStatement.Item x); + + boolean visit(OracleArgumentExpr x); + + void endVisit(OracleArgumentExpr x); + + boolean visit(OracleSetTransactionStatement x); + + void endVisit(OracleSetTransactionStatement x); + + boolean visit(OracleGrantStatement x); + + void endVisit(OracleGrantStatement x); + + boolean visit(OracleExplainStatement x); + + void endVisit(OracleExplainStatement x); + + boolean visit(OracleAlterProcedureStatement x); + + void endVisit(OracleAlterProcedureStatement x); + + boolean visit(OracleAlterTableDropPartition x); + + void endVisit(OracleAlterTableDropPartition x); + + boolean visit(OracleAlterTableTruncatePartition x); + + void endVisit(OracleAlterTableTruncatePartition x); + + boolean visit(OracleAlterTableStatement x); + + void endVisit(OracleAlterTableStatement x); + + boolean visit(OracleAlterTableSplitPartition.TableSpaceItem x); + + void endVisit(OracleAlterTableSplitPartition.TableSpaceItem x); + + boolean visit(OracleAlterTableSplitPartition.UpdateIndexesClause x); + + void endVisit(OracleAlterTableSplitPartition.UpdateIndexesClause x); + + boolean visit(OracleAlterTableSplitPartition.NestedTablePartitionSpec x); + + void endVisit(OracleAlterTableSplitPartition.NestedTablePartitionSpec x); + + boolean visit(OracleAlterTableSplitPartition x); + + void endVisit(OracleAlterTableSplitPartition x); } 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 697395a5cb..58d914ebd3 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 @@ -59,6 +59,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.clause.SubqueryFactoringClause; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAggregateExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalytic; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalyticWindowing; +import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleArgumentExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleBinaryDoubleExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleBinaryFloatExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleCursorExpr; @@ -69,11 +70,24 @@ import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleExtractExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIntervalExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIsSetExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleOuterExpr; +import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleSysdateExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleTimestampExpr; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterProcedureStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterSessionStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableDropPartition; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableItem; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableSplitPartition; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableSplitPartition.NestedTablePartitionSpec; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableSplitPartition.TableSpaceItem; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableSplitPartition.UpdateIndexesClause; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableTruncatePartition; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleBlockStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleConstraintState; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExceptionStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExplainStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleGrantStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleInsertStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLockTableStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement; @@ -99,6 +113,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectRestriction.Rea import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectSubqueryTableSource; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableReference; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectUnPivot; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSetTransactionStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleTableExpr; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleUpdateSetListClause; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleUpdateSetListMultiColumnItem; @@ -128,12 +143,19 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS } private void printHints(List hints) { - if (hints.size() > 0) throw new UnsupportedOperationException(); + if (hints.size() > 0) { + print("/*+ "); + printAndAccept(hints, ", "); + print(" */"); + } } public boolean visit(OracleAggregateExpr expr) { expr.getMethodName().accept(this); print("("); + if (expr.isUnique()) { + print("UNIQUE "); + } printAndAccept(expr.getArguments(), ", "); print(")"); @@ -218,6 +240,11 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS print("WHERE "); x.getWhere().accept(this); } + + if (x.getReturning() != null) { + println(); + x.getReturning().accept(this); + } return false; } @@ -337,6 +364,15 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS printAndAccept(x.getOf(), ", "); print(")"); } + + if (x.isNotWait()) { + print(" NOWAIT"); + } else if (x.isSkipLocked()) { + print(" SKIP LOCKED"); + } else if (x.getWait() != null) { + print(" WAIT "); + x.getWait().accept(this); + } return false; } @@ -475,6 +511,12 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS } printSelectList(select.getSelectList()); + + if (select.getInto() != null) { + println(); + print("INTO "); + select.getInto().accept(this); + } println(); print("FROM "); @@ -571,6 +613,10 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS x.getPartition().accept(this); } } + + if (x.getHints().size() > 0) { + this.printHints(x.getHints()); + } if (x.getSampleClause() != null) { println(); @@ -709,17 +755,23 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS if (x.isOnly()) { print("ONLY ("); - x.getTable().accept(this); + x.getTableSource().accept(this); print(")"); } else { - x.getTable().accept(this); + x.getTableSource().accept(this); } printAlias(x.getAlias()); println(); - x.getSetClause().accept(this); + print("SET "); + for (int i = 0, size = x.getItems().size(); i < size; ++i) { + if (i != 0) { + print(", "); + } + x.getItems().get(i).accept(this); + } if (x.getWhere() != null) { println(); @@ -906,7 +958,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS } print("("); - print(x.getPercent()); + printAndAccept(x.getPercent(), ", "); print(")"); if (x.getSeedValue() != null) { @@ -1418,8 +1470,11 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS @Override public boolean visit(MergeInsertClause x) { - print("WHEN NOT MATCHED THEN INSERT "); - printAndAccept(x.getColumns(), ", "); + print("WHEN NOT MATCHED THEN INSERT"); + if (x.getColumns().size() > 0) { + print(" "); + printAndAccept(x.getColumns(), ", "); + } print(" VALUES ("); printAndAccept(x.getValues(), ", "); print(")"); @@ -1719,4 +1774,270 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS public void endVisit(OracleDatetimeExpr x) { } + + @Override + public boolean visit(OracleSysdateExpr x) { + print("SYSDATE"); + if (x.getOption() != null) { + print("@"); + print(x.getOption()); + } + return false; + } + + @Override + public void endVisit(OracleSysdateExpr x) { + + } + + @Override + public void endVisit(com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExceptionStatement.Item x) { + + } + + @Override + public boolean visit(com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExceptionStatement.Item x) { + print("WHEN "); + x.getWhen().accept(this); + incrementIndent(); + println(); + x.getStatement().accept(this); + decrementIndent(); + return false; + } + + @Override + public boolean visit(OracleExceptionStatement x) { + print("EXCEPTION"); + incrementIndent(); + for (OracleExceptionStatement.Item item : x.getItems()) { + println(); + item.accept(this); + } + decrementIndent(); + return false; + } + + @Override + public void endVisit(OracleExceptionStatement x) { + + } + + @Override + public boolean visit(OracleArgumentExpr x) { + print(x.getArgumentName()); + print(" => "); + x.getValue().accept(this); + return false; + } + + @Override + public void endVisit(OracleArgumentExpr x) { + + } + + @Override + public boolean visit(OracleSetTransactionStatement x) { + print("SET TRANSACTION NAME "); + x.getName().accept(this); + return false; + } + + @Override + public void endVisit(OracleSetTransactionStatement x) { + + } + + @Override + public boolean visit(OracleGrantStatement x) { + print("GRANT "); + for (int i = 0, size = x.getPrivileges().size(); i < size; ++i) { + if (i != 0) { + print(", "); + } + print(x.getPrivileges().get(i)); + } + + if (x.getOn() != null) { + print(" ON "); + x.getOn().accept(this); + } + return false; + } + + @Override + public void endVisit(OracleGrantStatement x) { + + } + + @Override + public boolean visit(OracleExplainStatement x) { + print("XPLAIN PLAN"); + incrementIndent(); + println(); + if (x.getStatementId() != null) { + print("SET STATEMENT_ID = "); + x.getStatementId().accept(this); + println(); + } + + if (x.getInto() != null) { + print("INTO "); + x.getInto().accept(this); + println(); + } + + print("FRO"); + println(); + x.getForStatement().accept(this); + + decrementIndent(); + return false; + } + + @Override + public void endVisit(OracleExplainStatement x) { + + } + + @Override + public boolean visit(OracleAlterProcedureStatement x) { + print("ALTER PROCEDURE "); + x.getName().accept(this); + if (x.isCompile()) { + print(" COMPILE"); + } + if (x.isReuseSettings()) { + print(" REUSE SETTINGS"); + } + return false; + } + + @Override + public void endVisit(OracleAlterProcedureStatement x) { + + } + + @Override + public boolean visit(OracleAlterTableDropPartition x) { + print("DROP PARTITION "); + x.getName().accept(this); + return false; + } + + @Override + public void endVisit(OracleAlterTableDropPartition x) { + + } + + @Override + public boolean visit(OracleAlterTableStatement x) { + print("ALTER TABLE "); + x.getName().accept(this); + incrementIndent(); + for (OracleAlterTableItem item : x.getItems()) { + println(); + item.accept(this); + } + decrementIndent(); + return false; + } + + @Override + public void endVisit(OracleAlterTableStatement x) { + + } + + @Override + public boolean visit(OracleAlterTableTruncatePartition x) { + print("TRUNCATE PARTITION "); + x.getName().accept(this); + return false; + } + + @Override + public void endVisit(OracleAlterTableTruncatePartition x) { + + } + + @Override + public boolean visit(TableSpaceItem x) { + print("TABLESPACE "); + x.getTablespace().accept(this); + return false; + } + + @Override + public void endVisit(TableSpaceItem x) { + + } + + @Override + public boolean visit(UpdateIndexesClause x) { + print("UPDATE INDEXES"); + if (x.getItems().size() > 0) { + print("("); + printAndAccept(x.getItems(), ", "); + print(")"); + } + return false; + } + + @Override + public void endVisit(UpdateIndexesClause x) { + + } + + @Override + public boolean visit(OracleAlterTableSplitPartition x) { + print("SPLIT PARTITION "); + x.getName().accept(this); + + if (x.getAt().size() > 0) { + incrementIndent(); + println(); + print("AT ("); + printAndAccept(x.getAt(), ", "); + print(")"); + decrementIndent(); + } + + if (x.getInto().size() > 0) { + println(); + incrementIndent(); + print("INTO ("); + printAndAccept(x.getInto(), ", "); + print(")"); + decrementIndent(); + } + + if (x.getUpdateIndexes() != null) { + println(); + incrementIndent(); + x.getUpdateIndexes().accept(this); + decrementIndent(); + } + return false; + } + + @Override + public void endVisit(OracleAlterTableSplitPartition x) { + + } + + @Override + public boolean visit(NestedTablePartitionSpec x) { + print("PARTITION "); + x.getPartition().accept(this); + for (SQLObject item : x.getSegmentAttributeItems()) { + print(" "); + item.accept(this); + } + return false; + } + + @Override + public void endVisit(NestedTablePartitionSpec x) { + + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleSchemaStatVisitor.java index dde9148e35..a13dba3118 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleSchemaStatVisitor.java @@ -13,9 +13,11 @@ import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; import com.alibaba.druid.sql.ast.expr.SQLObjectCreateExpr; import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; +import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; import com.alibaba.druid.sql.ast.statement.SQLSelect; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; +import com.alibaba.druid.sql.ast.statement.SQLTableSource; import com.alibaba.druid.sql.dialect.oracle.ast.OracleHint; import com.alibaba.druid.sql.dialect.oracle.ast.OracleOrderBy; import com.alibaba.druid.sql.dialect.oracle.ast.clause.CycleClause; @@ -41,6 +43,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.clause.SubqueryFactoringClause.E import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAggregateExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalytic; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalyticWindowing; +import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleArgumentExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleBinaryDoubleExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleBinaryFloatExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleCursorExpr; @@ -51,11 +54,20 @@ import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleExtractExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIntervalExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIsSetExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleOuterExpr; +import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleSysdateExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleTimestampExpr; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterProcedureStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterSessionStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableDropPartition; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableSplitPartition; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableTruncatePartition; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleBlockStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleConstraintState; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExceptionStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExplainStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleGrantStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleInsertStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLockTableStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement; @@ -80,6 +92,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectRestriction.Rea import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectSubqueryTableSource; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableReference; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectUnPivot; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSetTransactionStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleTableExpr; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleUpdateSetListClause; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleUpdateSetListMultiColumnItem; @@ -217,9 +230,17 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle public boolean visit(OracleUpdateStatement x) { aliasLocal.set(new HashMap()); + setMode(x, Mode.Update); - if (x.getTable() instanceof SQLIdentifierExpr) { - String ident = x.getTable().toString(); + SQLTableSource tableSource = x.getTableSource(); + SQLExpr tableExpr = null; + + if (tableSource instanceof SQLExprTableSource) { + tableExpr = ((SQLExprTableSource) tableSource).getExpr(); + } + + if (tableExpr instanceof SQLIdentifierExpr) { + String ident = tableExpr.toString(); currentTableLocal.set(ident); TableStat stat = tableStats.get(ident); @@ -232,7 +253,7 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle Map aliasMap = aliasLocal.get(); aliasMap.put(ident, ident); } else { - accept(x.getTable()); + tableSource.accept(this); } accept(x.getSetClause()); @@ -1114,15 +1135,15 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle public void endVisit(OracleAlterSessionStatement x) { } - + @Override public boolean visit(OracleMethodInvokeStatement x) { return false; } - + @Override public void endVisit(OracleMethodInvokeStatement x) { - + } @Override @@ -1145,6 +1166,163 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle @Override public void endVisit(OracleDatetimeExpr x) { - + + } + + @Override + public boolean visit(OracleSysdateExpr x) { + return false; + } + + @Override + public void endVisit(OracleSysdateExpr x) { + + } + + @Override + public void endVisit(com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExceptionStatement.Item x) { + + } + + @Override + public boolean visit(com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExceptionStatement.Item x) { + return true; + } + + @Override + public boolean visit(OracleExceptionStatement x) { + return true; + } + + @Override + public void endVisit(OracleExceptionStatement x) { + + } + + @Override + public boolean visit(OracleArgumentExpr x) { + return true; + } + + @Override + public void endVisit(OracleArgumentExpr x) { + + } + + @Override + public boolean visit(OracleSetTransactionStatement x) { + return false; + } + + @Override + public void endVisit(OracleSetTransactionStatement x) { + + } + + @Override + public boolean visit(OracleGrantStatement x) { + return false; + } + + @Override + public void endVisit(OracleGrantStatement x) { + + } + + @Override + public boolean visit(OracleExplainStatement x) { + return false; + } + + @Override + public void endVisit(OracleExplainStatement x) { + + } + + @Override + public boolean visit(OracleAlterProcedureStatement x) { + return false; + } + + @Override + public void endVisit(OracleAlterProcedureStatement x) { + + } + + @Override + public boolean visit(OracleAlterTableDropPartition x) { + return false; + } + + @Override + public void endVisit(OracleAlterTableDropPartition x) { + + } + + @Override + public boolean visit(OracleAlterTableTruncatePartition x) { + return false; + } + + @Override + public void endVisit(OracleAlterTableTruncatePartition x) { + + } + + @Override + public boolean visit(OracleAlterTableStatement x) { + String tableName = x.getName().toString(); + TableStat stat = new TableStat(); + stat.incrementAlterCount(); + this.tableStats.put(new TableStat.Name(tableName), stat); + + accept(x.getItems()); + + return false; + } + + @Override + public void endVisit(OracleAlterTableStatement x) { + + } + + @Override + public boolean visit(OracleAlterTableSplitPartition.TableSpaceItem x) { + return false; + } + + @Override + public void endVisit(OracleAlterTableSplitPartition.TableSpaceItem x) { + + } + + @Override + public boolean visit(OracleAlterTableSplitPartition.UpdateIndexesClause x) { + return false; + } + + @Override + public void endVisit(OracleAlterTableSplitPartition.UpdateIndexesClause x) { + + } + + @Override + public boolean visit(OracleAlterTableSplitPartition.NestedTablePartitionSpec x) { + return false; + } + + @Override + public void endVisit(OracleAlterTableSplitPartition.NestedTablePartitionSpec x) { + + } + + @Override + public boolean visit(OracleAlterTableSplitPartition x) { + return false; + } + + @Override + public void endVisit(OracleAlterTableSplitPartition x) { + } } diff --git a/src/main/java/com/alibaba/druid/sql/parser/Lexer.java b/src/main/java/com/alibaba/druid/sql/parser/Lexer.java index df4a27bb42..70e8e36ac1 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Lexer.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Lexer.java @@ -296,11 +296,24 @@ public class Lexer { case '@': scanVariable(); return; + case '-': + int subNextChar = buf[bp + 1]; + if (subNextChar == '-') { + scanComment(); + if ((token() == Token.LINE_COMMENT || token() == Token.MULTI_LINE_COMMENT) && skipComment) { + sp = 0; + continue; + } + } else { + scanOperator(); + } + return; case '/': int nextChar = buf[bp + 1]; if (nextChar == '/' || nextChar == '*') { scanComment(); if ((token() == Token.LINE_COMMENT || token() == Token.MULTI_LINE_COMMENT) && skipComment) { + sp = 0; continue; } } else { @@ -856,6 +869,20 @@ public class Lexer { return result; } } + + public int bp() { + return this.bp; + } + + public char current() { + return this.ch; + } + + public void reset(int mark, char mark_ch, Token token) { + this.bp = mark; + this.ch = mark_ch; + this.token = token; + } public final String numberString() { return new String(buf, np, sp); 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 9341d813a1..2276ff82e9 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -209,6 +209,9 @@ public class SQLExprParser extends SQLParser { case TIME: case ZONE: case LOG: + case LIMIT: + case SCHEMA: + case AT: sqlExpr = new SQLIdentifierExpr(lexer.stringVal()); lexer.nextToken(); break; @@ -372,6 +375,13 @@ public class SQLExprParser extends SQLParser { case INTERVAL: sqlExpr = parseInterval(); break; + case COLON: + lexer.nextToken(); + if (lexer.token == Token.LITERAL_ALIAS) { + sqlExpr = new SQLVariantRefExpr(":\"" + lexer.stringVal() + "\""); + lexer.nextToken(); + } + break; case ANY: lexer.nextToken(); if (lexer.token() == Token.LPAREN) { @@ -416,7 +426,7 @@ public class SQLExprParser extends SQLParser { sqlExpr = allExpr; break; default: - throw new ParserException("ERROR. token : " + tok); + throw new ParserException("ERROR. token : " + tok + " " + lexer.stringVal()); } return primaryRest(sqlExpr); @@ -438,39 +448,56 @@ public class SQLExprParser extends SQLParser { if (lexer.token() == Token.DOT) { lexer.nextToken(); expr = dotRest(expr); + return primaryRest(expr); } else if (lexer.token() == Token.COLONEQ) { lexer.nextToken(); SQLExpr rightExp = primary(); expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Assignment, rightExp); } else { if (lexer.token() == Token.LPAREN) { - if (expr instanceof SQLIdentifierExpr || expr instanceof SQLDefaultExpr) { - String method_name = expr.toString(); - lexer.nextToken(); - - if (isAggreateFunction(method_name)) { - SQLAggregateExpr aggregateExpr = parseAggregateExpr(method_name); - - return aggregateExpr; - } - - SQLMethodInvokeExpr methodInvokeExpr = new SQLMethodInvokeExpr(method_name); - if (lexer.token() != Token.RPAREN) { - exprList(methodInvokeExpr.getParameters()); - } - - accept(Token.RPAREN); - - return primaryRest(methodInvokeExpr); - } - - throw new ParserException("not support token:" + lexer.token()); + return methodRest(expr, true); } } return expr; } + protected SQLExpr methodRest(SQLExpr expr, boolean acceptLPAREN) { + if (acceptLPAREN) { + accept(Token.LPAREN); + } + + if (expr instanceof SQLName || expr instanceof SQLDefaultExpr) { + String method_name; + + SQLMethodInvokeExpr methodInvokeExpr; + if (expr instanceof SQLPropertyExpr) { + method_name = ((SQLPropertyExpr) expr).getName(); + methodInvokeExpr = new SQLMethodInvokeExpr(method_name); + methodInvokeExpr.setOwner(((SQLPropertyExpr) expr).getOwner()); + } else { + method_name = expr.toString(); + methodInvokeExpr = new SQLMethodInvokeExpr(method_name); + } + + if (isAggreateFunction(method_name)) { + SQLAggregateExpr aggregateExpr = parseAggregateExpr(method_name); + + return aggregateExpr; + } + + if (lexer.token() != Token.RPAREN) { + exprList(methodInvokeExpr.getParameters()); + } + + accept(Token.RPAREN); + + return primaryRest(methodInvokeExpr); + } + + throw new ParserException("not support token:" + lexer.token()); + } + protected SQLExpr dotRest(SQLExpr expr) { if (lexer.token() == Token.STAR) { lexer.nextToken(); @@ -478,7 +505,8 @@ public class SQLExprParser extends SQLParser { } else { String name; - if (lexer.token() == Token.IDENTIFIER || lexer.token() == Token.LITERAL_CHARS || lexer.token() == Token.LITERAL_ALIAS) { + if (lexer.token() == Token.IDENTIFIER || lexer.token() == Token.LITERAL_CHARS + || lexer.token() == Token.LITERAL_ALIAS) { name = lexer.stringVal(); lexer.nextToken(); } else if (lexer.getKeywods().containsValue(lexer.token())) { @@ -569,16 +597,17 @@ public class SQLExprParser extends SQLParser { SQLName name = new SQLIdentifierExpr(identName); - if (lexer.token() == Token.DOT) { + while (lexer.token() == Token.DOT) { lexer.nextToken(); - + if (lexer.token() == Token.KEY) { name = new SQLPropertyExpr(name, "KEY"); lexer.nextToken(); return name; } - if (lexer.token() != Token.LITERAL_ALIAS && lexer.token() != Token.IDENTIFIER) { + if (lexer.token() != Token.LITERAL_ALIAS && lexer.token() != Token.IDENTIFIER + && (!lexer.getKeywods().containsValue(lexer.token()))) { throw new ParserException("error, " + lexer.token()); } @@ -612,6 +641,7 @@ public class SQLExprParser extends SQLParser { } else { aggregateExpr = new SQLAggregateExpr(method_name, 1); } + exprList(aggregateExpr.getArguments()); accept(Token.RPAREN); @@ -695,7 +725,7 @@ public class SQLExprParser extends SQLParser { return equalityRest(expr); } - public final SQLExpr equalityRest(SQLExpr expr) throws ParserException { + public SQLExpr equalityRest(SQLExpr expr) throws ParserException { SQLExpr rightExp; if (lexer.token() == Token.EQ) { lexer.nextToken(); @@ -997,13 +1027,13 @@ public class SQLExprParser extends SQLParser { } public SQLDataType parseDataType() throws ParserException { - if (lexer.token() != Token.IDENTIFIER) { - throw new ParserException(); + if (lexer.token() != Token.DATE && lexer.token() != Token.TIMESTAMP && lexer.token() != Token.IDENTIFIER) { + throw new ParserException("unexpect token : " + lexer.token() + " " + lexer.stringVal()); } - String typeName = lexer.stringVal(); + SQLName typeExpr = name(); + String typeName = typeExpr.toString(); - lexer.nextToken(); SQLDataType dataType = new SQLDataTypeImpl(typeName); if (lexer.token() == Token.LPAREN) { lexer.nextToken(); diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java index 9d1b4be687..516aca0e8a 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java @@ -65,7 +65,8 @@ public class SQLParser { return alias; } - if (lexer.token() == Token.YEAR || lexer.token() == Token.DAY || lexer.token() == Token.KEY || lexer.token() == Token.CASE) { + if (lexer.token() == Token.YEAR || lexer.token() == Token.DAY || lexer.token() == Token.KEY + || lexer.token() == Token.CASE || lexer.token() == Token.TIMESTAMP) { alias = lexer.token.name(); lexer.nextToken(); return alias; @@ -92,7 +93,9 @@ public class SQLParser { } else if (lexer.token() == Token.LITERAL_CHARS) { alias = "'" + lexer.stringVal() + "'"; lexer.nextToken(); - } else if (lexer.token() == Token.YEAR || lexer.token() == Token.DAY || lexer.token() == Token.CASE) { + } else if (lexer.token() == Token.YEAR || lexer.token() == Token.DAY || lexer.token() == Token.TIME + || lexer.token() == Token.MONTH || lexer.token() == Token.CASE || lexer.token() == Token.AT + || lexer.token() == Token.TIMESTAMP) { alias = lexer.token.name(); lexer.nextToken(); } diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java index ea6b7d98ef..5daa4c4bcc 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java @@ -24,6 +24,7 @@ import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLQueryExpr; import com.alibaba.druid.sql.ast.statement.SQLAssignItem; import com.alibaba.druid.sql.ast.statement.SQLCallStatement; +import com.alibaba.druid.sql.ast.statement.SQLCommentStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateViewStatement; import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; @@ -36,6 +37,7 @@ import com.alibaba.druid.sql.ast.statement.SQLTableSource; import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement; import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem; import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleSelectParser; public class SQLStatementParser extends SQLParser { @@ -250,7 +252,7 @@ public class SQLStatementParser extends SQLParser { return stmt; } - public SQLSetStatement parseSet() throws ParserException { + public SQLStatement parseSet() throws ParserException { accept(Token.SET); SQLSetStatement stmt = new SQLSetStatement(); @@ -299,7 +301,7 @@ public class SQLStatementParser extends SQLParser { } public SQLSelectParser createSQLSelectParser() { - return new SQLSelectParser(this.lexer); + return new OracleSelectParser(this.lexer); } public SQLUpdateStatement parseUpdateStatement() throws ParserException { @@ -383,4 +385,25 @@ public class SQLStatementParser extends SQLParser { return createView; } + public SQLCommentStatement parseComment() { + accept(Token.COMMENT); + SQLCommentStatement stmt = new SQLCommentStatement(); + + accept(Token.ON); + + if (lexer.token() == Token.TABLE) { + stmt.setType(SQLCommentStatement.Type.TABLE); + lexer.nextToken(); + } else if (lexer.token() == Token.COLUMN) { + stmt.setType(SQLCommentStatement.Type.COLUMN); + lexer.nextToken(); + } + + stmt.setOn(this.exprParser.name()); + + accept(Token.IS); + stmt.setComment(this.exprParser.expr()); + + return stmt; + } } diff --git a/src/main/java/com/alibaba/druid/sql/parser/Token.java b/src/main/java/com/alibaba/druid/sql/parser/Token.java index 13256b5729..ef90c2699c 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Token.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Token.java @@ -68,6 +68,7 @@ public enum Token { SCHEMA("SCHEMA"), CAST("CAST"), USER("USER"), + COLUMN("COLUMN"), AND("AND"), OR("OR"), @@ -128,6 +129,7 @@ public enum Token { USING("USING"), CURRENT("CURRENT"), RETURNING("RETURNING"), + COMMENT("COMMENT"), // oracle START("START"), @@ -157,10 +159,15 @@ public enum Token { WAIT("WAIT"), ADVISE("ADVISE"), SESSION("SESSION"), + PROCEDURE("PROCEDURE"), AT("AT"), LOCAL("LOCAL"), TIME("TIME"), ZONE("ZONE"), + SYSDATE("SYSDATE"), + DECLARE("DECLARE"), + EXCEPTION("EXCEPTION"), + GRANT("GRANT"), // transact-sql TOP("TOP"), 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 9552454a25..1aa3d2d492 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -66,6 +66,7 @@ import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; import com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause; import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource; import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource.JoinType; +import com.alibaba.druid.sql.ast.statement.SQLCommentStatement; import com.alibaba.druid.sql.ast.statement.SQLSelect; import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause; import com.alibaba.druid.sql.ast.statement.SQLSelectItem; @@ -893,4 +894,24 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter { print("DEFAULT"); return false; } + + @Override + public void endVisit(SQLCommentStatement x) { + + } + + @Override + public boolean visit(SQLCommentStatement x) { + print("COMMENT ON "); + if (x.getType() != null) { + print(x.getType().name()); + print(" "); + } + x.getOn().accept(this); + + print(" IS "); + x.getComment().accept(this); + + return false; + } } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java index 69a17a2792..ca8c26fc54 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java @@ -50,10 +50,11 @@ import com.alibaba.druid.sql.ast.expr.SQLQueryExpr; import com.alibaba.druid.sql.ast.expr.SQLSomeExpr; import com.alibaba.druid.sql.ast.expr.SQLUnaryExpr; import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; -import com.alibaba.druid.sql.ast.statement.SQLAssignItem; import com.alibaba.druid.sql.ast.statement.NotNullConstraint; +import com.alibaba.druid.sql.ast.statement.SQLAssignItem; import com.alibaba.druid.sql.ast.statement.SQLCallStatement; import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition; +import com.alibaba.druid.sql.ast.statement.SQLCommentStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateViewStatement; import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; @@ -325,4 +326,8 @@ public interface SQLASTVisitor { void endVisit(SQLDefaultExpr x); boolean visit(SQLDefaultExpr x); + + void endVisit(SQLCommentStatement x); + + boolean visit(SQLCommentStatement x); } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java index 86dfc3005b..abbe060875 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java @@ -54,6 +54,7 @@ import com.alibaba.druid.sql.ast.statement.SQLAssignItem; import com.alibaba.druid.sql.ast.statement.NotNullConstraint; import com.alibaba.druid.sql.ast.statement.SQLCallStatement; import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition; +import com.alibaba.druid.sql.ast.statement.SQLCommentStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateViewStatement; import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; @@ -562,4 +563,14 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor { public boolean visit(SQLDefaultExpr x) { return true; } + + @Override + public void endVisit(SQLCommentStatement x) { + + } + + @Override + public boolean visit(SQLCommentStatement x) { + return true; + } } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java index b704ab865e..08a6ef2cea 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java @@ -22,6 +22,7 @@ import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; import com.alibaba.druid.sql.ast.statement.SQLCallStatement; import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition; +import com.alibaba.druid.sql.ast.statement.SQLCommentStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement; @@ -403,8 +404,10 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { } } - x.getFrom().accept(this); // 提前执行,获得aliasMap - + if (x.getFrom() != null) { + x.getFrom().accept(this); // 提前执行,获得aliasMap + } + if (x.getWhere() != null) { x.getWhere().setParent(x); } @@ -759,4 +762,14 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { public boolean visit(SQLCallStatement x) { return false; } + + @Override + public void endVisit(SQLCommentStatement x) { + + } + + @Override + public boolean visit(SQLCommentStatement x) { + return false; + } } diff --git a/src/main/java/com/alibaba/druid/stat/TableStat.java b/src/main/java/com/alibaba/druid/stat/TableStat.java index 74a7f0e815..f87527e7a1 100644 --- a/src/main/java/com/alibaba/druid/stat/TableStat.java +++ b/src/main/java/com/alibaba/druid/stat/TableStat.java @@ -24,6 +24,15 @@ public class TableStat { int dropCount = 0; int mergeCount = 0; int createCount = 0; + int alterCount = 0; + + public int getAlterCount() { + return alterCount; + } + + public void incrementAlterCount() { + this.alterCount++; + } public int getCreateCount() { return createCount; @@ -124,6 +133,9 @@ public class TableStat { if (createCount > 0) { buf.append("Create"); } + if (alterCount > 0) { + buf.append("Alter"); + } return buf.toString(); } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleAlterProcedureTest.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleAlterProcedureTest.java new file mode 100644 index 0000000000..b98e75f348 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleAlterProcedureTest.java @@ -0,0 +1,44 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; + +public class OracleAlterProcedureTest extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "alter PROCEDURE ALIBABA1949.SP_BUILD_WS_DEGRADE_EMAIL compile "; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(0, visitor.getTables().size()); + + // Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("\"DUAL\""))); + + Assert.assertEquals(0, visitor.getColumns().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "*"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleAlterProcedureTest2.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleAlterProcedureTest2.java new file mode 100644 index 0000000000..c586819f1d --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleAlterProcedureTest2.java @@ -0,0 +1,44 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; + +public class OracleAlterProcedureTest2 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "ALTER PROCEDURE \"ALIBABA1949\".\"FIX_PRODUCT_ADDITION_YZS_0210\" COMPILE REUSE SETTINGS"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(0, visitor.getTables().size()); + + // Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("\"DUAL\""))); + + Assert.assertEquals(0, visitor.getColumns().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "*"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleAlterTableTest.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleAlterTableTest.java new file mode 100644 index 0000000000..0324f7f38a --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleAlterTableTest.java @@ -0,0 +1,45 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleAlterTableTest extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "alter table WRH$_SERVICE_WAIT_CLASS drop partition WRH$_SERVIC_1870432296_13478"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("WRH$_SERVICE_WAIT_CLASS"))); + + Assert.assertEquals(0, visitor.getColumns().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "*"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleAlterTableTest2.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleAlterTableTest2.java new file mode 100644 index 0000000000..3e24c0053a --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleAlterTableTest2.java @@ -0,0 +1,45 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleAlterTableTest2 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "alter table cdc.en_complaint_ipr_stat_fdt0 truncate partition AUTO_P_2012_02_14"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("cdc.en_complaint_ipr_stat_fdt0"))); + + Assert.assertEquals(0, visitor.getColumns().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "*"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleAlterTableTest3.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleAlterTableTest3.java new file mode 100644 index 0000000000..ccb784879b --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleAlterTableTest3.java @@ -0,0 +1,49 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleAlterTableTest3 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "alter table WRH$_ROWCACHE_SUMMARY split partition WRH$_ROWCAC_1870432296_13862 " // + + " at (1870432296,13910) " // + + " into (partition WRH$_ROWCAC_1870432296_13862 tablespace SYSAUX, partition WRH$_ROWCAC_1870432296_13910 tablespace SYSAUX" // + + ") " + // + " update indexes"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("cdc.en_complaint_ipr_stat_fdt0"))); + + Assert.assertEquals(0, visitor.getColumns().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "*"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest.java new file mode 100644 index 0000000000..fdd482bd2d --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest.java @@ -0,0 +1,49 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleBlockTest extends OracleTest { + + public void test_0() throws Exception { + String sql = "BEGIN :RESULT := \"SYS\".\"DBMS_AQ_IMPORT_INTERNAL\".\"AQ_EXPORT_CHECK\"(:arg); END;"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(2, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("departments"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees"))); + + Assert.assertEquals(7, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("departments", "department_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "department_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "employee_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "commission_pct"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "department_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("UNKNOWN", "job_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("UNKNOWN", "location_id"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCallTest.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCallTest.java new file mode 100644 index 0000000000..5d6d27c935 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCallTest.java @@ -0,0 +1,49 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleCallTest extends OracleTest { + + public void test_0() throws Exception { + String sql = "call ORACLE_OCM.MGMT_CONFIG.collect_config ( )"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(2, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("departments"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees"))); + + Assert.assertEquals(7, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("departments", "department_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "department_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "employee_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "commission_pct"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "department_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("UNKNOWN", "job_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("UNKNOWN", "location_id"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleExplainTest.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleExplainTest.java new file mode 100644 index 0000000000..82569b05c1 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleExplainTest.java @@ -0,0 +1,45 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleExplainTest extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "EXPLAIN PLAN SET STATEMENT_ID='PLUS19628905' FOR select * from( select row_.*, rownum rownum_ from( SELECT h.id taskId, t.id tradeId, t.OUT_ORDER_ID orderId, t.SELLER_SEQ sellerSeq, t.BUYER_SEQ buyerSeq, h.RECORD_TYPE recordType, t.SELLER_LOGIN_ID sellerLoginId, t.SELLER_ADMIN_SEQ sellerAdminSeq, h.GMT_CREATE gmtTaskCreate, h.GMT_MODIFIED gmtTaskModified, h.GMT_FETCH_TASK gmtFetchTask, h.GMT_FINISH_TASK gmtFinishTask, h.STATUS status, h.OWNER owner FROM HT_TASK_TRADE_HISTORY h, escrow_trade t WHERE h.TRADE_ID= t.ID and h.OWNER='zhoufei.zhangzf' and h.STATUS in('running') ORDER BY h.TASK_FLOW_LEVEL, t.GMT_CREATE, h.GMT_MODIFIED DESC) row_ where rownum<= 100) where rownum_>= 80"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(0, visitor.getTables().size()); + + // Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("\"DUAL\""))); + + Assert.assertEquals(0, visitor.getColumns().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "*"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleExplainTest2.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleExplainTest2.java new file mode 100644 index 0000000000..87dcbb456e --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleExplainTest2.java @@ -0,0 +1,52 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleExplainTest2 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "EXPLAIN PLAN " + // + " SET STATEMENT_ID = 'Raise in Tokyo' " + // + " INTO plan_table " + // + " FOR UPDATE employees " + // + " SET salary = salary * 1.10 " + // + " WHERE department_id = " + // + " (SELECT department_id FROM departments" + // + " WHERE location_id = 1700); "; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(0, visitor.getTables().size()); + +// Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("\"DUAL\""))); + + Assert.assertEquals(0, visitor.getColumns().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "*"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleGrantTest.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleGrantTest.java new file mode 100644 index 0000000000..77bb25344d --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleGrantTest.java @@ -0,0 +1,49 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleGrantTest extends OracleTest { + + public void test_0() throws Exception { + String sql = "grant all on p4p_pro"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(0, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("departments"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees"))); + + Assert.assertEquals(7, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("departments", "department_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "department_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "employee_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "commission_pct"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "department_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("UNKNOWN", "job_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("UNKNOWN", "location_id"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleInsertTest5.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleInsertTest5.java new file mode 100644 index 0000000000..f06057152d --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleInsertTest5.java @@ -0,0 +1,44 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleInsertTest5 extends OracleTest { + + public void test_0() throws Exception { + String sql = "insert into wrh$_seg_stat_obj ( snap_id , dbid , ts# , obj# , dataobj# , owner , object_name , subobject_name , partition_type , object_type , tablespace_name) select :lah_snap_id , :dbid , ss1.tsn_kewrseg , ss1.objn_kewrseg , ss1.objd_kewrseg , ss1.ownername_kewrseg , ss1.objname_kewrseg , ss1.subobjname_kewrseg , decode(po.parttype, 1, 'RANGE', 2, 'HASH', 3, 'SYSTEM', 4, 'LIST', NULL, 'NONE', 'UNKNOWN') , decode(ss1.objtype_kewrseg, 0, 'NEXT OBJECT', 1, 'INDEX', 2, 'TABLE', 3, 'CLUSTER', 4, 'VIEW', 5, 'SYNONYM', 6, 'SEQUENCE', 7, 'PROCEDURE', 8, 'FUNCTION', 9, 'PACKAGE', 11, 'PACKAGE BODY', 12, 'TRIGGER', 13, 'TYPE', 14, 'TYPE BODY', 19, 'TABLE PARTITION', 20, 'INDEX PARTITION', 21, 'LOB', 22, 'LIBRARY', 23, 'DIRECTORY', 24, 'QUEUE', 28, 'JAVA SOURCE', 29, 'JAVA CLASS', 30, 'JAVA RESOURCE', 32, 'INDEXTYPE', 33, 'OPERATOR', 34, 'TABLE SUBPARTITION', 35, 'INDEX SUBPARTITION', 40, 'LOB PARTITION', 41, 'LOB SUBPARTITION', 42, 'MATERIALIZED VIEW', 43, 'DIMENSION', 44, 'CONTEXT', 47, 'RESOURCE PLAN', 48, 'CONSUMER GROUP', 51, 'SUBSCRIPTION', 52, 'LOCATION', 55, 'XML SCHEMA', 56, 'JAVA DATA', 57, 'SECURITY PROFILE', 'UNDEFINED') , ss1.tsname_kewrseg from x$kewrattrnew at, x$kewrtsegstat ss1, (select tp.obj#, pob.parttype from sys.tabpart$ tp, sys.partobj$ pob where tp.bo# = pob.obj# union all select ip.obj#, pob.parttype from sys.indpart$ ip, sys.partobj$ pob where ip.bo# = pob.obj#) po where at.num1_kewrattr = ss1.objn_kewrseg and at.num2_kewrattr = ss1.objd_kewrseg and at.num1_kewrattr = po.obj#(+) and (ss1.objtype_kewrseg not in (1 /* INDEX - handled below */, 10 /* NON-EXISTENT */) or (ss1.objtype_kewrseg = 1 and 1 = (select 1 from ind$ i where i.obj# = ss1.objn_kewrseg and i.type# in (1, 2, 3, 4, 6, 7, 9)))) and ss1.objname_kewrseg != '_NEXT_OBJECT' and ss1.objname_kewrseg != '_default_auditing_options_'"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("raises"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees"))); + + Assert.assertEquals(2, visitor.getTables().size()); + Assert.assertEquals(3, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "employee_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "salary"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "commission_pct"))); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleMergeTest2.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleMergeTest2.java new file mode 100644 index 0000000000..86c0cc1638 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleMergeTest2.java @@ -0,0 +1,75 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleMergeTest2 extends OracleTest { + + public void test_0() throws Exception { + String sql = "MERGE INTO \"ESCROW\".\"HT_TASK_TRADE_HISTORY_NEW\" SNA$ " + // + " USING (" + // + " SELECT CURRENT$.\"ID\",CURRENT$.\"GMT_MODIFIED\"" + // + " ,CURRENT$.\"GMT_CREATE\",CURRENT$.\"TRADE_ID\",CURRENT$.\"STATUS\",CURRENT$.\"OWNER\"" + // + " ,CURRENT$.\"GMT_FETCH_TASK\",CURRENT$.\"GMT_FINISH_TASK\",CURRENT$.\"VERSION\"" + // + " ,CURRENT$.\"RECORD_TYPE\",CURRENT$.\"TASK_FLOW_LEVEL\",CURRENT$.\"DEAL_TYPE\"" + // + " ,CURRENT$.\"END_REASON\",CURRENT$.\"TRANSIT_TIME\" " + // + " FROM (" + // + " SELECT \"HT_TASK_TRADE_HISTORY\".\"ID\" \"ID\"" + // + " ,\"HT_TASK_TRADE_HISTORY\".\"GMT_MODIFIED\" \"GMT_MODIFIED\"" + // + " ,\"HT_TASK_TRADE_HISTORY\".\"GMT_CREATE\" \"GMT_CREATE\"" + // + " ,\"HT_TASK_TRADE_HISTORY\".\"TRADE_ID\" \"TRADE_ID\"" + // + " ,\"HT_TASK_TRADE_HISTORY\".\"STATUS\" \"STATUS\"" + // + " ,\"HT_TASK_TRADE_HISTORY\".\"OWNER\" \"OWNER\"" + // + " ,\"HT_TASK_TRADE_HISTORY\".\"GMT_FETCH_TASK\" \"GMT_FETCH_TASK\"" + // + " ,\"HT_TASK_TRADE_HISTORY\".\"GMT_FINISH_TASK\" \"GMT_FINISH_TASK\"" + // + " ,\"HT_TASK_TRADE_HISTORY\".\"VERSION\" \"VERSION\"" + // + " ,\"HT_TASK_TRADE_HISTORY\".\"RECORD_TYPE\" \"RECORD_TYPE\"" + // + " ,\"HT_TASK_TRADE_HISTORY\".\"TASK_FLOW_LEVEL\" \"TASK_FLOW_LEVEL\"" + // + " ,\"HT_TASK_TRADE_HISTORY\".\"DEAL_TYPE\" \"DEAL_TYPE\"" + // + " ,\"HT_TASK_TRADE_HISTORY\".\"END_REASON\" \"END_REASON\"" + // + " ,\"HT_TASK_TRADE_HISTORY\".\"TRANSIT_TIME\" \"TRANSIT_TIME\" " + // + " FROM \"ESCROW\".\"HT_TASK_TRADE_HISTORY\" \"HT_TASK_TRADE_HISTORY\"" + // + " ) CURRENT$, " + // + " (SELECT DISTINCT MLOG$.\"ID\" " + // + " FROM \"ESCROW\".\"MLOG$_HT_TASK_TRADE_HISTOR\" MLOG$ " + // + " WHERE \"SNAPTIME$$\" > :1 AND (\"DMLTYPE$$\" != 'D')" + // + " ) LOG$ " + // + " WHERE CURRENT$.\"ID\" = LOG$.\"ID\") AS OF SNAPSHOT(:SCN) MAS$ ON (SNA$.\"ID\" = MAS$.\"ID\") WHEN MATCHED THEN UPDATE SET SNA$.\"ID\" = MAS$.\"ID\", SNA$.\"GMT_MODIFIED\" = MAS$.\"GMT_MODIFIED\", SNA$.\"GMT_CREATE\" = MAS$.\"GMT_CREATE\", SNA$.\"TRADE_ID\" = MAS$.\"TRADE_ID\", SNA$.\"STATUS\" = MAS$.\"STATUS\", SNA$.\"OWNER\" = MAS$.\"OWNER\", SNA$.\"GMT_FETCH_TASK\" = MAS$.\"GMT_FETCH_TASK\", SNA$.\"GMT_FINISH_TASK\" = MAS$.\"GMT_FINISH_TASK\", SNA$.\"VERSION\" = MAS$.\"VERSION\", SNA$.\"RECORD_TYPE\" = MAS$.\"RECORD_TYPE\", SNA$.\"TASK_FLOW_LEVEL\" = MAS$.\"TASK_FLOW_LEVEL\", SNA$.\"DEAL_TYPE\" = MAS$.\"DEAL_TYPE\", SNA$.\"END_REASON\" = MAS$.\"END_REASON\", SNA$.\"TRANSIT_TIME\" = MAS$.\"TRANSIT_TIME\" WHEN NOT MATCHED THEN INSERT (\"ID\",\"GMT_MODIFIED\",\"GMT_CREATE\",\"TRADE_ID\",\"STATUS\",\"OWNER\",\"GMT_FETCH_TASK\",\"GMT_FINISH_TASK\",\"VERSION\",\"RECORD_TYPE\",\"TASK_FLOW_LEVEL\",\"DEAL_TYPE\",\"END_REASON\",\"TRANSIT_TIME\") VALUES (MAS$.\"ID\",MAS$.\"GMT_MODIFIED\",MAS$.\"GMT_CREATE\",MAS$.\"TRADE_ID\",MAS$.\"STATUS\",MAS$.\"OWNER\",MAS$.\"GMT_FETCH_TASK\",MAS$.\"GMT_FINISH_TASK\",MAS$.\"VERSION\",MAS$.\"RECORD_TYPE\",MAS$.\"TASK_FLOW_LEVEL\",MAS$.\"DEAL_TYPE\",MAS$.\"END_REASON\",MAS$.\"TRANSIT_TIME\")"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + + Assert.assertEquals(2, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("bonuses"))); + + Assert.assertEquals(5, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "employee_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "salary"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "department_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("bonuses", "employee_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("bonuses", "bonus"))); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleMergeTest3.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleMergeTest3.java new file mode 100644 index 0000000000..4bd33f5453 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleMergeTest3.java @@ -0,0 +1,47 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleMergeTest3 extends OracleTest { + + public void test_0() throws Exception { + String sql = "merge /*+ dynamic_sampling(mm 4) dynamic_sampling_est_cdn(mm) dynamic_sampling(m 4) dynamic_sampling_est_cdn(m) */ into sys.mon_mods_all$ mm using (select m.obj# obj#, m.inserts inserts, m.updates updates, m.deletes deletes, m.flags flags, m.timestamp timestamp, m.drop_segments drop_segments from sys.mon_mods$ m, tab$ t where m.obj# = t.obj# ) v on (mm.obj# = v.obj#) when matched then update set mm.inserts = mm.inserts + v.inserts, mm.updates = mm.updates + v.updates, mm.deletes = mm.deletes + v.deletes, mm.flags = mm.flags + v.flags - bitand(mm.flags,v.flags) /* bitor(mm.flags,v.flags) */, mm.timestamp = v.timestamp, mm.drop_segments = mm.drop_segments + v.drop_segments when NOT matched then insert (obj#, inserts, updates, deletes, timestamp, flags, drop_segments) values (v.obj#, v.inserts, v.updates, v.deletes, sysdate, v.flags, v.drop_segments);"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + + Assert.assertEquals(2, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("bonuses"))); + + Assert.assertEquals(5, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "employee_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "salary"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "department_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("bonuses", "employee_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("bonuses", "bonus"))); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleMergeTest4.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleMergeTest4.java new file mode 100644 index 0000000000..3f9e0415f8 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleMergeTest4.java @@ -0,0 +1,47 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleMergeTest4 extends OracleTest { + + public void test_0() throws Exception { + String sql = "MERGE INTO \"ESCROW \". \"HT_TASK_TRADE_HISTORY_NEW \" SNA$ USING (SELECT \"CURRENT$ \". \"ID \", \"OUTERTAB$ \". \"GMT_MODIFIED \" \"GMT_MODIFIED \", \"OUTERTAB$ \". \"GMT_CREATE \" \"GMT_CREATE \", \"OUTERTAB$ \". \"TRADE_ID \" \"TRADE_ID \", \"OUTERTAB$ \". \"STATUS \" \"STATUS \", \"OUTERTAB$ \". \"OWNER \" \"OWNER \", \"OUTERTAB$ \". \"GMT_FETCH_TASK \" \"GMT_FETCH_TASK \", \"OUTERTAB$ \". \"GMT_FINISH_TASK \" \"GMT_FINISH_TASK \", \"OUTERTAB$ \". \"VERSION \" \"VERSION \", \"OUTERTAB$ \". \"RECORD_TYPE \" \"RECORD_TYPE \", \"OUTERTAB$ \". \"TASK_FLOW_LEVEL \" \"TASK_FLOW_LEVEL \", \"OUTERTAB$ \". \"DEAL_TYPE \" \"DEAL_TYPE \", \"OUTERTAB$ \". \"END_REASON \" \"END_REASON \", \"OUTERTAB$ \". \"TRANSIT_TIME \" \"TRANSIT_TIME \" FROM (SELECT /*+ NO_MERGE NO_MERGE(LL$) ROWID(MAS$) ORDERED USE_NL(MAS$) NO_INDEX(MAS$) PQ_DISTRIBUTE(MAS$,RANDOM,NONE) */ \"MAS$ \". \"ID \" \"ID \" FROM \"ALL_SUMDELTA \" \"LL$ \", \"ESCROW \". \"HT_TASK_TRADE_HISTORY \" \"MAS$ \" WHERE ((LL$.TABLEOBJ# = :1 AND LL$.TIMESTAMP > :2 AND \"MAS$ \".ROWID BETWEEN LL$.LOWROWID AND LL$.HIGHROWID))) CURRENT$, \"ESCROW \". \"HT_TASK_TRADE_HISTORY \" OUTERTAB$ WHERE CURRENT$. \"ID \" = OUTERTAB$. \"ID \") AS OF SNAPSHOT(:SCN) MAS$ ON (SNA$. \"ID \" = MAS$. \"ID \") WHEN MATCHED THEN UPDATE SET SNA$. \"ID \" = MAS$. \"ID \", SNA$. \"GMT_MODIFIED \" = MAS$. \"GMT_MODIFIED \", SNA$. \"GMT_CREATE \" = MAS$. \"GMT_CREATE \", SNA$. \"TRADE_ID \" = MAS$. \"TRADE_ID \", SNA$. \"STATUS \" = MAS$. \"STATUS \", SNA$. \"OWNER \" = MAS$. \"OWNER \", SNA$. \"GMT_FETCH_TASK \" = MAS$. \"GMT_FETCH_TASK \", SNA$. \"GMT_FINISH_TASK \" = MAS$. \"GMT_FINISH_TASK \", SNA$. \"VERSION \" = MAS$. \"VERSION \", SNA$. \"RECORD_TYPE \" = MAS$. \"RECORD_TYPE \", SNA$. \"TASK_FLOW_LEVEL \" = MAS$. \"TASK_FLOW_LEVEL \", SNA$. \"DEAL_TYPE \" = MAS$. \"DEAL_TYPE \", SNA$. \"END_REASON \" = MAS$. \"END_REASON \", SNA$. \"TRANSIT_TIME \" = MAS$. \"TRANSIT_TIME \" WHEN NOT MATCHED THEN INSERT ( \"ID \", \"GMT_MODIFIED \", \"GMT_CREATE \", \"TRADE_ID \", \"STATUS \", \"OWNER \", \"GMT_FETCH_TASK \", \"GMT_FINISH_TASK \", \"VERSION \", \"RECORD_TYPE \", \"TASK_FLOW_LEVEL \", \"DEAL_TYPE \", \"END_REASON \", \"TRANSIT_TIME \") VALUES (MAS$. \"ID \",MAS$. \"GMT_MODIFIED \",MAS$. \"GMT_CREATE \",MAS$. \"TRADE_ID \",MAS$. \"STATUS \",MAS$. \"OWNER \",MAS$. \"GMT_FETCH_TASK \",MAS$. \"GMT_FINISH_TASK \",MAS$. \"VERSION \",MAS$. \"RECORD_TYPE \",MAS$. \"TASK_FLOW_LEVEL \",MAS$. \"DEAL_TYPE \",MAS$. \"END_REASON \",MAS$. \"TRANSIT_TIME \")"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + + Assert.assertEquals(2, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("bonuses"))); + + Assert.assertEquals(5, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "employee_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "salary"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "department_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("bonuses", "employee_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("bonuses", "bonus"))); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleMergeTest5.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleMergeTest5.java new file mode 100644 index 0000000000..b74e626e0c --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleMergeTest5.java @@ -0,0 +1,55 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleMergeTest5 extends OracleTest { + + public void test_0() throws Exception { + String sql = "MERGE " + // + "INTO MEMBER_LAST_LOGIN M2 " + // + "USING MEMBER_LAST_LOGIN_HZ M1 ON (M1.ID = M2.ID) " + // + " WHEN MATCHED THEN " + // + " UPDATE SET M2.LAST_LOGIN_TIME = M1.LAST_LOGIN_TIME, M2.GMT_MODIFIED = M1.GMT_MODIFIED" + // + " , M2.OWNER_SEQ = M1.OWNER_SEQ, M2.OWNER_MEMBER_ID = M1.OWNER_MEMBER_ID, M2.IP = M1.IP " + // + " WHEN NOT MATCHED THEN " + // + " INSERT VALUES (M1.ID, M1.GMT_CREATE, M1.GMT_MODIFIED, M1.OWNER_SEQ" + // + " , M1.LAST_LOGIN_TIME, M1.OWNER_MEMBER_ID, M1.IP)"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + + Assert.assertEquals(2, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("bonuses"))); + + Assert.assertEquals(5, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "employee_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "salary"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "department_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("bonuses", "employee_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("bonuses", "bonus"))); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest17.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest17.java new file mode 100644 index 0000000000..44d88ed56d --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest17.java @@ -0,0 +1,44 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleSelectTest17 extends OracleTest { + + public void test_0() throws Exception { + String sql = "select /* EXEC_FROM_DBMS_XPLAN */ 1, prev_sql_id, prev_child_number from v$session where sid=userenv('sid') and username is not null and prev_hash_value <> 0 "; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("\"DUAL\""))); + + Assert.assertEquals(0, visitor.getColumns().size()); + +// Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "*"))); +// Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR"))); +// Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest18.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest18.java new file mode 100644 index 0000000000..a1753dcfd3 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest18.java @@ -0,0 +1,57 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleSelectTest18 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "begin " + // + " select min(snap_id), max(snap_id), " + // + " to_char(max(begin_interval_time + 16/24), 'yyyy-mm-dd hh24:mi:ss')," + // + " to_char(max(end_interval_time + 16/24), 'yyyy-mm-dd hh24:mi:ss') " + // + " into :bid, :eid, :bst, :est " + // + " from (select snap_id, begin_interval_time, end_interval_time" + // + " from v$instance a,dba_hist_snapshot b" + // + " where a.INSTANCE_NUMBER=b.INSTANCE_NUMBER and begin_interval_time >= sysdate - 150/1440" + // + " order by snap_id desc" + // + " )" + // + " where rownum < 3; " + // + " select 'awr_'||:bid||'_'||:eid||'.html' into :awr from dual; " + // + "end;"; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("\"DUAL\""))); + + Assert.assertEquals(0, visitor.getColumns().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "*"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest19.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest19.java new file mode 100644 index 0000000000..186556e58e --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest19.java @@ -0,0 +1,55 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleSelectTest19 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "SELECT ddf.file_name file_name, vdf.status status, ddf.tablespace_name tablespace_name" + // + ", '', ddf.autoextensible autoextensible" + // + " , ddf.increment_by increment_by, ddf.maxbytes max_file_size, vdf.create_bytes " + // + "FROM sys.dba_data_files ddf, v$datafile vdf /*+ all_rows use_concat */ " + // + "WHERE (ddf.file_name = vdf.name) " + // + "UNION ALL " + // + "SELECT dtf.file_name file_name, vtf.status status, dtf.tablespace_name tablespace_name" + // + " , '', dtf.autoextensible autoextensible, dtf.increment_by increment_by" + // + " , dtf.maxbytes max_file_size, vtf.create_bytes " + // + "FROM sys.dba_temp_files dtf, v$tempfile vtf " + // + "WHERE (dtf.file_id = vtf.file#) "; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("\"DUAL\""))); + + Assert.assertEquals(0, visitor.getColumns().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "*"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest20.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest20.java new file mode 100644 index 0000000000..63a64a1dbc --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest20.java @@ -0,0 +1,49 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleSelectTest20 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "BEGIN" + // + " sys.dbms_stats.gather_table_stats(" + // + " ownname => 'ESCROW',tabname => 'HT_TASK_TRADE_HISTORY',estimate_percent=>0.5, cascade => TRUE" + // + " ,method_opt=>'FOR ALL COLUMNS SIZE 1',no_invalidate => false); " + // + "END; "; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("\"DUAL\""))); + + Assert.assertEquals(0, visitor.getColumns().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "*"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest21.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest21.java new file mode 100644 index 0000000000..06d6eabf4e --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest21.java @@ -0,0 +1,60 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleSelectTest21 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "SELECT EVENT, WAITS, TIME, DECODE(WAITS, NULL, TO_NUMBER(NULL), 0, TO_NUMBER(NULL), TIME/WAITS*1000) AVGWT" + // + " , PCTWTT, WAIT_CLASS " + "FROM (SELECT EVENT, WAITS, TIME, PCTWTT, WAIT_CLASS " + // + " FROM (" + // + " SELECT E.EVENT_NAME EVENT, E.TOTAL_WAITS - NVL(B.TOTAL_WAITS,0) WAITS" + // + " , (E.TIME_WAITED_MICRO - NVL(B.TIME_WAITED_MICRO,0)) / 1000000 TIME" + // + " , 100 * (E.TIME_WAITED_MICRO - NVL(B.TIME_WAITED_MICRO,0)) / :B1 PCTWTT" + // + " , E.WAIT_CLASS WAIT_CLASS " + // + " FROM DBA_HIST_SYSTEM_EVENT B, DBA_HIST_SYSTEM_EVENT E " + // + " WHERE B.SNAP_ID(+) = :B5 AND E.SNAP_ID = :B4 AND B.DBID(+) = :B3 AND E.DBID = :B3 " + // + " AND B.INSTANCE_NUMBER(+) = :B2 AND E.INSTANCE_NUMBER = :B2 AND B.EVENT_ID(+) = E.EVENT_ID " + // + " AND E.TOTAL_WAITS > NVL(B.TOTAL_WAITS,0) AND E.WAIT_CLASS != 'Idle' " + // + " UNION ALL " + // + " SELECT 'CPU time' EVENT, TO_NUMBER(NULL) WAITS" + // + " , :B6 /1000000 TIME, 100 * :B6 / :B1 PCTWTT, NULL WAIT_CLASS FROM DUAL WHERE :B6 > 0" + // + ") ORDER BY TIME DESC, WAITS DESC) " + // + "WHERE ROWNUM <= :B7 "; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("\"DUAL\""))); + + Assert.assertEquals(0, visitor.getColumns().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "*"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest22.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest22.java new file mode 100644 index 0000000000..8eaa396af7 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest22.java @@ -0,0 +1,45 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleSelectTest22 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "select /*+ no_parallel(t) no_parallel_index(t) dbms_stats cursor_sharing_exact use_weak_name_resl dynamic_sampling(0) no_monitoring */ count(*),sum(sys_op_opnsize(\"ID\")),substrb(dump(min(\"ID\"),16,0,32),1,120),substrb(dump(max(\"ID\"),16,0,32),1,120),count(distinct \"GMT_MODIFIED\"),substrb(dump(min(\"GMT_MODIFIED\"),16,0,32),1,120),substrb(dump(max(\"GMT_MODIFIED\"),16,0,32),1,120),count(distinct \"GMT_CREATE\"),substrb(dump(min(\"GMT_CREATE\"),16,0,32),1,120),substrb(dump(max(\"GMT_CREATE\"),16,0,32),1,120),count(\"TRADE_ID\"),count(distinct \"TRADE_ID\"),sum(sys_op_opnsize(\"TRADE_ID\")),substrb(dump(min(\"TRADE_ID\"),16,0,32),1,120),substrb(dump(max(\"TRADE_ID\"),16,0,32),1,120),count(\"STATUS\"),count(distinct \"STATUS\"),sum(sys_op_opnsize(\"STATUS\")),substrb(dump(min(substrb(\"STATUS\",1,32)),16,0,32),1,120),substrb(dump(max(substrb(\"STATUS\",1,32)),16,0,32),1,120),count(\"OWNER\"),count(distinct \"OWNER\"),sum(sys_op_opnsize(\"OWNER\")),substrb(dump(min(substrb(\"OWNER\",1,32)),16,0,32),1,120),substrb(dump(max(substrb(\"OWNER\",1,32)),16,0,32),1,120),count(\"GMT_FETCH_TASK\"),count(distinct \"GMT_FETCH_TASK\"),substrb(dump(min(\"GMT_FETCH_TASK\"),16,0,32),1,120),substrb(dump(max(\"GMT_FETCH_TASK\"),16,0,32),1,120),count(\"GMT_FINISH_TASK\"),count(distinct \"GMT_FINISH_TASK\"),substrb(dump(min(\"GMT_FINISH_TASK\"),16,0,32),1,120),substrb(dump(max(\"GMT_FINISH_TASK\"),16,0,32),1,120),count(\"VERSION\"),count(distinct \"VERSION\"),sum(sys_op_opnsize(\"VERSION\")),substrb(dump(min(\"VERSION\"),16,0,32),1,120),substrb(dump(max(\"VERSION\"),16,0,32),1,120),count(\"RECORD_TYPE\"),count(distinct \"RECORD_TYPE\"),sum(sys_op_opnsize(\"RECORD_TYPE\")),substrb(dump(min(substrb(\"RECORD_TYPE\",1,32)),16,0,32),1,120),substrb(dump(max(substrb(\"RECORD_TYPE\",1,32)),16,0,32),1,120),count(\"TASK_FLOW_LEVEL\"),count(distinct \"TASK_FLOW_LEVEL\"),sum(sys_op_opnsize(\"TASK_FLOW_LEVEL\")),substrb(dump(min(\"TASK_FLOW_LEVEL\"),16,0,32),1,120),substrb(dump(max(\"TASK_FLOW_LEVEL\"),16,0,32),1,120),count(\"DEAL_TYPE\"),count(distinct \"DEAL_TYPE\"),sum(sys_op_opnsize(\"DEAL_TYPE\")),substrb(dump(min(\"DEAL_TYPE\"),16,0,32),1,120),substrb(dump(max(\"DEAL_TYPE\"),16,0,32),1,120),count(\"END_REASON\"),count(distinct \"END_REASON\"),sum(sys_op_opnsize(\"END_REASON\")),substrb(dump(min(\"END_REASON\"),16,0,32),1,120),substrb(dump(max(\"END_REASON\"),16,0,32),1,120),count(\"TRANSIT_TIME\"),count(distinct \"TRANSIT_TIME\"),sum(sys_op_opnsize(\"TRANSIT_TIME\")),substrb(dump(min(\"TRANSIT_TIME\"),16,0,32),1,120),substrb(dump(max(\"TRANSIT_TIME\"),16,0,32),1,120) from \"ESCROW\".\"HT_TASK_TRADE_HISTORY\" sample ( .5000000000) t "; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("\"DUAL\""))); + + Assert.assertEquals(0, visitor.getColumns().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "*"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest23.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest23.java new file mode 100644 index 0000000000..7084eb994c --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest23.java @@ -0,0 +1,45 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleSelectTest23 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "select (select decode(count(*),1,'YES','NO') FROM sys.obj$ o, sys.user$ u WHERE u.name = 'PERFSTAT' AND o.owner# = u.user# AND o.name = 'STATSPACK' AND o.type# = 11 AND o.status = 1) is_installed , (select nvl(INTERVAL,'') from dba_jobs where what like 'statspack.snap%' and SCHEMA_USER='PERFSTAT' and rownum =1) freq from dual"; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("\"DUAL\""))); + + Assert.assertEquals(0, visitor.getColumns().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "*"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest24.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest24.java new file mode 100644 index 0000000000..b382441407 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest24.java @@ -0,0 +1,45 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleSelectTest24 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "select /*+ no_parallel_index(t, \"HT_TASK_TRADE_HIS_GOR_IND \") dbms_stats cursor_sharing_exact use_weak_name_resl dynamic_sampling(0) no_monitoring no_expand index_ffs(t, \"HT_TASK_TRADE_HIS_GOR_IND \") */ count(*) as nrw,count(distinct sys_op_lbid(196675,'L',t.rowid)) as nlb,count(distinct hextoraw(sys_op_descend( \"GMT_MODIFIED \")||sys_op_descend( \"OWNER \")||sys_op_descend( \"RECORD_TYPE \"))) as ndk,sys_op_countchg(substrb(t.rowid,1,15),1) as clf from \"ESCROW \". \"HT_TASK_TRADE_HISTORY \" sample block ( 34.6426417370,1) t where \"GMT_MODIFIED \" is not null or \"OWNER \" is not null or \"RECORD_TYPE \" is not null"; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("\"DUAL\""))); + + Assert.assertEquals(0, visitor.getColumns().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "*"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest25.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest25.java new file mode 100644 index 0000000000..f438504483 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest25.java @@ -0,0 +1,45 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleSelectTest25 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "SELECT NULL FROM DUAL FOR UPDATE NOWAIT"; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("\"DUAL\""))); + + Assert.assertEquals(0, visitor.getColumns().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "*"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest26.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest26.java new file mode 100644 index 0000000000..601c1af10e --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest26.java @@ -0,0 +1,52 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleSelectTest26 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "select * from ( select rownum rnm, z.* from (select " + + " o.id,o.gmt_create as \"gm_create\",o.country as \"country\",o.status as \"status\"," + + " o.logistics_company as \"company\",o.type as \"type\",o.freight/100 as \"feight\"," + + " d.gmt_create as \"gm_create_1\",d.logistics_company as \"company_1\",d.package_num as \" \",d.declare_amount as \" \"," + + " i.gmt_stockin as \" \",i.package_amount as \" \",i.weight as \" \"," + + " u.gmt_create as \" \",u.logistics_company as \" \",u.package_amount as \" \"" + + " from wl_wh_order o left join wl_domestic_send d on d.wh_order_id=o.id left join wl_wh_in i on i.wh_order_id=o.id left join wl_wh_out u on u.out_order_id=o.id" + + " where o.id=100120667) z where rownum < :1 ) where rnm >= :2 "; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("\"DUAL\""))); + + Assert.assertEquals(0, visitor.getColumns().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "*"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest27.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest27.java new file mode 100644 index 0000000000..8128c18d18 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest27.java @@ -0,0 +1,47 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleSelectTest27 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "select object_id tab_id_noprint , -9999999 col_id_noprint " + // + ", 'table '||lower(owner)||' '||object_id||' '||lower(object_name)||' '||y.tid from dba_objects x" + // + ", search.retl_table_config_search y where object_type='TABLE' and x.owner=upper(case when instr(y.TSCHEMA,'|',1,1)>0 then substr(y.TSCHEMA,1,instr(y.TSCHEMA,'|',1,1)-1) else y.TSCHEMA end) and x.object_name=upper(y.TNAME) and ( owner not in ('SYS','SYSTEM','OUTLN','PUBLIC','WMSYS') or ( owner in ('SYS') and object_name in ('TAB$','OBJ$','COL$','CCOL$','CDEF$') ) ) union all select g.object_id as tab_id_noprint, g.column_id as tab_id_noprint , 'column '||g.column_id||' '||g.data_type||' '||g.data_length ||' '||decode(h.column_name,null ,0 ,1)||' '||lower(g.column_name) from ( select a.object_id ,a.owner, a.object_name as table_name, b.name as column_name ,b.segcol# as column_id, b.type# as data_type, b.segcollength as data_length from dba_objects a ,sys.col$ b ,search.retl_table_config_search g where a.object_id=b.obj# and a.object_type='TABLE' and a.owner=upper(case when instr(g.TSCHEMA,'|',1,1)>0 then substr(g.TSCHEMA,1,instr(g.TSCHEMA,'|',1,1)-1) else g.TSCHEMA end) and a.object_name=upper(g.TNAME) and b.segcol#!=0 and ( owner not in ('SYS','SYSTEM','OUTLN','PUBLIC','WMSYS') or ( owner in ('SYS') and a.object_name in ('TAB$','OBJ$','COL$','CCOL$','CDEF$') ) ) ) g, ( select upper(case when instr(TSCHEMA,'|',1,1)>0 then substr(TSCHEMA,1,instr(TSCHEMA,'|',1,1)-1) else TSCHEMA end) as owner, upper(a.tname) as table_name, upper(b.COLUMN_VALUE) as column_name from search.retl_table_config_search a, table(cast(erosazm.str2varlist(a.pks) as erosazm.vartabletype)) b ) h where g.owner=h.owner(+) and g.table_name=h.table_name(+) and g.column_name=h.column_name(+) order by tab_id_noprint,col_id_noprint"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("\"DUAL\""))); + + Assert.assertEquals(0, visitor.getColumns().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "*"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest28.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest28.java new file mode 100644 index 0000000000..85874c66d4 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest28.java @@ -0,0 +1,45 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleSelectTest28 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "SELECT /*+ ORDERED USE_NL ( \"A1 \") USE_NL ( \"A2 \") USE_NL ( \"A3 \") */ \"A3 \". \"AP_PAY_TIME \", \"A2 \". \"ORDER_ID \", \"A3 \". \"AP_PAY_AMT \", \"A1 \". \"COUNTRY \" FROM \"ESCROW \". \"TRADE_PAY \" \"A3 \", \"ESCROW \". \"ESCROW_TRADE \" \"A2 \", \"ESCROW \". \"BUSINESS_ORDER \" \"A1 \" WHERE \"A3 \". \"TRADE_ID \"= \"A2 \". \"ID \" AND \"A1 \". \"ID \"(+)=TO_NUMBER( \"A2 \". \"OUT_ORDER_ID \") AND \"A2 \". \"ORDER_FROM \"='wholesale_order' AND \"A3 \". \"AP_PAY_TIME \">=:1-.003819444444444444444444444444444444444444 AND \"A3 \". \"AP_PAY_TIME \">=TRUNC(:2)"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("\"DUAL\""))); + + Assert.assertEquals(0, visitor.getColumns().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "*"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest29.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest29.java new file mode 100644 index 0000000000..449f31d2e9 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest29.java @@ -0,0 +1,45 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleSelectTest29 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "(select id,super_category_id_1 from category where super_category_id_1 is not null and super_category_id_1 != '-1') union (select id,super_category_id_2 from category where super_category_id_2 is not null and super_category_id_2 != '-1') union (select id,super_category_id_3 from category where super_category_id_3 is not null and super_category_id_3 != '-1') union (select id,super_category_id_4 from category where super_category_id_4 is not null and super_category_id_4 != '-1') union (select id,super_category_id_5 from category where super_category_id_5 is not null and super_category_id_5 != '-1')"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("\"DUAL\""))); + + Assert.assertEquals(0, visitor.getColumns().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "*"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest30.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest30.java new file mode 100644 index 0000000000..0cef33131b --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest30.java @@ -0,0 +1,56 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleSelectTest30 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "SELECT " + + // + "/* OPT_DYN_SAMP */ " + + // + "/*+ ALL_ROWS IGNORE_WHERE_CLAUSE NO_PARALLEL(SAMPLESUB) opt_param('parallel_execution_enabled', 'false') NO_PARALLEL_INDEX(SAMPLESUB) NO_SQL_TUNE */ " // + + "NVL(SUM(C1),:\"SYS_B_0\"), NVL(SUM(C2),:\"SYS_B_1\") " + + // + "FROM (SELECT " + + // + " /*+ NO_PARALLEL(\"IPAY_ACCOUNT_FUND_RCD\") FULL(\"IPAY_ACCOUNT_FUND_RCD\") NO_PARALLEL_INDEX(\"IPAY_ACCOUNT_FUND_RCD\") */ " + + // + ":\"SYS_B_2\" AS C1, :\"SYS_B_3\" AS C2 FROM \"ESCROW\".\"IPAY_ACCOUNT_FUND_RCD\" SAMPLE BLOCK (:\"SYS_B_4\" , :\"SYS_B_5\") SEED (:\"SYS_B_6\") \"IPAY_ACCOUNT_FUND_RCD\") SAMPLESUB"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("\"ESCROW\".\"IPAY_ACCOUNT_FUND_RCD\""))); + + Assert.assertEquals(0, visitor.getColumns().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "*"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSetTransactionTest.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSetTransactionTest.java new file mode 100644 index 0000000000..77b0cac833 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSetTransactionTest.java @@ -0,0 +1,49 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleSetTransactionTest extends OracleTest { + + public void test_0() throws Exception { + String sql = "set transaction name 'IGNORED_TRANS' "; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(2, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("departments"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees"))); + + Assert.assertEquals(7, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("departments", "department_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "department_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "employee_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "commission_pct"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "department_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("UNKNOWN", "job_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("UNKNOWN", "location_id"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleUpdateTest2.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleUpdateTest2.java new file mode 100644 index 0000000000..fb42eb65f0 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleUpdateTest2.java @@ -0,0 +1,56 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleUpdateTest2 extends OracleTest { + + public void test_0() throws Exception { + String sql = "UPDATE wrh$_tempfile tfh " // + + " SET (snap_id, filename, tsname) =" // + + " (SELECT :lah_snap_id, tf.name name, ts.name tsname" + + // + " FROM v$tempfile tf, ts$ ts" + + // + " WHERE tf.ts# = ts.ts# AND tfh.file# = tf.file# AND tfh.creation_change# = tf.creation_change#" + + // + " )" + // + "WHERE (file#, creation_change#) IN (" + // + " SELECT tf.tfnum, to_number(tf.tfcrc_scn) creation_change# " + // + " FROM x$kcctf tf " + // + " WHERE tf.tfdup != 0) AND dbid = :dbid AND snap_id < :snap_id"; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("table1"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("table2"))); + + Assert.assertEquals(2, visitor.getTables().size()); + Assert.assertEquals(3, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("table1", "column"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("table2", "expr"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("table2", "column"))); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleUpdateTest3.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleUpdateTest3.java new file mode 100644 index 0000000000..1ecfed1c8a --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleUpdateTest3.java @@ -0,0 +1,50 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleUpdateTest3 extends OracleTest { + + public void test_0() throws Exception { + String sql = "update sys.col_usage$ " + + "set equality_preds = equality_preds + decode(bitand(:flag,1),0,0,1)" // + + " , equijoin_preds = equijoin_preds + decode(bitand(:flag,2),0,0,1)" // + + " , nonequijoin_preds = nonequijoin_preds + decode(bitand(:flag,4),0,0,1)" // + + " , range_preds = range_preds + decode(bitand(:flag,8),0,0,1)" // + + " , like_preds = like_preds + decode(bitand(:flag,16),0,0,1)" // + + " , null_preds = null_preds + decode(bitand(:flag,32),0,0,1), timestamp = :time where obj# = :objn and intcol# = :coln"; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("table1"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("table2"))); + + Assert.assertEquals(2, visitor.getTables().size()); + Assert.assertEquals(3, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("table1", "column"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("table2", "expr"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("table2", "column"))); + } + +} diff --git a/src/test/java/com/alibaba/druid/sql/TestTransform.java b/src/test/java/com/alibaba/druid/sql/TestTransform.java index 1c97adf4cf..742ae82ebb 100644 --- a/src/test/java/com/alibaba/druid/sql/TestTransform.java +++ b/src/test/java/com/alibaba/druid/sql/TestTransform.java @@ -65,7 +65,7 @@ public class TestTransform extends OracleTest { stmt.setString(2, sqlId); int updateCount = stmt.executeUpdate(); - if (updateCount != 1) { + if (updateCount < 1) { throw new Exception(); } @@ -76,7 +76,7 @@ public class TestTransform extends OracleTest { System.out.println((this.updateCount++) + " : " + sqlId); } - public void f_test_transform() throws Exception { + public void test_transform() throws Exception { Connection conn = dataSource.getConnection(); @@ -135,6 +135,21 @@ public class TestTransform extends OracleTest { if (sqlId.equals("0tvydgpa3jmkv")) { continue; } + if (sqlId.equals("09xu7vwbdz0gs")) { + continue; + } + if (sqlId.equals("0wjc3zzc5z2x9")) { + continue; + } + if (sqlId.equals("22vkv80fyntg0")) { + continue; + } + if (sqlId.equals("24j7jc4c8hsw4")) { + continue; + } + if (sqlId.equals("2b4s4scg6rgp8")) { + continue; + } r.setSnapshotDate(d1); r.setDbName(s2); @@ -146,8 +161,12 @@ public class TestTransform extends OracleTest { r.setLastSnapshotDate(rs.getDate(7)); r.setDbPk(rs.getLong(8)); - // System.out.println(i + "(" + r.getDbName() + "/" + r.getSqlId() + ") : " + r.getSqlText()); - schemaStat(r); + System.out.println(i + "(" + r.getDbName() + "/" + r.getSqlId() + ") : " + r.getSqlText()); + try { + schemaStatInternal(r); + } catch (Exception e) { + // e.printStackTrace(); + } } rs.close(); stmt.close(); @@ -162,7 +181,7 @@ public class TestTransform extends OracleTest { try { schemaStatInternal(r); } catch (Exception e) { - // e.printStackTrace(); + e.printStackTrace(); } } }); @@ -177,45 +196,24 @@ public class TestTransform extends OracleTest { if (sql.startsWith("/* MV_REFRESH (DEL) */")) { return; } - if (sql.startsWith("grant") || sql.startsWith("GRANT")) { - return; - } if (sql.startsWith("SELECT /*+ Q1630000 NO_EXPAND ROWID(A1) */ A1.\"PRODUCT_ID\",A1.\"SUMMARY\"")) { return; } if (sql.startsWith("declare") || sql.startsWith("DECLARE")) { return; } - if (sql.startsWith("alter table")) { - return; - } - if (sql.startsWith("SELECT /* OPT_DYN_SAMP */")) { - return; - } - if (sql.startsWith("COMMENT")) { - return; - } - if (sql.startsWith("create index")) { - return; - } - if (sql.startsWith("alter index")) { - return; - } - if (sql.startsWith("create table")) { + if (sql.startsWith("create")) { return; } if (sql.startsWith("CREATE")) { return; } - if (sql.startsWith("explain plan")) { - return; - } - if (sql.startsWith("ALTER TABLE")) { - return; - } if (r.getSqlId().equals("09x7ytfdk63sp")) { return; } + if (sql.indexOf("AS OF SNAPSHOT") != -1) { + return; + } OracleStatementParser parser = new OracleStatementParser(sql); List statementList = parser.parseStatementList(); @@ -233,11 +231,11 @@ public class TestTransform extends OracleTest { buf.append("\nCoditions : " + visitor.getConditions().toString()); buf.append("\nrelationships " + visitor.getRelationships().toString()); - // System.out.println(buf.toString()); + System.out.println(buf.toString()); - // System.out.println(); - // System.out.println(); - // System.out.println(); + System.out.println(); + System.out.println(); + System.out.println(); updateRecord(r.getSqlId(), buf.toString()); } @@ -252,7 +250,7 @@ public class TestTransform extends OracleTest { conn.close(); } - public void test_migrate() throws Exception { + public void f_test_migrate() throws Exception { Connection conn = dataSource.getConnection(); int count = 0;