diff --git a/src/main/java/com/alibaba/druid/filter/trace/TraceFilter.java b/src/main/java/com/alibaba/druid/filter/trace/TraceFilter.java index 86fe25b883..2b79162f29 100644 --- a/src/main/java/com/alibaba/druid/filter/trace/TraceFilter.java +++ b/src/main/java/com/alibaba/druid/filter/trace/TraceFilter.java @@ -51,6 +51,11 @@ import com.alibaba.druid.stat.JdbcTraceManager; public class TraceFilter extends FilterAdapter implements TraceFilterMBean { + + private static final String TRACE_STMT_COLUMN = "stmt.columnNames"; + + private static final String TRACE_STMT_RS_HOLDABILITY = "stmt.resultSetHoldability"; + public final static String ATTR_NAME_RESULT_SET = "trace.rs"; public final static String TRACE_CONN_ID = "conn.id"; @@ -61,8 +66,11 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { public final static String TRACE_STMT_PARAMS = "stmt.params"; public final static String TRACE_STMT_UPDATE_COUNT = "stmt.updateCount"; public final static String TRACE_STMT_COLUMN_INDEXES = "stmt.columnIndexes"; + public final static String TRACE_STMT_RS_TYPE = "stmt.resultSetType"; + public static final String TRACE_STMT_RS_CONCURRENCY = "stmt.resultSetConcurrency"; public final static String TRACE_RS_ID = "rs.id"; public final static String TRACE_RS_CURSOR_INDEX = "rs.cusorIndex"; + public TraceFilter(){ @@ -489,8 +497,8 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_CONNECTED_TIME, connection.getConnectedTime()); event.putContext(TRACE_CONN_ID, connection.getId()); event.putContext(TRACE_STMT_SQL, sql); - event.putContext("stmt.resultSetType", resultSetType); - event.putContext("stmt.resultSetConcurrency", resultSetConcurrency); + event.putContext(TRACE_STMT_RS_TYPE, resultSetType); + event.putContext(TRACE_STMT_RS_CONCURRENCY, resultSetConcurrency); fireEvent(event); } @@ -507,8 +515,8 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_ID, connection.getId()); event.putContext(TRACE_STMT_ID, statement.getId()); event.putContext(TRACE_STMT_SQL, sql); - event.putContext("stmt.resultSetType", resultSetType); - event.putContext("stmt.resultSetConcurrency", resultSetConcurrency); + event.putContext(TRACE_STMT_RS_TYPE, resultSetType); + event.putContext(TRACE_STMT_RS_CONCURRENCY, resultSetConcurrency); fireEvent(event); } @@ -521,8 +529,8 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_CONNECTED_TIME, connection.getConnectedTime()); event.putContext(TRACE_CONN_ID, connection.getId()); event.putContext(TRACE_STMT_SQL, sql); - event.putContext("stmt.resultSetType", resultSetType); - event.putContext("stmt.resultSetConcurrency", resultSetConcurrency); + event.putContext(TRACE_STMT_RS_TYPE, resultSetType); + event.putContext(TRACE_STMT_RS_CONCURRENCY, resultSetConcurrency); fireEvent(event); } throw ex; @@ -534,8 +542,8 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_CONNECTED_TIME, connection.getConnectedTime()); event.putContext(TRACE_CONN_ID, connection.getId()); event.putContext(TRACE_STMT_SQL, sql); - event.putContext("stmt.resultSetType", resultSetType); - event.putContext("stmt.resultSetConcurrency", resultSetConcurrency); + event.putContext(TRACE_STMT_RS_TYPE, resultSetType); + event.putContext(TRACE_STMT_RS_CONCURRENCY, resultSetConcurrency); fireEvent(event); } throw ex; @@ -559,9 +567,9 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_CONNECTED_TIME, connection.getConnectedTime()); event.putContext(TRACE_CONN_ID, connection.getId()); event.putContext(TRACE_STMT_SQL, sql); - event.putContext("stmt.resultSetType", resultSetType); - event.putContext("stmt.resultSetConcurrency", resultSetConcurrency); - event.putContext("stmt.resultSetHoldability", resultSetHoldability); + event.putContext(TRACE_STMT_RS_TYPE, resultSetType); + event.putContext(TRACE_STMT_RS_CONCURRENCY, resultSetConcurrency); + event.putContext(TRACE_STMT_RS_HOLDABILITY, resultSetHoldability); fireEvent(event); } @@ -579,9 +587,9 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_ID, connection.getId()); event.putContext(TRACE_STMT_ID, statement.getId()); event.putContext(TRACE_STMT_SQL, sql); - event.putContext("stmt.resultSetType", resultSetType); - event.putContext("stmt.resultSetConcurrency", resultSetConcurrency); - event.putContext("stmt.resultSetHoldability", resultSetHoldability); + event.putContext(TRACE_STMT_RS_TYPE, resultSetType); + event.putContext(TRACE_STMT_RS_CONCURRENCY, resultSetConcurrency); + event.putContext(TRACE_STMT_RS_HOLDABILITY, resultSetHoldability); fireEvent(event); } @@ -594,9 +602,9 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_CONNECTED_TIME, connection.getConnectedTime()); event.putContext(TRACE_CONN_ID, connection.getId()); event.putContext(TRACE_STMT_SQL, sql); - event.putContext("stmt.resultSetType", resultSetType); - event.putContext("stmt.resultSetConcurrency", resultSetConcurrency); - event.putContext("stmt.resultSetHoldability", resultSetHoldability); + event.putContext(TRACE_STMT_RS_TYPE, resultSetType); + event.putContext(TRACE_STMT_RS_CONCURRENCY, resultSetConcurrency); + event.putContext(TRACE_STMT_RS_HOLDABILITY, resultSetHoldability); fireEvent(event); } throw ex; @@ -608,9 +616,9 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_CONNECTED_TIME, connection.getConnectedTime()); event.putContext(TRACE_CONN_ID, connection.getId()); event.putContext(TRACE_STMT_SQL, sql); - event.putContext("stmt.resultSetType", resultSetType); - event.putContext("stmt.resultSetConcurrency", resultSetConcurrency); - event.putContext("stmt.resultSetHoldability", resultSetHoldability); + event.putContext(TRACE_STMT_RS_TYPE, resultSetType); + event.putContext(TRACE_STMT_RS_CONCURRENCY, resultSetConcurrency); + event.putContext(TRACE_STMT_RS_HOLDABILITY, resultSetHoldability); fireEvent(event); } throw ex; @@ -695,7 +703,7 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_CONNECTED_TIME, connection.getConnectedTime()); event.putContext(TRACE_CONN_ID, connection.getId()); event.putContext(TRACE_STMT_SQL, sql); - event.putContext("stmt.columnNames", columnNames); + event.putContext(TRACE_STMT_COLUMN, columnNames); fireEvent(event); } @@ -711,7 +719,7 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_ID, connection.getId()); event.putContext(TRACE_STMT_ID, statement.getId()); event.putContext(TRACE_STMT_SQL, sql); - event.putContext("stmt.columnNames", columnNames); + event.putContext(TRACE_STMT_COLUMN, columnNames); fireEvent(event); } @@ -724,7 +732,7 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_CONNECTED_TIME, connection.getConnectedTime()); event.putContext(TRACE_CONN_ID, connection.getId()); event.putContext(TRACE_STMT_SQL, sql); - event.putContext("stmt.columnNames", columnNames); + event.putContext(TRACE_STMT_COLUMN, columnNames); fireEvent(event); } throw ex; @@ -736,7 +744,7 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_CONNECTED_TIME, connection.getConnectedTime()); event.putContext(TRACE_CONN_ID, connection.getId()); event.putContext(TRACE_STMT_SQL, sql); - event.putContext("stmt.columnNames", columnNames); + event.putContext(TRACE_STMT_COLUMN, columnNames); fireEvent(event); } throw ex; @@ -815,8 +823,8 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_CONNECTED_TIME, connection.getConnectedTime()); event.putContext(TRACE_CONN_ID, connection.getId()); event.putContext(TRACE_STMT_SQL, sql); - event.putContext("stmt.resultSetType", resultSetType); - event.putContext("stmt.resultSetConcurrency", resultSetConcurrency); + event.putContext(TRACE_STMT_RS_TYPE, resultSetType); + event.putContext(TRACE_STMT_RS_CONCURRENCY, resultSetConcurrency); fireEvent(event); } @@ -832,8 +840,8 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_ID, connection.getId()); event.putContext(TRACE_STMT_ID, statement.getId()); event.putContext(TRACE_STMT_SQL, sql); - event.putContext("stmt.resultSetType", resultSetType); - event.putContext("stmt.resultSetConcurrency", resultSetConcurrency); + event.putContext(TRACE_STMT_RS_TYPE, resultSetType); + event.putContext(TRACE_STMT_RS_CONCURRENCY, resultSetConcurrency); fireEvent(event); } @@ -845,8 +853,8 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_CONNECTED_TIME, connection.getConnectedTime()); event.putContext(TRACE_CONN_ID, connection.getId()); event.putContext(TRACE_STMT_SQL, sql); - event.putContext("stmt.resultSetType", resultSetType); - event.putContext("stmt.resultSetConcurrency", resultSetConcurrency); + event.putContext(TRACE_STMT_RS_TYPE, resultSetType); + event.putContext(TRACE_STMT_RS_CONCURRENCY, resultSetConcurrency); fireEvent(event); } throw ex; @@ -857,8 +865,8 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_CONNECTED_TIME, connection.getConnectedTime()); event.putContext(TRACE_CONN_ID, connection.getId()); event.putContext(TRACE_STMT_SQL, sql); - event.putContext("stmt.resultSetType", resultSetType); - event.putContext("stmt.resultSetConcurrency", resultSetConcurrency); + event.putContext(TRACE_STMT_RS_TYPE, resultSetType); + event.putContext(TRACE_STMT_RS_CONCURRENCY, resultSetConcurrency); fireEvent(event); } throw ex; @@ -882,9 +890,9 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_CONNECTED_TIME, connection.getConnectedTime()); event.putContext(TRACE_CONN_ID, connection.getId()); event.putContext(TRACE_STMT_SQL, sql); - event.putContext("stmt.resultSetType", resultSetType); - event.putContext("stmt.resultSetConcurrency", resultSetConcurrency); - event.putContext("stmt.resultSetHoldability", resultSetHoldability); + event.putContext(TRACE_STMT_RS_TYPE, resultSetType); + event.putContext(TRACE_STMT_RS_CONCURRENCY, resultSetConcurrency); + event.putContext(TRACE_STMT_RS_HOLDABILITY, resultSetHoldability); fireEvent(event); } @@ -900,9 +908,9 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_ID, connection.getId()); event.putContext(TRACE_STMT_ID, statement.getId()); event.putContext(TRACE_STMT_SQL, sql); - event.putContext("stmt.resultSetType", resultSetType); - event.putContext("stmt.resultSetConcurrency", resultSetConcurrency); - event.putContext("stmt.resultSetHoldability", resultSetHoldability); + event.putContext(TRACE_STMT_RS_TYPE, resultSetType); + event.putContext(TRACE_STMT_RS_CONCURRENCY, resultSetConcurrency); + event.putContext(TRACE_STMT_RS_HOLDABILITY, resultSetHoldability); fireEvent(event); } @@ -914,9 +922,9 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_CONNECTED_TIME, connection.getConnectedTime()); event.putContext(TRACE_CONN_ID, connection.getId()); event.putContext(TRACE_STMT_SQL, sql); - event.putContext("stmt.resultSetType", resultSetType); - event.putContext("stmt.resultSetConcurrency", resultSetConcurrency); - event.putContext("stmt.resultSetHoldability", resultSetHoldability); + event.putContext(TRACE_STMT_RS_TYPE, resultSetType); + event.putContext(TRACE_STMT_RS_CONCURRENCY, resultSetConcurrency); + event.putContext(TRACE_STMT_RS_HOLDABILITY, resultSetHoldability); fireEvent(event); } throw ex; @@ -927,9 +935,9 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_CONNECTED_TIME, connection.getConnectedTime()); event.putContext(TRACE_CONN_ID, connection.getId()); event.putContext(TRACE_STMT_SQL, sql); - event.putContext("stmt.resultSetType", resultSetType); - event.putContext("stmt.resultSetConcurrency", resultSetConcurrency); - event.putContext("stmt.resultSetHoldability", resultSetHoldability); + event.putContext(TRACE_STMT_RS_TYPE, resultSetType); + event.putContext(TRACE_STMT_RS_CONCURRENCY, resultSetConcurrency); + event.putContext(TRACE_STMT_RS_HOLDABILITY, resultSetHoldability); fireEvent(event); } throw ex; @@ -1002,8 +1010,8 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_INFO, connection.getProperties().clone()); event.putContext(TRACE_CONN_CONNECTED_TIME, connection.getConnectedTime()); event.putContext(TRACE_CONN_ID, connection.getId()); - event.putContext("stmt.resultSetType", resultSetType); - event.putContext("stmt.resultSetConcurrency", resultSetConcurrency); + event.putContext(TRACE_STMT_RS_TYPE, resultSetType); + event.putContext(TRACE_STMT_RS_CONCURRENCY, resultSetConcurrency); fireEvent(event); } @@ -1018,8 +1026,8 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_CONNECTED_TIME, connection.getConnectedTime()); event.putContext(TRACE_CONN_ID, connection.getId()); event.putContext(TRACE_STMT_ID, statement.getId()); - event.putContext("stmt.resultSetType", resultSetType); - event.putContext("stmt.resultSetConcurrency", resultSetConcurrency); + event.putContext(TRACE_STMT_RS_TYPE, resultSetType); + event.putContext(TRACE_STMT_RS_CONCURRENCY, resultSetConcurrency); fireEvent(event); } @@ -1030,8 +1038,8 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_INFO, connection.getProperties().clone()); event.putContext(TRACE_CONN_CONNECTED_TIME, connection.getConnectedTime()); event.putContext(TRACE_CONN_ID, connection.getId()); - event.putContext("stmt.resultSetType", resultSetType); - event.putContext("stmt.resultSetConcurrency", resultSetConcurrency); + event.putContext(TRACE_STMT_RS_TYPE, resultSetType); + event.putContext(TRACE_STMT_RS_CONCURRENCY, resultSetConcurrency); fireEvent(event); } throw ex; @@ -1041,8 +1049,8 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_INFO, connection.getProperties().clone()); event.putContext(TRACE_CONN_CONNECTED_TIME, connection.getConnectedTime()); event.putContext(TRACE_CONN_ID, connection.getId()); - event.putContext("stmt.resultSetType", resultSetType); - event.putContext("stmt.resultSetConcurrency", resultSetConcurrency); + event.putContext(TRACE_STMT_RS_TYPE, resultSetType); + event.putContext(TRACE_STMT_RS_CONCURRENCY, resultSetConcurrency); fireEvent(event); } throw ex; @@ -1065,9 +1073,9 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_INFO, connection.getProperties().clone()); event.putContext(TRACE_CONN_CONNECTED_TIME, connection.getConnectedTime()); event.putContext(TRACE_CONN_ID, connection.getId()); - event.putContext("stmt.resultSetType", resultSetType); - event.putContext("stmt.resultSetConcurrency", resultSetConcurrency); - event.putContext("stmt.resultSetHoldability", resultSetHoldability); + event.putContext(TRACE_STMT_RS_TYPE, resultSetType); + event.putContext(TRACE_STMT_RS_CONCURRENCY, resultSetConcurrency); + event.putContext(TRACE_STMT_RS_HOLDABILITY, resultSetHoldability); fireEvent(event); } @@ -1084,9 +1092,9 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_CONNECTED_TIME, connection.getConnectedTime()); event.putContext(TRACE_CONN_ID, connection.getId()); event.putContext(TRACE_STMT_ID, statement.getId()); - event.putContext("stmt.resultSetType", resultSetType); - event.putContext("stmt.resultSetConcurrency", resultSetConcurrency); - event.putContext("stmt.resultSetHoldability", resultSetHoldability); + event.putContext(TRACE_STMT_RS_TYPE, resultSetType); + event.putContext(TRACE_STMT_RS_CONCURRENCY, resultSetConcurrency); + event.putContext(TRACE_STMT_RS_HOLDABILITY, resultSetHoldability); fireEvent(event); } @@ -1097,9 +1105,9 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_INFO, connection.getProperties().clone()); event.putContext(TRACE_CONN_CONNECTED_TIME, connection.getConnectedTime()); event.putContext(TRACE_CONN_ID, connection.getId()); - event.putContext("stmt.resultSetType", resultSetType); - event.putContext("stmt.resultSetConcurrency", resultSetConcurrency); - event.putContext("stmt.resultSetHoldability", resultSetHoldability); + event.putContext(TRACE_STMT_RS_TYPE, resultSetType); + event.putContext(TRACE_STMT_RS_CONCURRENCY, resultSetConcurrency); + event.putContext(TRACE_STMT_RS_HOLDABILITY, resultSetHoldability); fireEvent(event); } throw ex; @@ -1109,9 +1117,9 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_INFO, connection.getProperties().clone()); event.putContext(TRACE_CONN_CONNECTED_TIME, connection.getConnectedTime()); event.putContext(TRACE_CONN_ID, connection.getId()); - event.putContext("stmt.resultSetType", resultSetType); - event.putContext("stmt.resultSetConcurrency", resultSetConcurrency); - event.putContext("stmt.resultSetHoldability", resultSetHoldability); + event.putContext(TRACE_STMT_RS_TYPE, resultSetType); + event.putContext(TRACE_STMT_RS_CONCURRENCY, resultSetConcurrency); + event.putContext(TRACE_STMT_RS_HOLDABILITY, resultSetHoldability); fireEvent(event); } throw ex; @@ -1341,7 +1349,7 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_ID, connection.getId()); event.putContext(TRACE_STMT_ID, statement.getId()); event.putContext(TRACE_STMT_SQL, sql); - event.putContext("stmt.columnNames", columnNames); + event.putContext(TRACE_STMT_COLUMN, columnNames); fireEvent(event); } @@ -1709,7 +1717,7 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_ID, connection.getId()); event.putContext(TRACE_STMT_ID, statement.getId()); event.putContext(TRACE_STMT_SQL, sql); - event.putContext("stmt.columnNames", columnNames); + event.putContext(TRACE_STMT_COLUMN, columnNames); fireEvent(event); } @@ -1726,7 +1734,7 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_ID, connection.getId()); event.putContext(TRACE_STMT_ID, statement.getId()); event.putContext(TRACE_STMT_SQL, sql); - event.putContext("stmt.columnNames", columnNames); + event.putContext(TRACE_STMT_COLUMN, columnNames); event.putContext(TRACE_STMT_UPDATE_COUNT, updateCount); fireEvent(event); } @@ -1740,7 +1748,7 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_ID, connection.getId()); event.putContext(TRACE_STMT_ID, statement.getId()); event.putContext(TRACE_STMT_SQL, sql); - event.putContext("stmt.columnNames", columnNames); + event.putContext(TRACE_STMT_COLUMN, columnNames); fireEvent(event); } throw ex; @@ -1752,7 +1760,7 @@ public class TraceFilter extends FilterAdapter implements TraceFilterMBean { event.putContext(TRACE_CONN_ID, connection.getId()); event.putContext(TRACE_STMT_ID, statement.getId()); event.putContext(TRACE_STMT_SQL, sql); - event.putContext("stmt.columnNames", columnNames); + event.putContext(TRACE_STMT_COLUMN, columnNames); fireEvent(event); } throw ex; diff --git a/src/main/java/com/alibaba/druid/sql/ast/SQLStatementImpl.java b/src/main/java/com/alibaba/druid/sql/ast/SQLStatementImpl.java index a5d8f5b151..ca8a4450a6 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/SQLStatementImpl.java +++ b/src/main/java/com/alibaba/druid/sql/ast/SQLStatementImpl.java @@ -15,7 +15,6 @@ */ package com.alibaba.druid.sql.ast; -import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; import com.alibaba.druid.sql.visitor.SQLASTVisitor; public abstract class SQLStatementImpl extends SQLObjectImpl implements SQLStatement { @@ -34,8 +33,4 @@ public abstract class SQLStatementImpl extends SQLObjectImpl implements SQLState protected void accept0(SQLASTVisitor visitor) { throw new UnsupportedOperationException(this.getClass().getName()); } - - protected void accept0(OracleASTVisitor visitor) { - throw new UnsupportedOperationException(this.getClass().getName()); - } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLCurrentOfCursorExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLCurrentOfCursorExpr.java index 9c9f0e127f..c037a80a81 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLCurrentOfCursorExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLCurrentOfCursorExpr.java @@ -29,6 +29,10 @@ public class SQLCurrentOfCursorExpr extends SQLExprImpl { } + public SQLCurrentOfCursorExpr(SQLName cursorName){ + this.cursorName = cursorName; + } + public SQLName getCursorName() { return cursorName; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/OracleParameter.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/OracleParameter.java index 6f05879131..99217b75d3 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/OracleParameter.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/OracleParameter.java @@ -41,6 +41,7 @@ public class OracleParameter extends OracleSQLObjectImpl { if (visitor.visit(this)) { acceptChild(visitor, name); acceptChild(visitor, dataType); + acceptChild(visitor, defaultValue); } visitor.endVisit(this); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCommitStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCommitStatement.java index 7ea7022f2c..235a9d3307 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCommitStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCommitStatement.java @@ -6,12 +6,40 @@ public class OracleCommitStatement extends OracleStatementImpl { private static final long serialVersionUID = 1L; + private boolean write; + private Boolean wait; + private Boolean immediate; + @Override public void accept0(OracleASTVisitor visitor) { if (visitor.visit(this)) { - + } visitor.endVisit(this); } + public boolean isWrite() { + return write; + } + + public void setWrite(boolean write) { + this.write = write; + } + + public Boolean getWait() { + return wait; + } + + public void setWait(Boolean wait) { + this.wait = wait; + } + + public Boolean getImmediate() { + return immediate; + } + + public void setImmediate(Boolean immediate) { + this.immediate = immediate; + } + } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateProcedureStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateProcedureStatement.java new file mode 100644 index 0000000000..0a82dc4cfe --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateProcedureStatement.java @@ -0,0 +1,61 @@ +package com.alibaba.druid.sql.dialect.oracle.ast.stmt; + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.druid.sql.ast.SQLName; +import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleParameter; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; + +public class OracleCreateProcedureStatement extends OracleStatementImpl { + + private static final long serialVersionUID = 1L; + + private boolean orReplace; + private SQLName name; + private OracleBlockStatement block; + private List parameters = new ArrayList(); + + @Override + public void accept0(OracleASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, name); + acceptChild(visitor, parameters); + acceptChild(visitor, block); + } + visitor.endVisit(this); + } + + public List getParameters() { + return parameters; + } + + public void setParameters(List parameters) { + this.parameters = parameters; + } + + public SQLName getName() { + return name; + } + + public void setName(SQLName name) { + this.name = name; + } + + public OracleBlockStatement getBlock() { + return block; + } + + public void setBlock(OracleBlockStatement block) { + this.block = block; + } + + public boolean isOrReplace() { + return orReplace; + } + + public void setOrReplace(boolean orReplace) { + this.orReplace = orReplace; + } + +} 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 index 6f71b42af8..76165444ea 100644 --- 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 @@ -23,9 +23,9 @@ public class OracleExceptionStatement extends OracleSQLObjectImpl implements Ora public static class Item extends OracleSQLObjectImpl { - private static final long serialVersionUID = 1L; - private SQLExpr when; - private SQLStatement statement; + private static final long serialVersionUID = 1L; + private SQLExpr when; + private List statements = new ArrayList(); public SQLExpr getWhen() { return when; @@ -35,19 +35,19 @@ public class OracleExceptionStatement extends OracleSQLObjectImpl implements Ora this.when = when; } - public SQLStatement getStatement() { - return statement; + public List getStatements() { + return statements; } - public void setStatement(SQLStatement statement) { - this.statement = statement; + public void setStatements(List statements) { + this.statements = statements; } @Override public void accept0(OracleASTVisitor visitor) { if (visitor.visit(this)) { acceptChild(visitor, when); - acceptChild(visitor, statement); + acceptChild(visitor, statements); } visitor.endVisit(this); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleFetchStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleFetchStatement.java new file mode 100644 index 0000000000..59506b1f5b --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleFetchStatement.java @@ -0,0 +1,43 @@ +package com.alibaba.druid.sql.dialect.oracle.ast.stmt; + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLName; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; + +public class OracleFetchStatement extends OracleStatementImpl { + + private static final long serialVersionUID = 1L; + + private SQLName cursorName; + + private List into = new ArrayList(); + + @Override + public void accept0(OracleASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, cursorName); + acceptChild(visitor, into); + } + visitor.endVisit(this); + } + + public SQLName getCursorName() { + return cursorName; + } + + public void setCursorName(SQLName cursorName) { + this.cursorName = cursorName; + } + + public List getInto() { + return into; + } + + public void setInto(List into) { + this.into = into; + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OraclePLSQLCommitStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OraclePLSQLCommitStatement.java index 9f8a80179e..09d30f4544 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OraclePLSQLCommitStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OraclePLSQLCommitStatement.java @@ -15,10 +15,9 @@ */ package com.alibaba.druid.sql.dialect.oracle.ast.stmt; -import com.alibaba.druid.sql.ast.SQLStatementImpl; import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; -public class OraclePLSQLCommitStatement extends SQLStatementImpl { +public class OraclePLSQLCommitStatement extends OracleStatementImpl { private static final long serialVersionUID = 1L; @@ -26,7 +25,7 @@ public class OraclePLSQLCommitStatement extends SQLStatementImpl { } - protected void accept0(OracleASTVisitor visitor) { + 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/OracleRollbackStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleRollbackStatement.java new file mode 100644 index 0000000000..c3a43ff235 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleRollbackStatement.java @@ -0,0 +1,28 @@ +package com.alibaba.druid.sql.dialect.oracle.ast.stmt; + +import com.alibaba.druid.sql.ast.SQLName; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; + +public class OracleRollbackStatement extends OracleStatementImpl { + + private static final long serialVersionUID = 1L; + + private SQLName to; + + @Override + public void accept0(OracleASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, to); + } + visitor.endVisit(this); + } + + public SQLName getTo() { + return to; + } + + public void setTo(SQLName to) { + this.to = to; + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSavePointStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSavePointStatement.java new file mode 100644 index 0000000000..4f11cdc5e1 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSavePointStatement.java @@ -0,0 +1,28 @@ +package com.alibaba.druid.sql.dialect.oracle.ast.stmt; + +import com.alibaba.druid.sql.ast.SQLName; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; + +public class OracleSavePointStatement extends OracleStatementImpl { + + private static final long serialVersionUID = 1L; + + private SQLName to; + + @Override + public void accept0(OracleASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, to); + } + visitor.endVisit(this); + } + + public SQLName getTo() { + return to; + } + + public void setTo(SQLName to) { + this.to = to; + } + +} 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 92d304a7e4..05d471b1b7 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 @@ -18,6 +18,8 @@ package com.alibaba.druid.sql.dialect.oracle.parser; import java.math.BigInteger; import java.util.List; +import com.alibaba.druid.sql.ast.SQLDataType; +import com.alibaba.druid.sql.ast.SQLDataTypeImpl; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLOrderingSpecification; @@ -65,24 +67,21 @@ import com.alibaba.druid.sql.parser.SQLExprParser; import com.alibaba.druid.sql.parser.Token; public class OracleExprParser extends SQLExprParser { - - - - - - - - - - - public boolean allowStringAdditive = false; /** * @formatter:off */ - private static final String[] _aggregateFunctions = { "AVG", "CORR", "COVAR_POP", "COVAR_SAMP", "COUNT", "CUME_DIST", "DENSE_RANK", "FIRST", "FIRST_VALUE", "LAG", "LAST", "LAST_VALUE", "LEAD", "MAX", "MIN", "NTILE", "PERCENT_RANK", "PERCENTILE_CONT", "PERCENTILE_DISC", "RANK", "RATIO_TO_REPORT", "REGR_SLOPE", "REGR_INTERCEPT", "REGR_COUNT", "REGR_R2", "REGR_AVGX", - "REGR_AVGY", "REGR_SXX", "REGR_SYY", "REGR_SXY", "ROW_NUMBER", "STDDEV", "STDDEV_POP", "STDDEV_SAMP", "SUM", "VAR_POP", "VAR_SAMP", "VARIANCE" }; + private static final String[] _aggregateFunctions = { // + "AVG", "CORR", "COVAR_POP", "COVAR_SAMP", "COUNT", // + "CUME_DIST", "DENSE_RANK", "FIRST", "FIRST_VALUE", // + "LAG", "LAST", "LAST_VALUE", "LEAD", "MAX", "MIN", // + "NTILE", "PERCENT_RANK", "PERCENTILE_CONT", "PERCENTILE_DISC", "RANK", // + "RATIO_TO_REPORT", "REGR_SLOPE", "REGR_INTERCEPT", "REGR_COUNT", "REGR_R2", // + "REGR_AVGX", "REGR_AVGY", "REGR_SXX", "REGR_SYY", "REGR_SXY", // + "ROW_NUMBER", "STDDEV", "STDDEV_POP", "STDDEV_SAMP", "SUM", // + "VAR_POP", "VAR_SAMP", "VARIANCE" // + }; public OracleExprParser(Lexer lexer){ super(lexer); @@ -92,6 +91,33 @@ public class OracleExprParser extends SQLExprParser { super(new OracleLexer(text)); this.lexer.nextToken(); } + + public SQLDataType parseDataType() throws ParserException { + + if (lexer.token() == Token.DEFAULT || lexer.token() == Token.NOT || lexer.token() == Token.NULL) { + return null; + } + + SQLName typeExpr = name(); + String typeName = typeExpr.toString(); + + if (lexer.token() == Token.PERCENT) { + lexer.nextToken(); + if (identifierEquals("TYPE")) { + lexer.nextToken(); + typeName += "%TYPE"; + } else if (identifierEquals("ROWTYPE")) { + lexer.nextToken(); + typeName += "%ROWTYPE"; + } else { + throw new ParserException("syntax error : " + lexer.token() + " " + lexer.stringVal()); + } + } + + SQLDataType dataType = new SQLDataTypeImpl(typeName); + parseDataTypeRest(dataType); + return dataType; + } public boolean isAggreateFunction(String word) { for (int i = 0; i < _aggregateFunctions.length; ++i) { 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 b8eb629354..cfb4936e37 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 @@ -139,6 +139,8 @@ public class OracleLexer extends Lexer { map.put("ELSE", Token.ELSE); map.put("GOTO", Token.GOTO); map.put("COMMIT", Token.COMMIT); + map.put("ROLLBACK", Token.ROLLBACK); + map.put("SAVEPOINT", Token.SAVEPOINT); DEFAULT_ORACLE_KEYWORDS = new Keywords(map); } @@ -217,7 +219,6 @@ public class OracleLexer extends Lexer { np = bp; sp = 0; scanChar(); - sp++; // /*+ */ if (ch == '*') { @@ -277,7 +278,7 @@ public class OracleLexer extends Lexer { break; } - if (ch == '\r') { + if (ch == '\n') { scanChar(); sp++; break; 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 13bcfd8ad1..5b459fb69e 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 @@ -18,14 +18,18 @@ package com.alibaba.druid.sql.dialect.oracle.parser; import java.util.ArrayList; import java.util.List; +import com.alibaba.druid.sql.ast.SQLDataTypeImpl; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator; import com.alibaba.druid.sql.ast.expr.SQLCharExpr; +import com.alibaba.druid.sql.ast.expr.SQLNullExpr; +import com.alibaba.druid.sql.ast.expr.SQLQueryExpr; import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition; import com.alibaba.druid.sql.ast.statement.SQLConstaint; +import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement; import com.alibaba.druid.sql.ast.statement.SQLInsertInto; import com.alibaba.druid.sql.ast.statement.SQLSelect; import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem; @@ -61,12 +65,14 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterViewStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleBlockStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCommitStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateIndexStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateProcedureStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateSequenceStatement; 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.OracleExitStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExplainStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExprStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleFetchStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleFileSpecification; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleForStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleGotoStatement; @@ -80,6 +86,8 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLoopStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement; 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.OracleRollbackStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSavePointStatement; 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.dialect.oracle.ast.stmt.OracleTruncateStatement; @@ -240,7 +248,7 @@ public class OracleStatementParser extends SQLStatementParser { statementList.add(this.parseException()); continue; } - + if (identifierEquals("EXIT")) { lexer.nextToken(); OracleExitStatement stmt = new OracleExitStatement(); @@ -252,6 +260,24 @@ public class OracleStatementParser extends SQLStatementParser { continue; } + if (identifierEquals("FETCH")) { + lexer.nextToken(); + OracleFetchStatement stmt = new OracleFetchStatement(); + stmt.setCursorName(this.exprParser.name()); + accept(Token.INTO); + for (;;) { + stmt.getInto().add(this.exprParser.name()); + if (lexer.token() == Token.COMMA) { + lexer.nextToken(); + continue; + } + + break; + } + statementList.add(stmt); + continue; + } + if (lexer.token() == Token.IDENTIFIER) { if (identifierEquals("EXPLAIN")) { statementList.add(this.parseExplain()); @@ -319,6 +345,62 @@ public class OracleStatementParser extends SQLStatementParser { lexer.nextToken(); } OracleCommitStatement stmt = new OracleCommitStatement(); + + if (identifierEquals("WRITE")) { + stmt.setWrite(true); + lexer.nextToken(); + + for (;;) { + if (lexer.token() == Token.WAIT) { + lexer.nextToken(); + stmt.setWait(Boolean.TRUE); + continue; + } else if (lexer.token() == Token.NOWAIT) { + lexer.nextToken(); + stmt.setWait(Boolean.FALSE); + continue; + } else if (identifierEquals("IMMEDIATE")) { + lexer.nextToken(); + stmt.setImmediate(Boolean.TRUE); + continue; + } else if (identifierEquals("BATCH")) { + lexer.nextToken(); + stmt.setImmediate(Boolean.FALSE); + continue; + } + + break; + } + } + + statementList.add(stmt); + continue; + } + + if (lexer.token() == Token.ROLLBACK) { + lexer.nextToken(); + + OracleRollbackStatement stmt = new OracleRollbackStatement(); + + if (lexer.token() == Token.TO) { + lexer.nextToken(); + stmt.setTo(this.exprParser.name()); + } + + statementList.add(stmt); + continue; + } + + if (lexer.token() == Token.SAVEPOINT) { + lexer.nextToken(); + + OracleSavePointStatement stmt = new OracleSavePointStatement(); + + if (lexer.token() == Token.TO) { + lexer.nextToken(); + stmt.setTo(this.exprParser.name()); + } + statementList.add(stmt); continue; } @@ -331,7 +413,26 @@ public class OracleStatementParser extends SQLStatementParser { statementList.add(stmt); continue; } - + + if (lexer.token() == Token.DROP) { + lexer.nextToken(); + + if (lexer.token() == Token.TABLE) { + SQLDropTableStatement stmt = parseDropTable(false); + statementList.add(stmt); + continue; + } + + throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + } + + if (lexer.token() == Token.NULL) { + lexer.nextToken(); + OracleExprStatement stmt = new OracleExprStatement(new SQLNullExpr()); + statementList.add(stmt); + continue; + } + throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); } } @@ -390,12 +491,12 @@ public class OracleStatementParser extends SQLStatementParser { accept(Token.LOOP); return stmt; } - + public OracleLoopStatement parseLoop() { accept(Token.LOOP); - + OracleLoopStatement stmt = new OracleLoopStatement(); - + this.parseStatementList(stmt.getStatements()); accept(Token.END); accept(Token.LOOP); @@ -457,17 +558,17 @@ public class OracleStatementParser extends SQLStatementParser { public SQLStatement parseSet() { accept(Token.SET); acceptIdentifier("TRANSACTION"); - + OracleSetTransactionStatement stmt = new OracleSetTransactionStatement(); - + if (identifierEquals("READ")) { lexer.nextToken(); acceptIdentifier("ONLY"); stmt.setReadOnly(true); } - + acceptIdentifier("NAME"); - + stmt.setName(this.exprParser.expr()); return stmt; } @@ -479,10 +580,10 @@ public class OracleStatementParser extends SQLStatementParser { SQLName name = this.exprParser.name(); stmt.getTableNames().add(name); - + if (identifierEquals("PURGE")) { lexer.nextToken(); - + if (identifierEquals("SNAPSHOT")) { lexer.nextToken(); accept(Token.LOG); @@ -952,30 +1053,15 @@ public class OracleStatementParser extends SQLStatementParser { return stmt; } - public OracleStatement parseBlock() { + public OracleBlockStatement parseBlock() { OracleBlockStatement block = new OracleBlockStatement(); if (lexer.token() == Token.DECLARE) { lexer.nextToken(); - for (;;) { - OracleParameter parameter = new OracleParameter(); - parameter.setName(this.exprParser.name()); - parameter.setDataType(this.exprParser.parseDataType()); - - block.getParameters().add(parameter); - - if (lexer.token() == Token.COLONEQ) { - lexer.nextToken(); - parameter.setDefaultValue(this.exprParser.expr()); - } - parameter.setParent(block); - accept(Token.SEMI); - if (lexer.token() != Token.BEGIN) { - continue; - } - - break; + parserParameters(block.getParameters()); + for (OracleParameter param : block.getParameters()) { + param.setParent(block); } } @@ -988,6 +1074,46 @@ public class OracleStatementParser extends SQLStatementParser { return block; } + private void parserParameters(List parameters) { + for (;;) { + OracleParameter parameter = new OracleParameter(); + + if (lexer.token() == Token.CURSOR) { + lexer.nextToken(); + + parameter.setName(this.exprParser.name()); + + accept(Token.IS); + SQLSelect select = this.createSQLSelectParser().select(); + + SQLDataTypeImpl dataType = new SQLDataTypeImpl(); + dataType.setName("CURSOR"); + parameter.setDataType(dataType); + + parameter.setDefaultValue(new SQLQueryExpr(select)); + } else { + parameter.setName(this.exprParser.name()); + parameter.setDataType(this.exprParser.parseDataType()); + + if (lexer.token() == Token.COLONEQ) { + lexer.nextToken(); + parameter.setDefaultValue(this.exprParser.expr()); + } + } + + parameters.add(parameter); + if (lexer.token() == Token.COMMA || lexer.token() == Token.SEMI) { + lexer.nextToken(); + } + + if (lexer.token() != Token.BEGIN && lexer.token() != Token.RPAREN) { + continue; + } + + break; + } + } + public OracleSelectParser createSQLSelectParser() { return new OracleSelectParser(this.lexer); } @@ -1187,9 +1313,7 @@ public class OracleStatementParser extends SQLStatementParser { 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)); + parseStatementList(item.getStatements()); stmt.getItems().add(item); @@ -1404,12 +1528,12 @@ public class OracleStatementParser extends SQLStatementParser { if (acceptCreate) { accept(Token.CREATE); } - + acceptIdentifier("SEQUENCE"); OracleCreateSequenceStatement stmt = new OracleCreateSequenceStatement(); stmt.setName(this.exprParser.name()); - + for (;;) { if (lexer.token() == Token.START) { lexer.nextToken(); @@ -1437,10 +1561,38 @@ public class OracleStatementParser extends SQLStatementParser { lexer.nextToken(); stmt.setCycle(Boolean.FALSE); continue; - } + } break; } return stmt; } + + public OracleCreateProcedureStatement parseCreateProcedure() { + OracleCreateProcedureStatement stmt = new OracleCreateProcedureStatement(); + accept(Token.CREATE); + if (lexer.token() == Token.OR) { + lexer.nextToken(); + acceptIdentifier("REPLACE"); + stmt.setOrReplace(true); + } + + accept(Token.PROCEDURE); + + stmt.setName(this.exprParser.name()); + + if (lexer.token() == Token.LPAREN) { + lexer.nextToken(); + parserParameters(stmt.getParameters()); + accept(Token.RPAREN); + } + + accept(Token.AS); + + OracleBlockStatement block = this.parseBlock(); + + stmt.setBlock(block); + + return stmt; + } } 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 61c86d5b7f..7084e6c39c 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 @@ -67,6 +67,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleBlockStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCommitStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleConstraintState; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateIndexStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateProcedureStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateSequenceStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateTableStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement; @@ -74,6 +75,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExceptionStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExitStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExplainStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExprStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleFetchStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleFileSpecification; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleForStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleGotoStatement; @@ -95,6 +97,8 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement. import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleOrderByItem; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OraclePLSQLCommitStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OraclePrimaryKey; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleRollbackStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSavePointStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelect; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectForUpdate; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectHierachicalQueryClause; @@ -1257,55 +1261,55 @@ public class OracleASTVIsitorAdapter extends SQLASTVisitorAdapter implements Ora public void endVisit(OracleAlterTableMoveTablespace x) { } - + @Override public boolean visit(OracleSizeExpr x) { return true; } - + @Override public void endVisit(OracleSizeExpr x) { - + } - + @Override public boolean visit(OracleFileSpecification x) { return true; } - + @Override public void endVisit(OracleFileSpecification x) { - + } - + @Override public boolean visit(OracleAlterTablespaceAddDataFile x) { return true; } - + @Override public void endVisit(OracleAlterTablespaceAddDataFile x) { - + } - + @Override public boolean visit(OracleAlterTablespaceStatement x) { return true; } - + @Override public void endVisit(OracleAlterTablespaceStatement x) { - + } - + @Override public boolean visit(OracleTruncateStatement x) { return true; } - + @Override public void endVisit(OracleTruncateStatement x) { - + } @Override @@ -1315,17 +1319,17 @@ public class OracleASTVIsitorAdapter extends SQLASTVisitorAdapter implements Ora @Override public void endVisit(OracleCreateSequenceStatement x) { - + } - + @Override public boolean visit(OracleRangeValuesClause x) { return true; } - + @Override public void endVisit(OracleRangeValuesClause x) { - + } @Override @@ -1335,16 +1339,17 @@ public class OracleASTVIsitorAdapter extends SQLASTVisitorAdapter implements Ora @Override public void endVisit(OraclePartitionByRangeClause x) { - + } + @Override public boolean visit(OracleLoopStatement x) { return true; } - + @Override public void endVisit(OracleLoopStatement x) { - + } @Override @@ -1354,6 +1359,46 @@ public class OracleASTVIsitorAdapter extends SQLASTVisitorAdapter implements Ora @Override public void endVisit(OracleExitStatement x) { + + } + + @Override + public boolean visit(OracleFetchStatement x) { + return true; + } + + @Override + public void endVisit(OracleFetchStatement x) { + + } + + @Override + public boolean visit(OracleRollbackStatement x) { + return true; + } + + @Override + public void endVisit(OracleRollbackStatement x) { + + } + + @Override + public boolean visit(OracleSavePointStatement x) { + return true; + } + + @Override + public void endVisit(OracleSavePointStatement x) { + + } + + @Override + public boolean visit(OracleCreateProcedureStatement x) { + return true; + } + + @Override + public void endVisit(OracleCreateProcedureStatement 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 1e214e6b6f..b598db1d27 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 @@ -73,6 +73,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleBlockStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCommitStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleConstraintState; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateIndexStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateProcedureStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateSequenceStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateTableStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement; @@ -80,6 +81,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExceptionStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExitStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExplainStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExprStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleFetchStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleFileSpecification; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleForStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleGotoStatement; @@ -99,6 +101,8 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement. import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleOrderByItem; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OraclePLSQLCommitStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OraclePrimaryKey; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleRollbackStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSavePointStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelect; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectForUpdate; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectHierachicalQueryClause; @@ -600,4 +604,20 @@ public interface OracleASTVisitor extends SQLASTVisitor { boolean visit(OracleExitStatement x); void endVisit(OracleExitStatement x); + + boolean visit(OracleFetchStatement x); + + void endVisit(OracleFetchStatement x); + + boolean visit(OracleRollbackStatement x); + + void endVisit(OracleRollbackStatement x); + + boolean visit(OracleSavePointStatement x); + + void endVisit(OracleSavePointStatement x); + + boolean visit(OracleCreateProcedureStatement x); + + void endVisit(OracleCreateProcedureStatement 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 54db2df90d..eae1dd8e75 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 @@ -28,6 +28,7 @@ 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; +import com.alibaba.druid.sql.ast.expr.SQLQueryExpr; import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; @@ -107,6 +108,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleBlockStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCommitStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleConstraintState; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateIndexStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateProcedureStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateSequenceStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateTableStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement; @@ -114,6 +116,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExceptionStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExitStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExplainStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExprStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleFetchStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleFileSpecification; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleForStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleGotoStatement; @@ -135,6 +138,8 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement. import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleOrderByItem; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OraclePLSQLCommitStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OraclePrimaryKey; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleRollbackStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSavePointStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelect; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectForUpdate; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectHierachicalQueryClause; @@ -169,6 +174,9 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS if (x instanceof OraclePLSQLCommitStatement) { return; } + if (x.getParent() instanceof OracleCreateProcedureStatement) { + return; + } if (x.getParent() != null) { print(";"); @@ -357,6 +365,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS public boolean visit(OraclePLSQLCommitStatement astNode) { print("/"); + println(); return false; } @@ -446,13 +455,13 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS if (isRoot) { incrementIndent(); } - + println(); print(JoinType.toString(x.getJoinType())); print(" "); x.getRight().accept(this); - + if (isRoot) { decrementIndent(); } @@ -1749,12 +1758,17 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS incrementIndent(); println(); - for (OracleParameter param : x.getParameters()) { + for (int i = 0, size = x.getParameters().size(); i < size; ++i) { + if (i != 0) { + println(); + } + OracleParameter param = x.getParameters().get(i); param.accept(this); - println(); + print(";"); } decrementIndent(); + println(); } print("BEGIN"); incrementIndent(); @@ -1870,8 +1884,13 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS print("WHEN "); x.getWhen().accept(this); incrementIndent(); - println(); - x.getStatement().accept(this); + + for (int i = 0, size = x.getStatements().size(); i < size; ++i) { + println(); + SQLStatement stmt = x.getStatements().get(i); + stmt.setParent(x); + stmt.accept(this); + } decrementIndent(); return false; } @@ -2576,14 +2595,28 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS @Override public boolean visit(OracleParameter x) { - x.getName().accept(this); - print(" "); - x.getDataType().accept(this); + if (x.getDataType().getName().equalsIgnoreCase("CURSOR")) { + print("CURSOR "); + x.getName().accept(this); + print(" IS"); + incrementIndent(); + println(); + SQLSelect select = ((SQLQueryExpr) x.getDefaultValue()).getSubQuery(); + select.accept(this); + decrementIndent(); - if (x.getDefaultValue() != null) { - print(" := "); - x.getDefaultValue().accept(this); + } else { + x.getName().accept(this); + print(" "); + + x.getDataType().accept(this); + + if (x.getDefaultValue() != null) { + print(" := "); + x.getDefaultValue().accept(this); + } } + return false; } @@ -2595,6 +2628,26 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS @Override public boolean visit(OracleCommitStatement x) { print("COMMIT"); + + if (x.isWrite()) { + print(" WRITE"); + if (x.getWait() != null) { + if (x.getWait().booleanValue()) { + print(" WAIT"); + } else { + print(" NOWAIT"); + } + } + + if (x.getImmediate() != null) { + if (x.getImmediate().booleanValue()) { + print(" IMMEDIATE"); + } else { + print(" BATCH"); + } + } + } + return false; } @@ -2919,4 +2972,89 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS public void endVisit(OracleExitStatement x) { } + + @Override + public boolean visit(OracleFetchStatement x) { + print("FETCH "); + x.getCursorName().accept(this); + print(" INTO "); + printAndAccept(x.getInto(), ", "); + return false; + } + + @Override + public void endVisit(OracleFetchStatement x) { + + } + + @Override + public boolean visit(OracleRollbackStatement x) { + print("ROLLBACK"); + if (x.getTo() != null) { + print(" TO "); + x.getTo().accept(this); + } + return false; + } + + @Override + public void endVisit(OracleRollbackStatement x) { + + } + + @Override + public boolean visit(OracleSavePointStatement x) { + print("ROLLBACK"); + if (x.getTo() != null) { + print(" TO "); + x.getTo().accept(this); + } + return false; + } + + @Override + public void endVisit(OracleSavePointStatement x) { + + } + + @Override + public boolean visit(OracleCreateProcedureStatement x) { + if (x.isOrReplace()) { + print("CREATE OR REPLACE PROCEDURE "); + } else { + print("CREATE PROCEDURE "); + } + x.getName().accept(this); + + int paramSize = x.getParameters().size(); + + if (paramSize > 0) { + print(" ("); + incrementIndent(); + println(); + + for (int i = 0; i < paramSize; ++i) { + if (i != 0) { + print(", "); + println(); + } + OracleParameter param = x.getParameters().get(i); + param.accept(this); + } + + decrementIndent(); + println(); + print(")"); + } + + println(); + x.getBlock().setParent(x); + x.getBlock().accept(this); + return false; + } + + @Override + public void endVisit(OracleCreateProcedureStatement 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 08a52ff7aa..7f98ef2ced 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 @@ -41,10 +41,10 @@ import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleParameter; import com.alibaba.druid.sql.dialect.oracle.ast.clause.OraclePartitionByRangeClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleRangeValuesClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleReturningClause; +import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleStorageClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.PartitionExtensionClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.SampleClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.SearchClause; -import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleStorageClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.SubqueryFactoringClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.SubqueryFactoringClause.Entry; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAggregateExpr; @@ -86,6 +86,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleBlockStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCommitStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleConstraintState; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateIndexStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateProcedureStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateSequenceStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateTableStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement; @@ -93,6 +94,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExceptionStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExitStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExplainStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExprStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleFetchStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleFileSpecification; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleForStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleGotoStatement; @@ -114,6 +116,8 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement. import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleOrderByItem; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OraclePLSQLCommitStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OraclePrimaryKey; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleRollbackStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSavePointStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelect; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectForUpdate; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectHierachicalQueryClause; @@ -143,7 +147,8 @@ import com.alibaba.druid.stat.TableStat.Relationship; public class OracleSchemaStatVisitor extends SchemaStatVisitor implements OracleASTVisitor { public OracleSchemaStatVisitor(){ - this.aliasMap.put("DUAL", null); + this.variants.put("DUAL", null); + this.variants.put("NOTFOUND", null); } protected Column getColumn(SQLExpr expr) { @@ -317,15 +322,16 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle x.getWhere().setParent(x); } - visit((SQLSelectQueryBlock) x); - if (x.getInto() instanceof SQLName) { - TableStat stat = getTableStat(x.getInto().toString()); + String tableName = x.getInto().toString(); + TableStat stat = getTableStat(tableName); if (stat != null) { stat.incrementInsertCount(); } } + visit((SQLSelectQueryBlock) x); + return true; } @@ -1610,7 +1616,7 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle @Override public boolean visit(OracleParameter x) { - return false; + return true; } @Override @@ -1755,7 +1761,7 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle @Override public void endVisit(OraclePartitionByRangeClause x) { - + } @Override @@ -1765,7 +1771,7 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle @Override public void endVisit(OracleLoopStatement x) { - + } @Override @@ -1775,6 +1781,49 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle @Override public void endVisit(OracleExitStatement x) { - + + } + + @Override + public boolean visit(OracleFetchStatement x) { + return true; + } + + @Override + public void endVisit(OracleFetchStatement x) { + + } + + @Override + public boolean visit(OracleRollbackStatement x) { + return false; + } + + @Override + public void endVisit(OracleRollbackStatement x) { + + } + + @Override + public boolean visit(OracleSavePointStatement x) { + return false; + } + + @Override + public void endVisit(OracleSavePointStatement x) { + + } + + @Override + public boolean visit(OracleCreateProcedureStatement x) { + String name = x.getName().toString(); + this.variants.put(name, x); + accept(x.getBlock()); + return false; + } + + @Override + public void endVisit(OracleCreateProcedureStatement x) { + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/PGCurrentOfExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/PGCurrentOfExpr.java deleted file mode 100644 index 0d1d484232..0000000000 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/PGCurrentOfExpr.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.alibaba.druid.sql.dialect.postgresql.ast; - -import com.alibaba.druid.sql.ast.SQLExpr; -import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitor; - -public class PGCurrentOfExpr extends PGSQLObjectImpl implements SQLExpr { - - private static final long serialVersionUID = 1L; - private SQLExpr cursor; - - public PGCurrentOfExpr() { - - } - - public PGCurrentOfExpr(SQLExpr cursor) { - this.cursor = cursor; - } - - public SQLExpr getCursor() { - return cursor; - } - - public void setCursor(SQLExpr cursor) { - this.cursor = cursor; - } - - @Override - public void accept0(PGASTVisitor visitor) { - if (visitor.visit(this)) { - acceptChild(visitor, cursor); - } - visitor.endVisit(this); - } - -} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSQLStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSQLStatementParser.java index 8c9e059d18..8f9eb1727c 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSQLStatementParser.java @@ -5,12 +5,12 @@ 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.SQLCurrentOfCursorExpr; import com.alibaba.druid.sql.ast.expr.SQLQueryExpr; import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; import com.alibaba.druid.sql.ast.statement.SQLTableSource; import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem; import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; -import com.alibaba.druid.sql.dialect.postgresql.ast.PGCurrentOfExpr; import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithClause; import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithQuery; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGDeleteStatement; @@ -169,7 +169,7 @@ public class PGSQLStatementParser extends SQLStatementParser { lexer.nextToken(); accept(Token.OF); SQLName cursorName = this.exprParser.name(); - SQLExpr where = new PGCurrentOfExpr(cursorName); + SQLExpr where = new SQLCurrentOfCursorExpr(cursorName); deleteStatement.setWhere(where); } else { SQLExpr where = this.exprParser.expr(); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGASTVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGASTVisitor.java index 4505a2b12e..f919fab3e3 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGASTVisitor.java @@ -1,6 +1,5 @@ package com.alibaba.druid.sql.dialect.postgresql.visitor; -import com.alibaba.druid.sql.dialect.postgresql.ast.PGCurrentOfExpr; import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithClause; import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithQuery; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGDeleteStatement; @@ -45,10 +44,6 @@ public interface PGASTVisitor extends SQLASTVisitor { boolean visit(PGDeleteStatement x); - void endVisit(PGCurrentOfExpr x); - - boolean visit(PGCurrentOfExpr x); - void endVisit(PGInsertStatement x); boolean visit(PGInsertStatement x); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGASTVisitorAdapter.java index 7f75acbe8d..e4cacce11e 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGASTVisitorAdapter.java @@ -1,6 +1,5 @@ package com.alibaba.druid.sql.dialect.postgresql.visitor; -import com.alibaba.druid.sql.dialect.postgresql.ast.PGCurrentOfExpr; import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithClause; import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithQuery; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGDeleteStatement; @@ -104,16 +103,6 @@ public class PGASTVisitorAdapter extends SQLASTVisitorAdapter implements PGASTVi return true; } - @Override - public void endVisit(PGCurrentOfExpr x) { - - } - - @Override - public boolean visit(PGCurrentOfExpr x) { - return true; - } - @Override public void endVisit(PGInsertStatement x) { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGOutputVisitor.java index 4822b339ed..3428f8f6e1 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGOutputVisitor.java @@ -3,7 +3,6 @@ package com.alibaba.druid.sql.dialect.postgresql.visitor; import com.alibaba.druid.sql.ast.SQLSetQuantifier; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; -import com.alibaba.druid.sql.dialect.postgresql.ast.PGCurrentOfExpr; import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithClause; import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithQuery; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGDeleteStatement; @@ -318,19 +317,6 @@ public class PGOutputVisitor extends SQLASTOutputVisitor implements PGASTVisitor return false; } - @Override - public void endVisit(PGCurrentOfExpr x) { - - } - - @Override - public boolean visit(PGCurrentOfExpr x) { - print("CURRENT OF "); - x.getCursor().accept(this); - - return false; - } - @Override public void endVisit(PGInsertStatement x) { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGSchemaStatVisitor.java index 5bf9b5e853..22aacdff67 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGSchemaStatVisitor.java @@ -6,7 +6,6 @@ import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement; -import com.alibaba.druid.sql.dialect.postgresql.ast.PGCurrentOfExpr; import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithClause; import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithQuery; import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGDeleteStatement; @@ -152,16 +151,6 @@ public class PGSchemaStatVisitor extends SchemaStatVisitor implements PGASTVisit return false; } - @Override - public void endVisit(PGCurrentOfExpr x) { - - } - - @Override - public boolean visit(PGCurrentOfExpr x) { - return false; - } - @Override public void endVisit(PGInsertStatement x) { @@ -225,7 +214,7 @@ public class PGSchemaStatVisitor extends SchemaStatVisitor implements PGASTVisit @Override public boolean visit(PGUpdateStatement x) { Map oldAliasMap = getAliasMap(); - + setAliasMap(); if (x.getWith() != null) { @@ -243,7 +232,7 @@ public class PGSchemaStatVisitor extends SchemaStatVisitor implements PGASTVisit accept(x.getItems()); accept(x.getWhere()); - + setAliasMap(oldAliasMap); return false; 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 63fcae2f38..3af57c7386 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Lexer.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Lexer.java @@ -582,7 +582,6 @@ public class Lexer { np = bp; sp = 0; scanChar(); - sp++; if (ch == '*') { scanChar(); @@ -620,7 +619,7 @@ public class Lexer { break; } - if (ch == '\r') { + if (ch == '\n') { scanChar(); sp++; break; 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 ca5f6b1756..60c1009173 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -34,6 +34,7 @@ import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator; import com.alibaba.druid.sql.ast.expr.SQLCaseExpr; import com.alibaba.druid.sql.ast.expr.SQLCastExpr; import com.alibaba.druid.sql.ast.expr.SQLCharExpr; +import com.alibaba.druid.sql.ast.expr.SQLCurrentOfCursorExpr; import com.alibaba.druid.sql.ast.expr.SQLDefaultExpr; import com.alibaba.druid.sql.ast.expr.SQLExistsExpr; import com.alibaba.druid.sql.ast.expr.SQLHexExpr; @@ -449,9 +450,20 @@ public class SQLExprParser extends SQLParser { throw new IllegalArgumentException("expr"); } + if (lexer.token() == Token.OF) { + if (expr instanceof SQLIdentifierExpr) { + String name = ((SQLIdentifierExpr) expr).getName(); + if ("CURRENT".equalsIgnoreCase(name)) { + lexer.nextToken(); + SQLName cursorName = this.name(); + return new SQLCurrentOfCursorExpr(cursorName); + } + } + } + if (lexer.token() == Token.DOT) { lexer.nextToken(); - + expr = dotRest(expr); return primaryRest(expr); } else if (lexer.token() == Token.COLONEQ) { @@ -1035,21 +1047,25 @@ public class SQLExprParser extends SQLParser { } public SQLDataType parseDataType() throws ParserException { - + if (lexer.token() == Token.DEFAULT || lexer.token() == Token.NOT || lexer.token() == Token.NULL) { return null; } - + SQLName typeExpr = name(); String typeName = typeExpr.toString(); SQLDataType dataType = new SQLDataTypeImpl(typeName); + parseDataTypeRest(dataType); + return dataType; + } + + protected void parseDataTypeRest(SQLDataType dataType) { if (lexer.token() == Token.LPAREN) { lexer.nextToken(); exprList(dataType.getArguments()); accept(Token.RPAREN); } - return dataType; } protected SQLDataType parseCharType() throws ParserException { @@ -1108,7 +1124,7 @@ public class SQLExprParser extends SQLParser { throw new SQLParseException("syntax error, expect " + token + ", actual " + lexer.token()); } } - + public SQLColumnDefinition parseColumn() { SQLColumnDefinition column = new SQLColumnDefinition(); column.setName(name()); @@ -1116,7 +1132,7 @@ public class SQLExprParser extends SQLParser { return parseColumnRest(column); } - + public SQLColumnDefinition parseColumnRest(SQLColumnDefinition column) { if (lexer.token() == Token.DEFAULT) { lexer.nextToken(); @@ -1133,7 +1149,7 @@ public class SQLExprParser extends SQLParser { return column; } - + public SQLPrimaryKey parsePrimaryKey() { throw new ParserException("TODO"); } 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 da3805881d..e56f0e69b2 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java @@ -114,19 +114,8 @@ public class SQLStatementParser extends SQLParser { lexer.nextToken(); if (lexer.token() == Token.TABLE) { - lexer.nextToken(); - SQLDropTableStatement stmt = new SQLDropTableStatement(); - - for (;;) { - SQLName name = this.exprParser.name(); - stmt.getTableNames().add(name); - if (lexer.token() == Token.COMMA) { - lexer.nextToken(); - continue; - } - break; - } + SQLDropTableStatement stmt = parseDropTable(false); statementList.add(stmt); continue; @@ -159,11 +148,31 @@ public class SQLStatementParser extends SQLParser { } } + protected SQLDropTableStatement parseDropTable(boolean acceptDrop) { + if (acceptDrop) { + accept(Token.DROP); + } + accept(Token.TABLE); + + SQLDropTableStatement stmt = new SQLDropTableStatement(); + + for (;;) { + SQLName name = this.exprParser.name(); + stmt.getTableNames().add(name); + if (lexer.token() == Token.COMMA) { + lexer.nextToken(); + continue; + } + break; + } + return stmt; + } + public SQLStatement parseTruncate() { accept(Token.TRUNCATE); accept(Token.TABLE); SQLTruncateStatement stmt = new SQLTruncateStatement(); - + for (;;) { SQLName name = this.exprParser.name(); stmt.getTableNames().add(name); @@ -187,27 +196,27 @@ public class SQLStatementParser extends SQLParser { parseInsert0(insertStatement); return insertStatement; } - + protected void parseInsert0(SQLInsertInto insertStatement) { parseInsert0(insertStatement, true); } protected void parseInsert0_hinits(SQLInsertInto insertStatement) { - + } - + protected void parseInsert0(SQLInsertInto insertStatement, boolean acceptSubQuery) { accept(Token.INTO); - + SQLName tableName = this.exprParser.name(); insertStatement.setTableName(tableName); - + if (lexer.token() == Token.LITERAL_ALIAS) { insertStatement.setAlias(as()); } - + parseInsert0_hinits(insertStatement); - + if (lexer.token() == Token.IDENTIFIER) { insertStatement.setAlias(lexer.stringVal()); lexer.nextToken(); @@ -283,6 +292,9 @@ public class SQLStatementParser extends SQLParser { } public SQLStatement parseCreate() throws ParserException { + char mark_ch = lexer.current(); + int mark_bp = lexer.bp(); + accept(Token.CREATE); Token token = lexer.token(); @@ -294,15 +306,29 @@ public class SQLStatementParser extends SQLParser { return parseCreateIndex(false); } else if (identifierEquals("SEQUENCE")) { return parseCreateSequence(false); + } else if (token == Token.OR) { + lexer.nextToken(); + acceptIdentifier("REPLACE"); + if (lexer.token() == Token.PROCEDURE) { + lexer.reset(mark_bp, mark_ch, Token.CREATE); + return parseCreateProcedure(); + } + + //lexer.reset(mark_bp, mark_ch, Token.CREATE); + throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); } throw new ParserException("TODO " + lexer.token()); } + public SQLStatement parseCreateProcedure() { + throw new ParserException("TODO " + lexer.token()); + } + public SQLStatement parseCreateSequence(boolean acceptCreate) { throw new ParserException("TODO " + lexer.token()); } - + public SQLStatement parseCreateIndex(boolean acceptCreate) { throw new ParserException("TODO " + lexer.token()); } @@ -403,9 +429,9 @@ public class SQLStatementParser extends SQLParser { 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(); @@ -413,12 +439,12 @@ public class SQLStatementParser extends SQLParser { 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 a5737ca03f..b893f250dd 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Token.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Token.java @@ -172,6 +172,8 @@ public enum Token { LOOP("LOOP"), GOTO("GOTO"), COMMIT("COMMIT"), + ROLLBACK("ROLLBACK"), + SAVEPOINT("SAVEPOINT"), // 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 737a71a5c8..94ec3bddab 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -985,4 +985,5 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter { 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 ca8c26fc54..c862bacfc0 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java @@ -318,16 +318,17 @@ public interface SQLASTVisitor { void endVisit(SQLSubqueryTableSource x); boolean visit(SQLSubqueryTableSource x); - + void endVisit(SQLTruncateStatement x); - + boolean visit(SQLTruncateStatement x); - + 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 abbe060875..259087554f 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java @@ -50,8 +50,8 @@ 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; @@ -543,22 +543,22 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor { public boolean visit(SQLSubqueryTableSource x) { return true; } - + @Override public void endVisit(SQLTruncateStatement x) { - + } - + @Override public boolean visit(SQLTruncateStatement x) { return true; } - + @Override public void endVisit(SQLDefaultExpr x) { - + } - + @Override public boolean visit(SQLDefaultExpr x) { return true; @@ -566,11 +566,12 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor { @Override public void endVisit(SQLCommentStatement x) { - + } @Override public boolean visit(SQLCommentStatement x) { return true; } + } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest10.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest10.java new file mode 100644 index 0000000000..15bbf67a8f --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest10.java @@ -0,0 +1,54 @@ +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 OracleBlockTest10 extends OracleTest { + + public void test_0() throws Exception { + String sql = "DECLARE" + // + " CURSOR c1 IS" + // + " SELECT last_name, department_name" + // + " FROM employees, departments" + // + " WHERE employees.department_id = departments.department_id " + // + " AND job_id = 'SA_MAN'" + // + " FOR UPDATE OF salary;" + // + "BEGIN" + // + " NULL;" + // + "END;"; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + for (SQLStatement statement : statementList) { + statement.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("employees"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("departments"))); + + Assert.assertEquals(5, visitor.getColumns().size()); + Assert.assertEquals(3, visitor.getConditions().size()); + +// Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "salary"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest11.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest11.java new file mode 100644 index 0000000000..93f93694fe --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest11.java @@ -0,0 +1,70 @@ +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 OracleBlockTest11 extends OracleTest { + + public void test_0() throws Exception { + String sql = "DROP TABLE emp;" + + "CREATE TABLE emp AS SELECT * FROM employees;" + + " " + + "DECLARE" + + " CURSOR c1 IS" + + " SELECT * FROM emp" + + " FOR UPDATE OF salary" + + " ORDER BY employee_id;" + + " emp_rec emp%ROWTYPE;" + + "BEGIN" + + " OPEN c1;" + + " LOOP" + + " FETCH c1 INTO emp_rec; -- fails on second iteration\n" + + " EXIT WHEN c1%NOTFOUND;" + + " DBMS_OUTPUT.PUT_LINE (" + + " 'emp_rec.employee_id = ' ||" + + " TO_CHAR(emp_rec.employee_id)" + + " );" + + " " + + " UPDATE emp" + + " SET salary = salary * 1.05" + + " WHERE employee_id = 105;" + + " " + + " COMMIT; -- releases locks\n" + + " END LOOP;" + + "END;"; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + print(statementList); + + Assert.assertEquals(3, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + for (SQLStatement statement : statementList) { + statement.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("employees"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("emp"))); + + Assert.assertEquals(4, visitor.getColumns().size()); + Assert.assertEquals(1, visitor.getConditions().size()); + +// Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "salary"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest12.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest12.java new file mode 100644 index 0000000000..6cc0b22189 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest12.java @@ -0,0 +1,70 @@ +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 OracleBlockTest12 extends OracleTest { + + public void test_0() throws Exception { + String sql = "DECLARE" + + " emp_id NUMBER(6);" + + " emp_lastname VARCHAR2(25);" + + " emp_salary NUMBER(8,2);" + + " emp_jobid VARCHAR2(10);" + + "BEGIN" + + " SELECT employee_id, last_name, salary, job_id" + + " INTO emp_id, emp_lastname, emp_salary, emp_jobid" + + " FROM employees" + + " WHERE employee_id = 120;" + + "" + + " INSERT INTO emp_name (employee_id, last_name)" + + " VALUES (emp_id, emp_lastname); " + + " INSERT INTO emp_sal (employee_id, salary) " + + " VALUES (emp_id, emp_salary);" + + "" + + " INSERT INTO emp_job (employee_id, job_id)" + + " VALUES (emp_id, emp_jobid);" + + " " + + "EXCEPTION" + + " WHEN DUP_VAL_ON_INDEX THEN" + + " ROLLBACK;" + + " DBMS_OUTPUT.PUT_LINE('Inserts were rolled back');" + + "END;"; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + for (SQLStatement statement : statementList) { + statement.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(4, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("emp_name"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("emp_sal"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("emp_job"))); + + Assert.assertEquals(11, visitor.getColumns().size()); + Assert.assertEquals(1, visitor.getConditions().size()); + +// Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "salary"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest13.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest13.java new file mode 100644 index 0000000000..560f054ccc --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest13.java @@ -0,0 +1,73 @@ +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 OracleBlockTest13 extends OracleTest { + + public void test_0() throws Exception { + String sql = "DECLARE" + // + " emp_id employees.employee_id%TYPE;" + // + " emp_lastname employees.last_name%TYPE;" + // + " emp_salary employees.salary%TYPE;" + // + "" + // + "BEGIN" + // + " SELECT employee_id, last_name, salary" + // + " INTO emp_id, emp_lastname, emp_salary " + // + " FROM employees" + // + " WHERE employee_id = 120;" + // + " " + // + " UPDATE emp_name" + // + " SET salary = salary * 1.1" + // + " WHERE employee_id = emp_id;" + // + "" + // + " DELETE FROM emp_name" + // + " WHERE employee_id = 130;" + // + "" + // + " SAVEPOINT do_insert;" + // + " " + // + " INSERT INTO emp_name (employee_id, last_name, salary)" + // + " VALUES (emp_id, emp_lastname, emp_salary);" + // + " " + // + "EXCEPTION" + // + " WHEN DUP_VAL_ON_INDEX THEN" + // + " ROLLBACK TO do_insert;" + // + " DBMS_OUTPUT.PUT_LINE('Insert was rolled back');" + // + "END;"; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + for (SQLStatement statement : statementList) { + statement.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("employees"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("emp_name"))); + + Assert.assertEquals(7, visitor.getColumns().size()); + Assert.assertEquals(3, visitor.getConditions().size()); + Assert.assertEquals(1, visitor.getRelationships().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "salary"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest14.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest14.java new file mode 100644 index 0000000000..47933010d1 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest14.java @@ -0,0 +1,74 @@ +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 OracleBlockTest14 extends OracleTest { + + public void test_0() throws Exception { + String sql = "DECLARE" + // + " emp_id employees.employee_id%TYPE;" + // + " emp_lastname employees.last_name%TYPE;" + // + " emp_salary employees.salary%TYPE;" + // + "" + // + "BEGIN" + // + " SELECT employee_id, last_name, salary" + // + " INTO emp_id, emp_lastname, emp_salary" + // + " FROM employees" + // + " WHERE employee_id = 120;" + // + " SAVEPOINT my_savepoint;" + // + " " + // + " UPDATE emp_name" + // + " SET salary = salary * 1.1" + // + " WHERE employee_id = emp_id;" + // + " " + // + " DELETE FROM emp_name" + // + " WHERE employee_id = 130;" + // + " " + // + " SAVEPOINT my_savepoint;" + // + " " + // + " INSERT INTO emp_name (employee_id, last_name, salary)" + // + " VALUES (emp_id, emp_lastname, emp_salary);" + // + "" + // + "EXCEPTION" + // + " WHEN DUP_VAL_ON_INDEX THEN" + // + " ROLLBACK TO my_savepoint;" + // + " DBMS_OUTPUT.PUT_LINE('Transaction rolled back.');" + // + "END;"; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + for (SQLStatement statement : statementList) { + statement.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("employees"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("emp_name"))); + + Assert.assertEquals(7, visitor.getColumns().size()); + Assert.assertEquals(3, visitor.getConditions().size()); + Assert.assertEquals(1, visitor.getRelationships().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "salary"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest7.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest7.java new file mode 100644 index 0000000000..1f4bfd03a7 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest7.java @@ -0,0 +1,69 @@ +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 OracleBlockTest7 extends OracleTest { + + public void test_0() throws Exception { + String sql = "DROP TABLE employees_temp; " + // + "CREATE TABLE employees_temp AS " + // + " SELECT employee_id, first_name, last_name " + // + " FROM employees;" + // + " " + // + "DECLARE" + // + " emp_id employees_temp.employee_id%TYPE := 299;" + // + " emp_first_name employees_temp.first_name%TYPE := 'Bob';" + // + " emp_last_name employees_temp.last_name%TYPE := 'Henry';" + // + "BEGIN" + // + " INSERT INTO employees_temp (employee_id, first_name, last_name) " + // + " VALUES (emp_id, emp_first_name, emp_last_name);" + // + " " + // + " UPDATE employees_temp" + // + " SET first_name = 'Robert'" + // + " WHERE employee_id = emp_id;" + // + " " + // + " DELETE FROM employees_temp" + // + " WHERE employee_id = emp_id" + // + " RETURNING first_name, last_name" + // + " INTO emp_first_name, emp_last_name;" + // + "" + // + " COMMIT;" + // + " DBMS_OUTPUT.PUT_LINE (emp_first_name || ' ' || emp_last_name);" + // + "END;"; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + print(statementList); + + Assert.assertEquals(3, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + for (SQLStatement statement : statementList) { + statement.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("employees"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees_temp"))); + + Assert.assertEquals(6, visitor.getColumns().size()); + Assert.assertEquals(2, visitor.getConditions().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "employee_id"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest8.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest8.java new file mode 100644 index 0000000000..a32996773a --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest8.java @@ -0,0 +1,69 @@ +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 OracleBlockTest8 extends OracleTest { + + public void test_0() throws Exception { + String sql = "DECLARE" + // + " daily_order_total NUMBER(12,2);" + // + " weekly_order_total NUMBER(12,2); " + // + " monthly_order_total NUMBER(12,2);" + // + "BEGIN" + // + " COMMIT; -- end previous transaction\n" + // + " SET TRANSACTION READ ONLY NAME 'Calculate Order Totals';" + // + "" + // + " SELECT SUM (order_total)" + // + " INTO daily_order_total" + // + " FROM orders" + // + " WHERE order_date = SYSDATE;" + // + "" + // + " SELECT SUM (order_total)" + // + " INTO weekly_order_total" + // + " FROM orders" + // + " WHERE order_date = SYSDATE - 7;" + // + "" + // + " SELECT SUM (order_total)" + // + " INTO monthly_order_total" + // + " FROM orders" + // + " WHERE order_date = SYSDATE - 30;" + // + "" + // + " COMMIT; -- ends read-only transaction\n" + // + "END;"; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + for (SQLStatement statement : statementList) { + statement.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("orders"))); + + Assert.assertEquals(2, visitor.getColumns().size()); + Assert.assertEquals(1, visitor.getConditions().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("orders", "order_total"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("orders", "order_date"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest9.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest9.java new file mode 100644 index 0000000000..c2e3799821 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest9.java @@ -0,0 +1,64 @@ +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 OracleBlockTest9 extends OracleTest { + + public void test_0() throws Exception { + String sql = "DECLARE" + // + " my_emp_id NUMBER(6);" + // + " my_job_id VARCHAR2(10);" + // + " my_sal NUMBER(8,2);" + // + " CURSOR c1 IS" + // + " SELECT employee_id, job_id, salary" + // + " FROM employees FOR UPDATE;" + // + "BEGIN" + // + " OPEN c1;" + // + " LOOP" + // + " FETCH c1 INTO my_emp_id, my_job_id, my_sal;" + // + " IF my_job_id = 'SA_REP' THEN" + // + " UPDATE employees" + // + " SET salary = salary * 1.02" + // + " WHERE CURRENT OF c1;" + // + " END IF;" + // + " EXIT WHEN c1%NOTFOUND;" + // + " END LOOP;" + // + "END;"; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + for (SQLStatement statement : statementList) { + statement.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("employees"))); + + Assert.assertEquals(3, visitor.getColumns().size()); + Assert.assertEquals(0, visitor.getConditions().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "salary"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "employee_id"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "job_id"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateProcedureTest1.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateProcedureTest1.java new file mode 100644 index 0000000000..f68ecce78f --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateProcedureTest1.java @@ -0,0 +1,64 @@ +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 OracleCreateProcedureTest1 extends OracleTest { + + public void test_0() throws Exception { + String sql = "CREATE OR REPLACE PROCEDURE p (" + + " dept_no NUMBER" + + ") AS " + + "BEGIN" + + " DELETE FROM dept_temp" + + " WHERE department_id = dept_no;" + + " " + + " IF SQL%FOUND THEN" + + " DBMS_OUTPUT.PUT_LINE (" + + " 'Delete succeeded for department number ' || dept_no" + + " );" + + " ELSE" + + " DBMS_OUTPUT.PUT_LINE ('No department number ' || dept_no);" + + " END IF;" + + "END;" + + "/" + + "BEGIN" + + " p(270);" + + " p(400);" + + "END;"; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + print(statementList); + + Assert.assertEquals(3, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + for (SQLStatement statement : statementList) { + statement.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("dept_temp"))); + +// Assert.assertEquals(7, visitor.getColumns().size()); + Assert.assertEquals(2, visitor.getConditions().size()); + Assert.assertEquals(1, visitor.getRelationships().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "salary"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateProcedureTest2.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateProcedureTest2.java new file mode 100644 index 0000000000..ff0d301ceb --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateProcedureTest2.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 OracleCreateProcedureTest2 extends OracleTest { + + public void test_0() throws Exception { + String sql = "CREATE OR REPLACE PROCEDURE transfer (" + // + " from_acct NUMBER," + // + " to_acct NUMBER," + // + " amount NUMBER" + // + ") AS " + // + "BEGIN" + // + " UPDATE accounts" + // + " SET balance = balance - amount" + // + " WHERE account_id = from_acct;" + // + " " + // + " UPDATE accounts" + // + " SET balance = balance + amount" + // + " WHERE account_id = to_acct;" + // + " " + // + " COMMIT WRITE IMMEDIATE NOWAIT;" + // + "END;"; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + for (SQLStatement statement : statementList) { + statement.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("accounts"))); + + Assert.assertEquals(5, visitor.getColumns().size()); + Assert.assertEquals(3, visitor.getConditions().size()); + Assert.assertEquals(2, visitor.getRelationships().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "salary"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/visitor/OracleResourceTest.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/visitor/OracleResourceTest.java index 4fbee5e417..0f4b228a31 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/visitor/OracleResourceTest.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/visitor/OracleResourceTest.java @@ -19,9 +19,9 @@ public class OracleResourceTest extends OracleTest { public void test_0() throws Exception { // 13 -// exec_test("bvt/parser/oracle-17.txt"); - for (int i = 0; i <= 53; ++i) { - exec_test("bvt/parser/oracle-" + i + ".txt"); +// exec_test("bvt/parser/oracle-56.txt"); + for (int i = 0; i <= 56; ++i) { + exec_test("bvt/parser/oracle-" + i + ".txt"); } } @@ -39,16 +39,19 @@ public class OracleResourceTest extends OracleTest { OracleStatementParser parser = new OracleStatementParser(sql); List statementList = parser.parseStatementList(); - SQLStatement statemen = statementList.get(0); - Assert.assertEquals(1, statementList.size()); - + // Assert.assertEquals(1, statementList.size()); + System.out.println(sql); - + print(statementList); OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); - statemen.accept(visitor); + + for (int i = 0, size = statementList.size(); i < size; ++i) { + SQLStatement statement = statementList.get(i); + statement.accept(visitor); + } System.out.println("Tables : " + visitor.getTables()); System.out.println("fields : " + visitor.getColumns()); diff --git a/src/test/resources/bvt/parser/oracle-56.txt b/src/test/resources/bvt/parser/oracle-56.txt new file mode 100755 index 0000000000..797a3f873f --- /dev/null +++ b/src/test/resources/bvt/parser/oracle-56.txt @@ -0,0 +1,91 @@ +DROP TABLE employees_temp; +CREATE TABLE employees_temp AS + SELECT employee_id, first_name, last_name + FROM employees; + +DROP TABLE employees_temp2; +CREATE TABLE employees_temp2 AS + SELECT employee_id, first_name, last_name + FROM employees; + +DECLARE + seq_value NUMBER; +BEGIN + -- Generate initial sequence number + + seq_value := employees_seq.NEXTVAL; + + -- Print initial sequence number: + + DBMS_OUTPUT.PUT_LINE ( + 'Initial sequence value: ' || TO_CHAR(seq_value) + ); + + -- Use NEXTVAL to create unique number when inserting data: + + INSERT INTO employees_temp (employee_id, first_name, last_name) + VALUES (employees_seq.NEXTVAL, 'Lynette', 'Smith'); + + -- Use CURRVAL to store same value somewhere else: + + INSERT INTO employees_temp2 VALUES (employees_seq.CURRVAL, + 'Morgan', 'Smith'); + + /* Because NEXTVAL values might be referenced + by different users and applications, + and some NEXTVAL values might not be stored in database, + there might be gaps in sequence. */ + + -- Use CURRVAL to specify record to delete: + + seq_value := employees_seq.CURRVAL; + + DELETE FROM employees_temp2 + WHERE employee_id = seq_value; + + -- Udpate employee_id with NEXTVAL for specified record: + + UPDATE employees_temp + SET employee_id = employees_seq.NEXTVAL + WHERE first_name = 'Lynette' + AND last_name = 'Smith'; + + -- Display final value of CURRVAL: + + seq_value := employees_seq.CURRVAL; + + DBMS_OUTPUT.PUT_LINE ( + 'Ending sequence value: ' || TO_CHAR(seq_value) + ); +END; +--------------------------- +DROP TABLE employees_temp; +CREATE TABLE employees_temp + AS + SELECT employee_id, first_name, last_name + FROM employees; +DROP TABLE employees_temp2; +CREATE TABLE employees_temp2 + AS + SELECT employee_id, first_name, last_name + FROM employees; +DECLARE + seq_value NUMBER +BEGIN + seq_value := employees_seq.NEXTVAL; + DBMS_OUTPUT.PUT_LINE('Initial sequence value: ' || TO_CHAR(seq_value)); + INSERT INTO employees_temp + (employee_id, first_name, last_name) + VALUES (employees_seq.NEXTVAL, 'Lynette', 'Smith'); + INSERT INTO employees_temp2 + VALUES (employees_seq.CURRVAL, 'Morgan', 'Smith'); + seq_value := employees_seq.CURRVAL; + DELETE FROM employees_temp2 + WHERE employee_id = seq_value; + UPDATE employees_temp + SET employee_id = employees_seq.NEXTVAL + WHERE first_name = 'Lynette' + AND last_name = 'Smith'; + seq_value := employees_seq.CURRVAL; + DBMS_OUTPUT.PUT_LINE('Ending sequence value: ' || TO_CHAR(seq_value)); +END;