diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLUnaryOperator.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLUnaryOperator.java index 4a99173590..00c2e2750c 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLUnaryOperator.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLUnaryOperator.java @@ -16,7 +16,7 @@ package com.alibaba.druid.sql.ast.expr; public enum SQLUnaryOperator { - Plus("+"), Negative("-"), Not("!"), Compl("~"), Prior("PRIOR"), ConnectByRoot("CONNECT BY"); + Plus("+"), Negative("-"), Not("!"), Compl("~"), Prior("PRIOR"), ConnectByRoot("CONNECT BY"), NOT("NOT"); public final String name; 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 69d73af737..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; } @@ -74,7 +83,16 @@ public class OracleAggregateExpr extends SQLAggregateExpr implements Serializabl @Override protected void accept0(SQLASTVisitor visitor) { - this.accept0((OracleASTVisitor) visitor); + if (visitor instanceof OracleASTVisitor) { + this.accept0((OracleASTVisitor) visitor); + } else { + if (visitor.visit(this)) { + acceptChild(visitor, this.methodName); + acceptChild(visitor, this.arguments); + acceptChild(visitor, this.over); + } + visitor.endVisit(this); + } } public void accept0(OracleASTVisitor visitor) { 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/OracleDatetimeExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleDatetimeExpr.java new file mode 100644 index 0000000000..68e6c9f917 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleDatetimeExpr.java @@ -0,0 +1,48 @@ +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 OracleDatetimeExpr extends OracleSQLObjectImpl implements SQLExpr { + + private static final long serialVersionUID = 1L; + + private SQLExpr expr; + private SQLExpr timeZone; + + public OracleDatetimeExpr(){ + + } + + public OracleDatetimeExpr(SQLExpr expr, SQLExpr timeZone){ + this.expr = expr; + this.timeZone = timeZone; + } + + @Override + public void accept0(OracleASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, expr); + acceptChild(visitor, timeZone); + } + visitor.endVisit(this); + } + + public SQLExpr getExpr() { + return expr; + } + + public void setExpr(SQLExpr expr) { + this.expr = expr; + } + + public SQLExpr getTimeZone() { + return timeZone; + } + + public void setTimeZone(SQLExpr timeZone) { + this.timeZone = timeZone; + } + +} 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/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/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 index aef4a0fe47..e18eea8fc2 100644 --- 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 @@ -77,7 +77,11 @@ public class OracleDeleteParser extends SQLStatementParser { return deleteStatement; } + protected OracleExprParser createExprParser() { + return new OracleExprParser(lexer); + } + private void parseHints(OracleDeleteStatement parseInsert) throws ParserException { - if (lexer.token() == Token.HINT) throw new ParserException("TODO"); + this.createExprParser().parseHints(parseInsert.getHints()); } } 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 6852f2ad9f..655c6fc294 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 @@ -29,23 +29,28 @@ import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr; import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; import com.alibaba.druid.sql.ast.expr.SQLNumberExpr; import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; +import com.alibaba.druid.sql.ast.expr.SQLUnaryExpr; +import com.alibaba.druid.sql.ast.expr.SQLUnaryOperator; import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; 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.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; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDateExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDateTimeUnit; +import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDatetimeExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDbLinkExpr; 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.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; @@ -58,6 +63,7 @@ public class OracleExprParser extends SQLExprParser { + public boolean allowStringAdditive = false; /** @@ -90,6 +96,21 @@ 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(); + sqlExpr = new SQLUnaryExpr(SQLUnaryOperator.Prior, sqlExpr); + return primaryRest(sqlExpr); case COLON: lexer.nextToken(); if (lexer.token() == Token.LITERAL_INT) { @@ -116,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); @@ -204,8 +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); @@ -286,6 +312,27 @@ public class OracleExprParser extends SQLExprParser { expr = interval; } + 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 { + if (lexer.token() == Token.TIME) { + lexer.nextToken(); + } else { + lexer.reset(mark_bp, mark_ch, Token.AT); + return expr; + } + accept(Token.ZONE); + + SQLExpr timeZone = primary(); + expr = new OracleDatetimeExpr(expr, timeZone); + } + } + SQLExpr restExpr = super.primaryRest(expr); if (restExpr != expr && restExpr instanceof SQLMethodInvokeExpr) { @@ -312,7 +359,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; } @@ -332,8 +383,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(); @@ -382,6 +437,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); @@ -392,6 +454,7 @@ public class OracleExprParser extends SQLExprParser { } else { aggregateExpr = new OracleAggregateExpr(method_name, 1); } + aggregateExpr.setUnique(unique); exprList(aggregateExpr.getArguments()); if (lexer.stringVal().equalsIgnoreCase("IGNORE")) { @@ -517,10 +580,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(); @@ -618,4 +681,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 f368222dc9..6e82c97ec0 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,6 +122,15 @@ public class OracleLexer extends Lexer { map.put("WAIT", Token.WAIT); map.put("NOWAIT", Token.NOWAIT); map.put("SESSION", Token.SESSION); + 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); } @@ -177,7 +187,7 @@ public class OracleLexer extends Lexer { } public void scanComment() { - if (ch != '/') { + if (ch != '/' && ch != '-') { throw new IllegalStateException(); } @@ -227,7 +237,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 23e67bee81..4b205b9526 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); @@ -607,6 +616,14 @@ public class OracleSelectParser extends SQLSelectParser { queryBlock.setGroupBy(groupBy); } } + + protected String as() throws ParserException { + if (lexer.token() == Token.CONNECT) { + return null; + } + + return super.as(); + } private void parseHierachical(OracleSelectQueryBlock queryBlock) { OracleSelectHierachicalQueryClause hierachical = null; @@ -695,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); @@ -713,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")) { @@ -819,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; } @@ -841,12 +854,16 @@ public class OracleSelectParser extends SQLSelectParser { tableSource.setAlias(as()); } } + + if (lexer.token() == Token.HINT) { + this.createExprParser().parseHints(tableSource.getHints()); + } OracleSelectJoin.JoinType joinType = null; if (lexer.token() == Token.LEFT) { lexer.nextToken(); - if (identifierEquals("OUTER")) { + if (lexer.token() == Token.OUTER) { lexer.nextToken(); } accept(Token.JOIN); @@ -855,16 +872,16 @@ public class OracleSelectParser extends SQLSelectParser { if (lexer.token() == Token.RIGHT) { lexer.nextToken(); - if (identifierEquals("OUTER")) { + if (lexer.token() == Token.OUTER) { lexer.nextToken(); } accept(Token.JOIN); joinType = OracleSelectJoin.JoinType.RIGHT_OUTER_JOIN; } - if (identifierEquals("FULL")) { + if (lexer.token() == Token.FULL) { lexer.nextToken(); - if (identifierEquals("OUTER")) { + if (lexer.token() == Token.OUTER) { lexer.nextToken(); } accept(Token.JOIN); @@ -1050,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..0361217cac 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,6 +19,7 @@ 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; @@ -34,6 +35,8 @@ 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.OracleAlterSessionStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleBlockStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExceptionStatement; +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 +44,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 +80,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; } @@ -142,7 +156,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 +169,7 @@ public class OracleStatementParser extends SQLStatementParser { statementList.add(this.parseLock()); continue; } - + if (lexer.token() == Token.TRUNCATE) { statementList.add(this.parseTruncate()); continue; @@ -173,22 +192,113 @@ public class OracleStatementParser extends SQLStatementParser { statementList.add(stmt); continue; } - + + if (lexer.token() == Token.EXCEPTION) { + statementList.add(this.parseException()); + continue; + } + if (lexer.token() == Token.IDENTIFIER) { 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) { + lexer.nextToken(); + parseStatementList(statementList, statementList.size() + 1); + accept(Token.RPAREN); + continue; + } + + 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,13 +307,13 @@ 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; } @@ -236,7 +346,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 +443,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 +472,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 +547,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(); 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 4e0effd04e..c0de8f1918 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,20 +26,25 @@ 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; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDateExpr; +import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDatetimeExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDbLinkExpr; 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.OracleAlterSessionStatement; 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.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; @@ -64,6 +69,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; @@ -813,4 +819,74 @@ public class OracleASTVIsitorAdapter extends SQLASTVisitorAdapter implements Ora } + @Override + public boolean visit(OracleDatetimeExpr x) { + return true; + } + + @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) { + + } + } 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 ee59ef25e6..6b66deb48b 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,20 +32,25 @@ 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; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDateExpr; +import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDatetimeExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDbLinkExpr; 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.OracleAlterSessionStatement; 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.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; @@ -66,6 +71,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; @@ -355,4 +361,32 @@ public interface OracleASTVisitor extends SQLASTVisitor { 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); } 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 363fdcc16a..a036658eda 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 @@ -24,6 +24,7 @@ import com.alibaba.druid.sql.ast.SQLObject; import com.alibaba.druid.sql.ast.SQLSetQuantifier; import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLAllColumnExpr; +import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr; import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; import com.alibaba.druid.sql.ast.expr.SQLObjectCreateExpr; @@ -58,20 +59,25 @@ 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; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDateExpr; +import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDatetimeExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDbLinkExpr; 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.OracleAlterSessionStatement; 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.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; @@ -97,6 +103,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; @@ -126,12 +133,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(")"); @@ -335,6 +349,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; } @@ -473,6 +496,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 "); @@ -569,6 +598,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(); @@ -707,17 +740,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(); @@ -904,7 +943,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS } print("("); - print(x.getPercent()); + printAndAccept(x.getPercent(), ", "); print(")"); if (x.getSeedValue() != null) { @@ -1416,8 +1455,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(")"); @@ -1694,4 +1736,122 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS public void endVisit(OracleMethodInvokeStatement x) { } + + @Override + public boolean visit(OracleDatetimeExpr x) { + x.getExpr().accept(this); + SQLExpr timeZone = x.getTimeZone(); + + if (timeZone instanceof SQLIdentifierExpr) { + if (((SQLIdentifierExpr) timeZone).getName().equalsIgnoreCase("LOCAL")) { + print(" AT LOCAL"); + return false; + } + } + + print(" AT TIME ZONE "); + timeZone.accept(this); + + return false; + } + + @Override + 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) { + + } } 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 2b6a6eeea7..95c21560b7 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,20 +43,25 @@ 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; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDateExpr; +import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDatetimeExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDbLinkExpr; 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.OracleAlterSessionStatement; 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.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; @@ -79,6 +86,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; @@ -216,9 +224,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); @@ -231,7 +247,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()); @@ -1136,4 +1152,74 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle public void endVisit(OracleLockTableStatement x) { } + + @Override + public boolean visit(OracleDatetimeExpr x) { + return true; + } + + @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) { + + } } diff --git a/src/main/java/com/alibaba/druid/sql/parser/Keywords.java b/src/main/java/com/alibaba/druid/sql/parser/Keywords.java index 1f8975d830..cd9548aff7 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Keywords.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Keywords.java @@ -101,6 +101,10 @@ public class Keywords { map.put("DEFAULT", Token.DEFAULT); DEFAULT_KEYWORDS = new Keywords(map); } + + public boolean containsValue(Token token) { + return this.keywords.containsValue(token); + } public Keywords(Map keywords){ this.keywords = keywords; 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 e5affa0b58..70e8e36ac1 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Lexer.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Lexer.java @@ -90,6 +90,10 @@ public class Lexer { Token token; } + public Keywords getKeywods() { + return keywods; + } + public void mark() { SavePoint savePoint = new SavePoint(); savePoint.bp = bp; @@ -143,7 +147,7 @@ public class Lexer { protected final void scanChar() { ch = buf[++bp]; } - + protected void unscan() { ch = buf[--bp]; } @@ -292,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 { @@ -852,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 a0a6ceaa1e..e379933a68 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -201,6 +201,17 @@ public class SQLExprParser extends SQLParser { case USER: case PASSWORD: case DUAL: + case REFERENCE: + case KEY: + case DISTINCT: + case YEAR: + case MONTH: + case TIME: + case ZONE: + case LOG: + case LIMIT: + case SCHEMA: + case AT: sqlExpr = new SQLIdentifierExpr(lexer.stringVal()); lexer.nextToken(); break; @@ -250,9 +261,10 @@ public class SQLExprParser extends SQLParser { sqlExpr = new SQLExistsExpr(createSelectParser().select(), true); accept(Token.RPAREN); } else if (lexer.token() == Token.LPAREN) { - lexer.token(); + lexer.nextToken(); - sqlExpr = new SQLNotExpr(expr()); + SQLExpr notTarget = expr(); + sqlExpr = new SQLNotExpr(notTarget); accept(Token.RPAREN); return primaryRest(sqlExpr); @@ -393,13 +405,6 @@ public class SQLExprParser extends SQLParser { sqlExpr = someExpr; break; - case KEY: - case DISTINCT: - case YEAR: - case MONTH: - lexer.nextToken(); - sqlExpr = new SQLIdentifierExpr(tok.name()); - break; case ALL: lexer.nextToken(); SQLAllExpr allExpr = new SQLAllExpr(); @@ -414,7 +419,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); @@ -436,14 +441,26 @@ 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(); + 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); + } + lexer.nextToken(); if (isAggreateFunction(method_name)) { @@ -452,7 +469,7 @@ public class SQLExprParser extends SQLParser { return aggregateExpr; } - SQLMethodInvokeExpr methodInvokeExpr = new SQLMethodInvokeExpr(method_name); + if (lexer.token() != Token.RPAREN) { exprList(methodInvokeExpr.getParameters()); } @@ -476,14 +493,15 @@ public class SQLExprParser extends SQLParser { } else { String name; - if (lexer.token() == Token.KEY) { - name = "KEY"; - lexer.nextToken(); - } else if (lexer.token() != Token.IDENTIFIER && lexer.token() != Token.USER && lexer.token() != Token.PASSWORD) { - throw new ParserException("error : " + lexer.stringVal()); - } else { + 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())) { + name = lexer.stringVal(); + lexer.nextToken(); + } else { + throw new ParserException("error : " + lexer.stringVal()); } if (lexer.token() == Token.LPAREN) { @@ -567,16 +585,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()); } @@ -610,6 +629,7 @@ public class SQLExprParser extends SQLParser { } else { aggregateExpr = new SQLAggregateExpr(method_name, 1); } + exprList(aggregateExpr.getArguments()); accept(Token.RPAREN); @@ -693,7 +713,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(); @@ -920,9 +940,9 @@ public class SQLExprParser extends SQLParser { expr = notRationalRest(expr); } else if (lexer.token() == (Token.BETWEEN)) { lexer.nextToken(); - SQLExpr beginExpr = primary(); + SQLExpr beginExpr = bitOr(); accept(Token.AND); - SQLExpr endExpr = primary(); + SQLExpr endExpr = bitOr(); expr = new SQLBetweenExpr(expr, beginExpr, endExpr); } else if (lexer.token() == (Token.IS)) { lexer.nextToken(); @@ -981,9 +1001,9 @@ public class SQLExprParser extends SQLParser { return expr; } else if (lexer.token() == (Token.BETWEEN)) { lexer.nextToken(); - SQLExpr beginExpr = primary(); + SQLExpr beginExpr = bitOr(); accept(Token.AND); - SQLExpr endExpr = primary(); + SQLExpr endExpr = bitOr(); expr = new SQLBetweenExpr(expr, true, beginExpr, endExpr); @@ -995,8 +1015,8 @@ 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(); 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 3dfdbaedcb..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) { + 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) { + } 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(); } @@ -114,7 +117,8 @@ public class SQLParser { lexer.nextToken(); } else { setErrorEndPos(lexer.pos()); - throw new SQLParseException("syntax error, expect " + token + ", actual " + lexer.token() + " " + lexer.stringVal()); + throw new SQLParseException("syntax error, expect " + token + ", actual " + lexer.token() + " " + + lexer.stringVal()); } } 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 128768ba15..494a30fc0c 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,6 +159,14 @@ public enum Token { WAIT("WAIT"), ADVISE("ADVISE"), SESSION("SESSION"), + 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 94690c0247..08a6ef2cea 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java @@ -20,7 +20,9 @@ import com.alibaba.druid.sql.ast.expr.SQLInSubQueryExpr; import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr; 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; @@ -402,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); } @@ -677,7 +681,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { setMode(x, Mode.Delete); - String ident = ((SQLIdentifierExpr) x.getTableName()).getName(); + String ident = x.getTableName().toString(); currentTableLocal.set(ident); TableStat stat = tableStats.get(ident); @@ -753,4 +757,19 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { return false; } + + @Override + 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/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/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/OracleInsertTest4.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleInsertTest4.java new file mode 100644 index 0000000000..b2f178d0a2 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleInsertTest4.java @@ -0,0 +1,83 @@ +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 OracleInsertTest4 extends OracleTest { + + public void test_0() throws Exception { + String sql = "insert into \"OPS$ADMIN\".\"ORASTAT\"" + + // + " select /*+ rule */ :5 statid, 'C' type, :6 version, bitand(h.spare2,7) flags, " + + // + "ot.name c1, null c2, null c3, c.name c4, u.name c5, " + + // + " h.distcnt n1, h.density n2, h.spare1 n3, h.sample_size n4, h.null_cnt n5, " + + // + " h.minimum n6, h.maximum n7, h.avgcln n8, " + + // + " decode(h.cache_cnt,0,null,1) n9, hg.bucket n10, hg.endpoint n11, " + + // + " null n12, h.timestamp# d1, h.lowval r1, h.hival r2, hg.epvalue ch1 " + + // + " from sys.user$ u, sys.obj$ ot, sys.col$ c, sys.hist_head$ h, histgrm$ hg " + + // + " where :3 is null and u.name = :1 and ot.owner# = u.user# and " + + // + " ot.name = :2 and ot.type# = 2 and c.obj# = ot.obj# and " + + // + " (:4 is null or c.name = :4) and h.obj# = ot.obj# and h.intcol# = c.intcol# and " + + // + " hg.obj#(+) = h.obj# and hg.intcol#(+) = h.intcol# union all select :5 statid, " + + // + "'C' type, :6 version, bitand(h.spare2,7) flags, ot.name c1, op.subname c2, null c3, c.name c4, u.name c5, " + + // + " h.distcnt n1, h.density n2, h.spare1 n3, h.sample_size n4, h.null_cnt n5, " + + // + " h.minimum n6, h.maximum n7, h.avgcln n8, " + + // + " decode(h.cache_cnt,0,null,1) n9, hg.bucket n10, hg.endpoint n11, null n12, h.timestamp# d1, " + + " h.lowval r1, h.hival r2, hg.epvalue ch1 from sys.user$ u, sys.obj$ ot, sys.col$ c, sys.tabpart$ tp, sys.obj$ op, " + + " sys.hist_head$ h, histgrm$ hg where u.name = :1 and ot.owner# = u.user# and " + + " ot.name = :2 and ot.type# = 2 and c.obj# = ot.obj# and (:4 is null or c.name = :4) and " + + " tp.bo# = ot.obj# and tp.obj# = op.obj# and ((:3 is null and :vc_cascade_parts is not null) " + + " or op.subname = :3) and h.obj# = op.obj# and h.intcol# = c.intcol# and " + + " hg.obj#(+) = h.obj# and hg.intcol#(+) = h.intcol# " + + "" + + " union all select :5 statid, 'C' type, :6 version, bitand(h.spare2,7) flags, " + + " op.name c1, op.subname c2, null c3, c.name c4, u.name c5, h.distcnt n1, h.density n2, h.spare1 n3, h.sample_size n4, h.null_cnt n5, h.minimum n6, h.maximum n7, h.avgcln n8, decode(h.cache_cnt,0,null,1) n9, hg.bucket n10, hg.endpoint n11, null n12, h.timestamp# d1, h.lowval r1, h.hival r2, hg.epvalue ch1 from sys.user$ u, sys.col$ c, sys.tabcompart$ tp, sys.obj$ op, sys.hist_head$ h, histgrm$ hg where u.name = :1 and op.owner# = u.user# and op.name = :2 and op.type# = 19 and ((:3 is null and :vc_cascade_parts is not null) or op.subname = :3) and tp.obj# = op.obj# and c.obj# = tp.bo# and (:4 is null or c.name = :4) and h.obj# = op.obj# and h.intcol# = c.intcol# and hg.obj#(+) = h.obj# and hg.intcol#(+) = h.intcol# union all select :5 statid, 'C' type, :6 version, bitand(h.spare2,7) flags, op.name c1, op.subname c2, os.subname c3, c.name c4, u.name c5, h.distcnt n1, h.density n2, h.spare1 n3, h.sample_size n4, h.null_cnt n5, h.minimum n6, h.maximum n7, h.avgcln n8, decode(h.cache_cnt,0,null,1) n9, hg.bucket n10, hg.endpoint n11, null n12, h.timestamp# d1, h.lowval r1, h.hival r2, hg.epvalue ch1 from sys.user$ u, sys.col$ c, sys.tabcompart$ tp, sys.obj$ op, sys.tabsubpart$ ts, sys.obj$ os, sys.hist_head$ h, histgrm$ hg where u.name = :1 and op.owner# = u.user# and op.name = :2 and op.type# = 19 and tp.obj# = op.obj# and c.obj# = tp.bo# and (:4 is null or c.name = :4) and ts.pobj# = tp.obj# and ts.obj# = os.obj# and ((:3 is null and :vc_cascade_parts is not null) or (op.subname = :3 and (:vc_cascade_parts is not null -- cascade to subpart or os.subname is null)) -- matches partition itself or os.subname = :3) and -- matches subpartition h.obj# = os.obj# and h.intcol# = c.intcol# and hg.obj#(+) = h.obj# and hg.intcol#(+) = h.intcol# order by c5,c1,c2,c3,c4,n10"; + + 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/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/OracleSelectTest12.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest12.java new file mode 100644 index 0000000000..a8fa2328fa --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest12.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 OracleSelectTest12 extends OracleTest { + + public void test_0() throws Exception { + String sql = "select /*+ use_nl(b c) ordered */ count(*) " + // + " from (" + // + " select distinct parent_id parentId from BUSINESS_ORDER a1 " + // + " where SELLER_SEQ in ( ?) " + // + " and not (order_from = 'safepay' and status in ('buyer_create', 'closed')) " + // + " ) b, business_order c where ID = b.parentId"; // + + 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("BUSINESS_ORDER"))); + + Assert.assertEquals(3, 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/OracleSelectTest13.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest13.java new file mode 100644 index 0000000000..1eca45b2fb --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest13.java @@ -0,0 +1,46 @@ +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 OracleSelectTest13 extends OracleTest { + + public void test_0() throws Exception { + String sql = "select id, table_id, event_type, pk_data, transaction_id, ignore_node_cluster_id, gmt_create " + + " from retl_data_search" + + " where id>=50001 and id<52001 and GMT_CREATE between sysdate-2 and sysdate order by 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()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("BUSINESS_ORDER"))); + + Assert.assertEquals(3, 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/OracleSelectTest14.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest14.java new file mode 100644 index 0000000000..ef778774e9 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest14.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 OracleSelectTest14 extends OracleTest { + + public void test_0() throws Exception { + String sql = "select /* EXEC_FROM_DBMS_XPLAN */ case when upper(sql_text) like '%DBMS_XPLAN%' then 0 else 1 end case, SQL_ID, child_number" + + " from v$sql where SQL_ID ='90jx354zd6jx5' and child_number =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("BUSINESS_ORDER"))); + + Assert.assertEquals(3, 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/OracleSelectTest15.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest15.java new file mode 100644 index 0000000000..4e8bec9064 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest15.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 OracleSelectTest15 extends OracleTest { + + public void test_0() throws Exception { + String sql = "SELECT CURRENT_TIMESTAMP(6) AT TIME ZONE 'PST' FROM \"DUAL\" \"A1\""; // + + 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/OracleSelectTest16.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest16.java new file mode 100644 index 0000000000..613227d6ab --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest16.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 OracleSelectTest16 extends OracleTest { + + public void test_0() throws Exception { + String sql = "select privilege#,level from sysauth$ connect by grantee#=prior privilege# and privilege#>0 start with grantee#=:1 and privilege#>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/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/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 3f904fd3d1..f4af9bc15a 100644 --- a/src/test/java/com/alibaba/druid/sql/TestTransform.java +++ b/src/test/java/com/alibaba/druid/sql/TestTransform.java @@ -5,9 +5,13 @@ import java.sql.Date; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.Statement; +import java.util.ArrayList; import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import junit.framework.Assert; +import oracle.jdbc.OracleStatement; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.sql.ast.SQLStatement; @@ -22,6 +26,8 @@ public class TestTransform extends OracleTest { private String password; private DruidDataSource dataSource; + private ExecutorService executor = Executors.newFixedThreadPool(10); + public void setUp() throws Exception { jdbcUrl = "jdbc:oracle:thin:@10.20.149.18:1521:emdb"; user = "wardon"; @@ -32,26 +38,119 @@ public class TestTransform extends OracleTest { dataSource.setUrl(jdbcUrl); dataSource.setUsername(user); dataSource.setPassword(password); + dataSource.setMaxActive(50); + dataSource.setPoolPreparedStatements(true); + dataSource.setMaxOpenPreparedStatements(100); + } + + public void f_test_createIndex() throws Exception { + String sql = "CREATE INDEX i_db_day_sql_fulltext on db_day_sql_fulltext (sql_id)"; + Connection conn = dataSource.getConnection(); + + Statement stmt = conn.createStatement(); + + stmt.execute(sql); + + conn.close(); + } + + private int updateCount = 0; + + public void updateRecord(String sqlId, String result) throws Exception { + Connection conn = dataSource.getConnection(); + + PreparedStatement stmt = conn.prepareStatement("UPDATE db_day_sql_fulltext SET SQL_PARSE_RESULT = ? WHERE sql_id = ?"); + + stmt.setString(1, result); + stmt.setString(2, sqlId); + + int updateCount = stmt.executeUpdate(); + if (updateCount < 1) { + throw new Exception(); + } + + stmt.close(); + + conn.close(); + + System.out.println((this.updateCount++) + " : " + sqlId); } public void test_transform() throws Exception { + + Connection conn = dataSource.getConnection(); + + int count = 0; + { + String sql = "SELECT COUNT(*) FROM db_day_sql_fulltext WHERE SQL_PARSE_RESULT IS NULL"; + Statement stmt = conn.createStatement(); + + ResultSet rs = stmt.executeQuery(sql); + rs.next(); + count = rs.getInt(1); + rs.close(); + stmt.close(); + } + System.out.println("COUNT : " + count); + String sql = "SELECT SNAP_DATE, DBNAME, SQL_ID, PIECE, SQL_TEXT" + // " , COMMAND_TYPE, LAST_SNAP_DATE, DB_PK, SQL_PARSE_RESULT " + // " FROM db_day_sql_fulltext " + // + " WHERE SQL_PARSE_RESULT IS NULL" + // " ORDER BY sql_id, piece"; - Connection conn = dataSource.getConnection(); - + Statement stmt = conn.createStatement(); + + OracleStatement oracleStmt = stmt.unwrap(OracleStatement.class); + oracleStmt.setRowPrefetch(100); + ResultSet rs = stmt.executeQuery(sql); Record r = null; - + + int i = 0; while (rs.next()) { r = new Record(); - + + i++; + Date d1 = rs.getDate(1); String s2 = rs.getString(2); String sqlId = rs.getString(3); - + + if (sqlId.equals("018vcjmqxuguv")) { + continue; + } + if (sqlId.equals("0d69js78vuh8j")) { + continue; + } + if (sqlId.equals("0khp9aykj08vq")) { + continue; + } + if (sqlId.equals("0ns0zv7qaxzus")) { + continue; + } + if (sqlId.equals("0tg8ryp81gq1w")) { + continue; + } + 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); r.setSqlId(sqlId); @@ -61,82 +160,177 @@ public class TestTransform extends OracleTest { r.setCommandType(rs.getInt(6)); r.setLastSnapshotDate(rs.getDate(7)); r.setDbPk(rs.getLong(8)); - - System.out.println(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(); - + conn.close(); } - - public void schemaStat(Record r) { + + public void schemaStat(final Record r) throws Exception { + executor.submit(new Runnable() { + + public void run() { + try { + schemaStatInternal(r); + } catch (Exception e) { + // e.printStackTrace(); + } + } + }); + } + + public void schemaStatInternal(Record r) throws Exception { String sql = r.getSqlText(); - + if (sql.startsWith("/* MV_REFRESH (INS) */")) { return; } if (sql.startsWith("/* MV_REFRESH (DEL) */")) { 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("EXPLAIN")) { + return; + } + if (sql.startsWith("SET")) { + return; + } + if (sql.startsWith("create index")) { + return; + } + if (sql.startsWith("alter ")) { + return; + } + if (sql.startsWith("create")) { + return; + } + if (sql.startsWith("CREATE")) { + return; + } + if (sql.startsWith("explain plan")) { + return; + } + if (sql.startsWith("ALTER ")) { + return; + } + if (r.getSqlId().equals("09x7ytfdk63sp")) { + return; + } + if (sql.indexOf("AS OF SNAPSHOT") != -1) { + return; + } + OracleStatementParser parser = new OracleStatementParser(sql); List statementList = parser.parseStatementList(); SQLStatement statemen = statementList.get(0); Assert.assertEquals(1, statementList.size()); - System.out.println(output(statementList)); + // System.out.println(output(statementList)); 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()); - + + StringBuffer buf = new StringBuffer(); + buf.append("Tables : " + visitor.getTables().toString()); + buf.append("\nColumns : " + visitor.getColumns().toString()); + buf.append("\nCoditions : " + visitor.getConditions().toString()); + buf.append("\nrelationships " + visitor.getRelationships().toString()); + + System.out.println(buf.toString()); + System.out.println(); System.out.println(); System.out.println(); + + updateRecord(r.getSqlId(), buf.toString()); } - + public void clearResult() throws Exception { Connection conn = dataSource.getConnection(); Statement stmt = conn.createStatement(); - + stmt.execute("DELETE FROM db_day_sql_fulltext"); stmt.close(); conn.close(); } public void f_test_migrate() throws Exception { + Connection conn = dataSource.getConnection(); + + int count = 0; + { + String sql = "SELECT COUNT(*) FROM db_day_sqltext"; + Statement stmt = conn.createStatement(); + + ResultSet rs = stmt.executeQuery(sql); + rs.next(); + count = rs.getInt(1); + rs.close(); + stmt.close(); + } + System.out.println("COUNT : " + count); + clearResult(); - + String sql = "SELECT SNAP_DATE, DBNAME, SQL_ID, PIECE, SQL_TEXT" + // " , COMMAND_TYPE, LAST_SNAP_DATE, DB_PK, SQL_PARSE_RESULT " + // " FROM db_day_sqltext " + // - " WHERE db_pk = 40 and snap_date = trunc(sysdate) " + // - " ORDER BY sql_id, piece"; - Connection conn = dataSource.getConnection(); + // " WHERE db_pk = 40 and snap_date = trunc(sysdate) " + // + " ORDER BY db_pk, sql_id, piece"; Statement stmt = conn.createStatement(); + OracleStatement oracleStmt = stmt.unwrap(OracleStatement.class); + oracleStmt.setRowPrefetch(1000); ResultSet rs = stmt.executeQuery(sql); + + List list = new ArrayList(); Record r = null; String lastSqlId = null; + int i = 0; + int j = 0; while (rs.next()) { + j++; Date d1 = rs.getDate(1); String s2 = rs.getString(2); String sqlId = rs.getString(3); if (lastSqlId == null || !lastSqlId.equals(sqlId)) { if (r != null) { - System.out.println(r.getSqlText()); + System.out.println((i++) + "/" + j + " : " + r.getSqlId()); System.out.println(); - insert(r); + try { + setInfo(r); + } catch (Exception e) { + e.printStackTrace(); + } + + list.add(r); + if (list.size() > 100) { + insert(list); + list.clear(); + } } r = new Record(); @@ -152,19 +346,46 @@ public class TestTransform extends OracleTest { } else { String part = rs.getString(5); if (part != null) { - r.setSqlText(r.getSqlText() + part); + r.appendSqlText(part); } } lastSqlId = sqlId; } + + insert(list); rs.close(); stmt.close(); conn.close(); } - public void insert(Record r) throws Exception { + public void setInfo(Record r) { + OracleStatementParser parser = new OracleStatementParser(r.getSqlText()); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + + Assert.assertEquals(1, statementList.size()); + // System.out.println(output(statementList)); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + StringBuffer buf = new StringBuffer(); + buf.append("Tables : " + visitor.getTables().toString()); + buf.append("\nColumns : " + visitor.getColumns().toString()); + buf.append("\nCoditions : " + visitor.getConditions().toString()); + buf.append("\nrelationships " + visitor.getRelationships().toString()); + + r.setResult(buf.toString()); + + } + + public void insert(List list) throws Exception { + if (list.size() == 0) { + return; + } + String sql = "INSERT INTO db_day_sql_fulltext " + // "(SNAP_DATE, DBNAME, SQL_ID, PIECE, SQL_TEXT" + // ", COMMAND_TYPE, LAST_SNAP_DATE, DB_PK, SQL_PARSE_RESULT)" + // @@ -173,18 +394,21 @@ public class TestTransform extends OracleTest { PreparedStatement stmt = conn.prepareStatement(sql); - stmt.setDate(1, r.getSnapshotDate()); - stmt.setString(2, r.getDbName()); - stmt.setString(3, r.getSqlId()); - stmt.setInt(4, r.getPiece()); - stmt.setString(5, r.getSqlText()); + for (Record r : list) { + stmt.setDate(1, r.getSnapshotDate()); + stmt.setString(2, r.getDbName()); + stmt.setString(3, r.getSqlId()); + stmt.setInt(4, r.getPiece()); + stmt.setString(5, r.getSqlText()); - stmt.setInt(6, r.getCommandType()); - stmt.setDate(7, r.getLastSnapshotDate()); - stmt.setLong(8, r.getDbPk()); - stmt.setString(9, r.getSqlText()); - - stmt.execute(); + stmt.setInt(6, r.getCommandType()); + stmt.setDate(7, r.getLastSnapshotDate()); + stmt.setLong(8, r.getDbPk()); + stmt.setString(9, r.getResult()); + + stmt.addBatch(); + } + stmt.executeBatch(); stmt.close(); @@ -193,14 +417,23 @@ public class TestTransform extends OracleTest { public static class Record { - private Date snapshotDate; - private String dbName; - private String sqlId; - private String sqlText; - private Integer piece; - private Integer commandType; - private Date lastSnapshotDate; - private Long dbPk; + private Date snapshotDate; + private String dbName; + private String sqlId; + private StringBuffer sqlText = new StringBuffer(); + private Integer piece; + private Integer commandType; + private Date lastSnapshotDate; + private Long dbPk; + private String result; + + public String getResult() { + return result; + } + + public void setResult(String result) { + this.result = result; + } public Date getSnapshotDate() { return snapshotDate; @@ -227,11 +460,15 @@ public class TestTransform extends OracleTest { } public String getSqlText() { - return sqlText; + return sqlText.toString(); } public void setSqlText(String sqlText) { - this.sqlText = sqlText; + this.sqlText = new StringBuffer(sqlText); + } + + public void appendSqlText(String sqlText) { + this.sqlText.append(sqlText); } public Integer getPiece() {