From e5574d7a7d4c9b12f1538c63e09dd4dc6f21e5dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=A9=E5=B0=91?= Date: Wed, 7 Mar 2012 14:31:34 +0800 Subject: [PATCH] bug fixed for sql parser --- .../sql/ast/statement/SQLDeleteStatement.java | 9 + .../clause/OraclePartitionByRangeClause.java | 65 ++++ .../ast/clause/OraclePartitioningClause.java | 8 + .../ast/clause/OracleRangeValuesClause.java | 43 +++ .../ast/clause/OracleStorageClause.java | 1 - .../stmt/OracleCreateSequenceStatement.java | 87 +++++ .../ast/stmt/OracleCreateTableStatement.java | 57 ++- .../ast/stmt/OracleDeleteStatement.java | 10 +- .../oracle/ast/stmt/OracleExitStatement.java | 27 ++ .../oracle/ast/stmt/OracleLoopStatement.java | 31 ++ .../parser/OracleCreateTableParser.java | 99 +++++ .../oracle/parser/OracleExprParser.java | 16 +- .../dialect/oracle/parser/OracleLexer.java | 4 + .../oracle/parser/OracleStatementParser.java | 74 +++- .../visitor/OracleASTVIsitorAdapter.java | 56 ++- .../oracle/visitor/OracleASTVisitor.java | 27 +- .../oracle/visitor/OracleOutputVisitor.java | 160 +++++++- .../visitor/OracleSchemaStatVisitor.java | 74 +++- .../druid/sql/parser/SQLExprParser.java | 1 - .../alibaba/druid/sql/parser/SQLParser.java | 2 +- .../druid/sql/parser/SQLStatementParser.java | 10 + .../druid/sql/visitor/SchemaStatVisitor.java | 47 ++- .../bvt/sql/oracle/OracleBlockTest5.java | 59 +++ .../bvt/sql/oracle/OracleBlockTest6.java | 69 ++++ .../sql/oracle/OracleCreateSequenceTest.java | 49 +++ .../sql/oracle/OracleCreateTableTest10.java | 47 +++ .../sql/oracle/OracleCreateTableTest11.java | 83 +++++ .../bvt/sql/oracle/OracleDeleteTest.java | 46 +++ .../bvt/sql/oracle/OracleExplainTest3.java | 45 +++ .../bvt/sql/oracle/OracleInsertTest8.java | 50 +++ .../bvt/sql/oracle/OracleInsertTest9.java | 48 +++ .../bvt/sql/oracle/OracleSelectTest32.java | 45 +++ .../bvt/sql/oracle/OracleSelectTest33.java | 47 +++ .../bvt/sql/oracle/OracleSelectTest34.java | 59 +++ .../com/alibaba/druid/sql/TestMigrate.java | 346 ++++++++++++++++++ .../com/alibaba/druid/sql/TestTransform.java | 20 +- 36 files changed, 1852 insertions(+), 69 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/OraclePartitionByRangeClause.java create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/OraclePartitioningClause.java create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/OracleRangeValuesClause.java create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateSequenceStatement.java create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleExitStatement.java create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleLoopStatement.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest5.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest6.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateSequenceTest.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest10.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest11.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleDeleteTest.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleExplainTest3.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleInsertTest8.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleInsertTest9.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest32.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest33.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest34.java create mode 100644 src/test/java/com/alibaba/druid/sql/TestMigrate.java diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLDeleteStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLDeleteStatement.java index b899e0fd44..13ad5b6ba6 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLDeleteStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLDeleteStatement.java @@ -25,6 +25,7 @@ public class SQLDeleteStatement extends SQLStatementImpl { private static final long serialVersionUID = 1L; protected SQLName tableName; protected SQLExpr where; + private String alias; public SQLDeleteStatement(){ @@ -46,6 +47,14 @@ public class SQLDeleteStatement extends SQLStatementImpl { this.where = where; } + public String getAlias() { + return this.alias; + } + + public void setAlias(String alias) { + this.alias = alias; + } + public void output(StringBuffer buf) { buf.append("DELETE FROM "); this.tableName.output(buf); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/OraclePartitionByRangeClause.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/OraclePartitionByRangeClause.java new file mode 100644 index 0000000000..2ac49f637b --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/OraclePartitionByRangeClause.java @@ -0,0 +1,65 @@ +package com.alibaba.druid.sql.dialect.oracle.ast.clause; + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLName; +import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; + +public class OraclePartitionByRangeClause extends OracleSQLObjectImpl implements OraclePartitioningClause { + + private static final long serialVersionUID = 1L; + + private List columns = new ArrayList(); + + private SQLExpr interval; + private List storeIn = new ArrayList(); + + private List ranges = new ArrayList(); + + @Override + public void accept0(OracleASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, columns); + acceptChild(visitor, interval); + acceptChild(visitor, storeIn); + acceptChild(visitor, ranges); + } + visitor.endVisit(this); + } + + public List getRanges() { + return ranges; + } + + public void setRanges(List ranges) { + this.ranges = ranges; + } + + public List getStoreIn() { + return storeIn; + } + + public void setStoreIn(List storeIn) { + this.storeIn = storeIn; + } + + public SQLExpr getInterval() { + return interval; + } + + public void setInterval(SQLExpr interval) { + this.interval = interval; + } + + public List getColumns() { + return columns; + } + + public void setColumns(List columns) { + this.columns = columns; + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/OraclePartitioningClause.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/OraclePartitioningClause.java new file mode 100644 index 0000000000..9b100b4f61 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/OraclePartitioningClause.java @@ -0,0 +1,8 @@ +package com.alibaba.druid.sql.dialect.oracle.ast.clause; + +import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObject; + + +public interface OraclePartitioningClause extends OracleSQLObject { + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/OracleRangeValuesClause.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/OracleRangeValuesClause.java new file mode 100644 index 0000000000..809fa61e38 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/OracleRangeValuesClause.java @@ -0,0 +1,43 @@ +package com.alibaba.druid.sql.dialect.oracle.ast.clause; + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLName; +import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; + +public class OracleRangeValuesClause extends OracleSQLObjectImpl { + + private static final long serialVersionUID = 1L; + + private SQLName name; + private List values = new ArrayList(); + + @Override + public void accept0(OracleASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, name); + acceptChild(visitor, values); + } + visitor.endVisit(this); + } + + public SQLName getName() { + return name; + } + + public void setName(SQLName name) { + this.name = name; + } + + public List getValues() { + return values; + } + + public void setValues(List values) { + this.values = values; + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/OracleStorageClause.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/OracleStorageClause.java index bd44953fde..4af2692947 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/OracleStorageClause.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/clause/OracleStorageClause.java @@ -1,7 +1,6 @@ package com.alibaba.druid.sql.dialect.oracle.ast.clause; import com.alibaba.druid.sql.ast.SQLExpr; -import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl; import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateSequenceStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateSequenceStatement.java new file mode 100644 index 0000000000..1bc9548b6f --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateSequenceStatement.java @@ -0,0 +1,87 @@ +package com.alibaba.druid.sql.dialect.oracle.ast.stmt; + +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 OracleCreateSequenceStatement extends OracleStatementImpl { + + private static final long serialVersionUID = 1L; + private SQLName name; + + private SQLExpr startWith; + private SQLExpr incrementBy; + private SQLExpr maxValue; + + private Boolean cycle; + private Boolean cache; + private Boolean order; + + @Override + public void accept0(OracleASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, name); + acceptChild(visitor, startWith); + acceptChild(visitor, incrementBy); + acceptChild(visitor, maxValue); + } + visitor.endVisit(this); + } + + public SQLName getName() { + return name; + } + + public void setName(SQLName name) { + this.name = name; + } + + public SQLExpr getStartWith() { + return startWith; + } + + public void setStartWith(SQLExpr startWith) { + this.startWith = startWith; + } + + public SQLExpr getIncrementBy() { + return incrementBy; + } + + public void setIncrementBy(SQLExpr incrementBy) { + this.incrementBy = incrementBy; + } + + public SQLExpr getMaxValue() { + return maxValue; + } + + public void setMaxValue(SQLExpr maxValue) { + this.maxValue = maxValue; + } + + public Boolean getCycle() { + return cycle; + } + + public void setCycle(Boolean cycle) { + this.cycle = cycle; + } + + public Boolean getCache() { + return cache; + } + + public void setCache(Boolean cache) { + this.cache = cache; + } + + public Boolean getOrder() { + return order; + } + + public void setOrder(Boolean order) { + this.order = order; + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateTableStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateTableStatement.java index 0726b5c3bc..542eb4561b 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateTableStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateTableStatement.java @@ -1,44 +1,62 @@ package com.alibaba.druid.sql.dialect.oracle.ast.stmt; -import java.util.ArrayList; -import java.util.List; - import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; import com.alibaba.druid.sql.ast.statement.SQLSelect; +import com.alibaba.druid.sql.dialect.oracle.ast.clause.OraclePartitioningClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleStorageClause; import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; import com.alibaba.druid.sql.visitor.SQLASTVisitor; public class OracleCreateTableStatement extends SQLCreateTableStatement implements OracleStatement { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - private SQLName tablespace; + private SQLName tablespace; - private SQLSelect select; + private SQLSelect select; - private boolean inMemoryMetadata; + private boolean inMemoryMetadata; - private boolean cursorSpecificSegment; + private boolean cursorSpecificSegment; // NOPARALLEL - private Boolean parallel; + private Boolean parallel; - private OracleStorageClause storage; + private OracleStorageClause storage; - private boolean organizationIndex = false; + private boolean organizationIndex = false; - private SQLExpr ptcfree; - private SQLExpr pctused; - private SQLExpr initrans; - private SQLExpr maxtrans; + private SQLExpr ptcfree; + private SQLExpr pctused; + private SQLExpr initrans; + private SQLExpr maxtrans; - private Boolean logging; - private Boolean compress; - private boolean onCommit; - private boolean preserveRows; + private Boolean logging; + private Boolean compress; + private boolean onCommit; + private boolean preserveRows; + + private Boolean cache; + + private OraclePartitioningClause partitioning; + + public OraclePartitioningClause getPartitioning() { + return partitioning; + } + + public void setPartitioning(OraclePartitioningClause partitioning) { + this.partitioning = partitioning; + } + + public Boolean getCache() { + return cache; + } + + public void setCache(Boolean cache) { + this.cache = cache; + } public boolean isOnCommit() { return onCommit; @@ -171,6 +189,7 @@ public class OracleCreateTableStatement extends SQLCreateTableStatement implemen this.acceptChild(visitor, tablespace); this.acceptChild(visitor, select); this.acceptChild(visitor, storage); + this.acceptChild(visitor, partitioning); } visitor.endVisit(this); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleDeleteStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleDeleteStatement.java index 114c27f0bb..e645dff506 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleDeleteStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleDeleteStatement.java @@ -29,7 +29,7 @@ public class OracleDeleteStatement extends SQLDeleteStatement { private static final long serialVersionUID = 1L; private boolean only = false; - private String alias; + private final List hints = new ArrayList(); private OracleReturningClause returning = null; @@ -72,11 +72,5 @@ public class OracleDeleteStatement extends SQLDeleteStatement { this.only = only; } - public String getAlias() { - return this.alias; - } - - public void setAlias(String alias) { - this.alias = alias; - } + } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleExitStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleExitStatement.java new file mode 100644 index 0000000000..9d35a7d26f --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleExitStatement.java @@ -0,0 +1,27 @@ +package com.alibaba.druid.sql.dialect.oracle.ast.stmt; + +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; + +public class OracleExitStatement extends OracleStatementImpl { + + private static final long serialVersionUID = 1L; + private SQLExpr when; + + public SQLExpr getWhen() { + return when; + } + + public void setWhen(SQLExpr when) { + this.when = when; + } + + @Override + public void accept0(OracleASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, when); + } + visitor.endVisit(this); + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleLoopStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleLoopStatement.java new file mode 100644 index 0000000000..479fc6c32d --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleLoopStatement.java @@ -0,0 +1,31 @@ +package com.alibaba.druid.sql.dialect.oracle.ast.stmt; + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; + +public class OracleLoopStatement extends OracleStatementImpl { + + private static final long serialVersionUID = 1L; + + private List statements = new ArrayList(); + + @Override + public void accept0(OracleASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, statements); + } + visitor.endVisit(this); + } + + public List getStatements() { + return statements; + } + + public void setStatements(List statements) { + this.statements = statements; + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleCreateTableParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleCreateTableParser.java index 93a9537dcb..9fee6ddaf4 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleCreateTableParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleCreateTableParser.java @@ -1,9 +1,14 @@ package com.alibaba.druid.sql.dialect.oracle.parser; +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLName; +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.OracleStorageClause; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateTableStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelect; import com.alibaba.druid.sql.parser.Lexer; +import com.alibaba.druid.sql.parser.ParserException; import com.alibaba.druid.sql.parser.SQLCreateTableParser; import com.alibaba.druid.sql.parser.Token; @@ -48,6 +53,14 @@ public class OracleCreateTableParser extends SQLCreateTableParser { lexer.nextToken(); stmt.setLogging(Boolean.TRUE); continue; + } else if (identifierEquals("CACHE")) { + lexer.nextToken(); + stmt.setCache(Boolean.TRUE); + continue; + } else if (identifierEquals("NOCACHE")) { + lexer.nextToken(); + stmt.setCache(Boolean.FALSE); + continue; } else if (identifierEquals("NOCOMPRESS")) { lexer.nextToken(); stmt.setCompress(Boolean.FALSE); @@ -117,6 +130,92 @@ public class OracleCreateTableParser extends SQLCreateTableParser { lexer.nextToken(); stmt.setMaxtrans(this.exprParser.expr()); continue; + } else if (identifierEquals("PARTITION")) { + lexer.nextToken(); + accept(Token.BY); + + if (identifierEquals("RANGE")) { + lexer.nextToken(); + accept(Token.LPAREN); + OraclePartitionByRangeClause clause = new OraclePartitionByRangeClause(); + for (;;) { + SQLName column = this.exprParser.name(); + clause.getColumns().add(column); + + if (lexer.token() == Token.COMMA) { + lexer.nextToken(); + continue; + } + + break; + } + accept(Token.RPAREN); + + if (identifierEquals("INTERVAL")) { + lexer.nextToken(); + clause.setInterval(this.exprParser.expr()); + } + + if (identifierEquals("STORE")) { + lexer.nextToken(); + accept(Token.IN); + accept(Token.LPAREN); + for (;;) { + SQLName tablespace = this.exprParser.name(); + clause.getStoreIn().add(tablespace); + + if (lexer.token() == Token.COMMA) { + lexer.nextToken(); + continue; + } + + break; + } + accept(Token.RPAREN); + } + + accept(Token.LPAREN); + + for (;;) { + acceptIdentifier("PARTITION"); + OracleRangeValuesClause range = new OracleRangeValuesClause(); + range.setName(this.exprParser.name()); + + accept(Token.VALUES); + acceptIdentifier("LESS"); + acceptIdentifier("THAN"); + + accept(Token.LPAREN); + for (;;) { + SQLExpr rangeValue = this.exprParser.expr(); + range.getValues().add(rangeValue); + + if (lexer.token() == Token.COMMA) { + lexer.nextToken(); + continue; + } + + break; + } + accept(Token.RPAREN); + + clause.getRanges().add(range); + + if (lexer.token() == Token.COMMA) { + lexer.nextToken(); + continue; + } + + break; + } + + accept(Token.RPAREN); + + stmt.setPartitioning(clause); + continue; + } else { + throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); + } } break; } 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 1b291f8716..92d304a7e4 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 @@ -28,6 +28,7 @@ import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr; import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; import com.alibaba.druid.sql.ast.expr.SQLNumberExpr; +import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr; import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; import com.alibaba.druid.sql.ast.expr.SQLUnaryExpr; import com.alibaba.druid.sql.ast.expr.SQLUnaryOperator; @@ -73,6 +74,8 @@ public class OracleExprParser extends SQLExprParser { + + public boolean allowStringAdditive = false; /** @@ -274,7 +277,7 @@ public class OracleExprParser extends SQLExprParser { } public SQLExpr primaryRest(SQLExpr expr) throws ParserException { - if (lexer.token() == Token.IDENTIFIER) { + if (lexer.token() == Token.IDENTIFIER && expr instanceof SQLNumericLiteralExpr) { String ident = lexer.stringVal(); if (ident.length() == 1) { char unit = ident.charAt(0); @@ -313,9 +316,14 @@ public class OracleExprParser extends SQLExprParser { OracleDbLinkExpr dblink = new OracleDbLinkExpr(); dblink.setExpr(expr); - String link = lexer.stringVal(); - accept(Token.IDENTIFIER); - dblink.setDbLink(link); + if (lexer.token() == Token.BANG) { + dblink.setDbLink("!"); + lexer.nextToken(); + } else { + String link = lexer.stringVal(); + accept(Token.IDENTIFIER); + dblink.setDbLink(link); + } expr = dblink; } 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 bc7e9b3fe4..b8eb629354 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 @@ -10,6 +10,8 @@ import com.alibaba.druid.sql.parser.Lexer; import com.alibaba.druid.sql.parser.SQLParseException; import com.alibaba.druid.sql.parser.Token; +import static com.alibaba.druid.sql.parser.LayoutCharacters.EOI; + public class OracleLexer extends Lexer { public final static Keywords DEFAULT_ORACLE_KEYWORDS; @@ -271,6 +273,8 @@ public class OracleLexer extends Lexer { } sp++; break; + } else if (ch == EOI) { + break; } if (ch == '\r') { 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 5c9165f9d5..534b2d1cfc 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 @@ -61,8 +61,10 @@ 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.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.OracleFileSpecification; @@ -74,6 +76,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleInsertStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLabelStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLockTableStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLockTableStatement.LockMode; +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; @@ -237,6 +240,17 @@ public class OracleStatementParser extends SQLStatementParser { statementList.add(this.parseException()); continue; } + + if (identifierEquals("EXIT")) { + lexer.nextToken(); + OracleExitStatement stmt = new OracleExitStatement(); + if (lexer.token() == Token.WHEN) { + lexer.nextToken(); + stmt.setWhen(this.exprParser.expr()); + } + statementList.add(stmt); + continue; + } if (lexer.token() == Token.IDENTIFIER) { if (identifierEquals("EXPLAIN")) { @@ -281,6 +295,10 @@ public class OracleStatementParser extends SQLStatementParser { statementList.add(this.parseFor()); continue; } + if (lexer.token() == Token.LOOP) { + statementList.add(this.parseLoop()); + continue; + } if (lexer.token() == Token.IF) { statementList.add(this.parseIf()); continue; @@ -313,7 +331,7 @@ public class OracleStatementParser extends SQLStatementParser { statementList.add(stmt); continue; } - + throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); } } @@ -372,6 +390,17 @@ 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); + return stmt; + } public SQLStatement parseGrant() { accept(Token.GRANT); @@ -1362,4 +1391,47 @@ public class OracleStatementParser extends SQLStatementParser { return stmt; } + public OracleCreateSequenceStatement parseCreateSequence(boolean acceptCreate) { + if (acceptCreate) { + accept(Token.CREATE); + } + + acceptIdentifier("SEQUENCE"); + + OracleCreateSequenceStatement stmt = new OracleCreateSequenceStatement(); + stmt.setName(this.exprParser.name()); + + for (;;) { + if (lexer.token() == Token.START) { + lexer.nextToken(); + accept(Token.WITH); + stmt.setStartWith(this.exprParser.expr()); + continue; + } else if (identifierEquals("INCREMENT")) { + lexer.nextToken(); + accept(Token.BY); + stmt.setIncrementBy(this.exprParser.expr()); + continue; + } else if (identifierEquals("CACHE")) { + lexer.nextToken(); + stmt.setCache(Boolean.TRUE); + continue; + } else if (identifierEquals("NOCACHE")) { + lexer.nextToken(); + stmt.setCache(Boolean.FALSE); + continue; + } else if (identifierEquals("CYCLE")) { + lexer.nextToken(); + stmt.setCycle(Boolean.TRUE); + continue; + } else if (identifierEquals("NOCYCLE")) { + lexer.nextToken(); + stmt.setCycle(Boolean.FALSE); + continue; + } + break; + } + + 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 8523b695d6..61c86d5b7f 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 @@ -19,11 +19,13 @@ import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.QueryPartitio import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.ReturnRowsClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleErrorLoggingClause; 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; @@ -65,9 +67,11 @@ 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.OracleCreateSequenceStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateTableStatement; 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.OracleFileSpecification; @@ -80,6 +84,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleIfStatement.ElseIf; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleInsertStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLabelStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLockTableStatement; +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.OracleMergeStatement.MergeInsertClause; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement.MergeUpdateClause; @@ -1303,4 +1308,53 @@ public class OracleASTVIsitorAdapter extends SQLASTVisitorAdapter implements Ora } + @Override + public boolean visit(OracleCreateSequenceStatement x) { + return true; + } + + @Override + public void endVisit(OracleCreateSequenceStatement x) { + + } + + @Override + public boolean visit(OracleRangeValuesClause x) { + return true; + } + + @Override + public void endVisit(OracleRangeValuesClause x) { + + } + + @Override + public boolean visit(OraclePartitionByRangeClause x) { + return true; + } + + @Override + public void endVisit(OraclePartitionByRangeClause x) { + + } + @Override + public boolean visit(OracleLoopStatement x) { + return true; + } + + @Override + public void endVisit(OracleLoopStatement x) { + + } + + @Override + public boolean visit(OracleExitStatement x) { + return true; + } + + @Override + public void endVisit(OracleExitStatement 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 730e112383..1e214e6b6f 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 @@ -26,11 +26,13 @@ import com.alibaba.druid.sql.dialect.oracle.ast.clause.GroupingSetExpr; import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleErrorLoggingClause; 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.expr.OracleAggregateExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalytic; @@ -71,9 +73,11 @@ 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.OracleCreateSequenceStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateTableStatement; 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.OracleFileSpecification; @@ -86,6 +90,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleIfStatement.ElseIf; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleInsertStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLabelStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLockTableStatement; +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.OracleMultiInsertStatement.ConditionalInsertClause; @@ -575,4 +580,24 @@ public interface OracleASTVisitor extends SQLASTVisitor { boolean visit(OracleTruncateStatement x); void endVisit(OracleTruncateStatement x); + + boolean visit(OracleCreateSequenceStatement x); + + void endVisit(OracleCreateSequenceStatement x); + + boolean visit(OracleRangeValuesClause x); + + void endVisit(OracleRangeValuesClause x); + + boolean visit(OraclePartitionByRangeClause x); + + void endVisit(OraclePartitionByRangeClause x); + + boolean visit(OracleLoopStatement x); + + void endVisit(OracleLoopStatement x); + + boolean visit(OracleExitStatement x); + + void endVisit(OracleExitStatement 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 1cd2bd592a..b478f6642a 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 @@ -34,7 +34,6 @@ import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource.JoinType; import com.alibaba.druid.sql.ast.statement.SQLSelect; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; -import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement; import com.alibaba.druid.sql.dialect.oracle.ast.OracleHint; import com.alibaba.druid.sql.dialect.oracle.ast.OracleOrderBy; import com.alibaba.druid.sql.dialect.oracle.ast.clause.CycleClause; @@ -56,11 +55,13 @@ import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.ReferenceMode import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.ReturnRowsClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleErrorLoggingClause; 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.expr.OracleAggregateExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalytic; @@ -106,9 +107,11 @@ 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.OracleCreateSequenceStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateTableStatement; 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.OracleFileSpecification; @@ -121,6 +124,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleIfStatement.ElseIf; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleInsertStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLabelStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLockTableStatement; +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.OracleMergeStatement.MergeInsertClause; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement.MergeUpdateClause; @@ -1928,7 +1932,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS @Override public boolean visit(OracleExplainStatement x) { - print("XPLAIN PLAN"); + print("EXPLAIN PLAN"); incrementIndent(); println(); if (x.getStatementId() != null) { @@ -2430,6 +2434,12 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS print(" NOPARALLEL"); } + if (x.getCache() == Boolean.TRUE) { + print(" CACHE"); + } else if (x.getCache() == Boolean.FALSE) { + print(" NOCACHE"); + } + if (x.getCompress() == Boolean.TRUE) { print(" COMPRESS"); } else if (x.getCompress() == Boolean.FALSE) { @@ -2454,6 +2464,11 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS if (x.isPreserveRows()) { print(" PRESERVE ROWS"); } + + if (x.getPartitioning() != null) { + println(); + x.getPartitioning().accept(this); + } if (x.getSelect() != null) { println(); @@ -2751,4 +2766,143 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS public void endVisit(OracleTruncateStatement x) { } + + @Override + public boolean visit(OracleCreateSequenceStatement x) { + print("CREATE SEQUENCE "); + x.getName().accept(this); + + if (x.getStartWith() != null) { + print(" START WITH "); + x.getStartWith().accept(this); + } + + if (x.getIncrementBy() != null) { + print(" INCREMENT BY "); + x.getIncrementBy().accept(this); + } + + if (x.getMaxValue() != null) { + print(" MAXVALUE "); + x.getMaxValue().accept(this); + } + + if (x.getCycle() != null) { + if (x.getCycle().booleanValue()) { + print(" CYCLE"); + } else { + print(" NOCYCLE"); + } + } + + if (x.getCache() != null) { + if (x.getCache().booleanValue()) { + print(" CACHE"); + } else { + print(" NOCACHE"); + } + } + + return false; + } + + @Override + public void endVisit(OracleCreateSequenceStatement x) { + + } + + @Override + public boolean visit(OracleRangeValuesClause x) { + print("PARTITION "); + x.getName().accept(this); + print(" VALUES LESS THAN ("); + printAndAccept(x.getValues(), ", "); + print(")"); + return false; + } + + @Override + public void endVisit(OracleRangeValuesClause x) { + + } + + @Override + public boolean visit(OraclePartitionByRangeClause x) { + print("PARTITION BY RANGE ("); + printAndAccept(x.getColumns(), ", "); + print(")"); + + if (x.getInterval() != null) { + print(" INTERVAL "); + x.getInterval().accept(this); + } + + if (x.getStoreIn().size() > 0) { + print(" STORE IN ("); + printAndAccept(x.getStoreIn(), ", "); + print(")"); + } + + + println(); + print("("); + incrementIndent(); + for (int i = 0, size = x.getRanges().size(); i < size; ++i) { + if (i != 0) { + print(","); + } + println(); + x.getRanges().get(i).accept(this); + } + decrementIndent(); + println(); + print(")"); + return false; + } + + @Override + public void endVisit(OraclePartitionByRangeClause x) { + + } + + @Override + public boolean visit(OracleLoopStatement x) { + print("LOOP"); + incrementIndent(); + println(); + + for (int i = 0, size = x.getStatements().size(); i < size; ++i) { + SQLStatement item = x.getStatements().get(i); + item.setParent(x); + item.accept(this); + if (i != size - 1) { + println(); + } + } + + decrementIndent(); + println(); + print("END LOOP"); + return false; + } + + @Override + public void endVisit(OracleLoopStatement x) { + + } + + @Override + public boolean visit(OracleExitStatement x) { + print("EXIT"); + if (x.getWhen() != null) { + print(" WHEN "); + x.getWhen().accept(this); + } + return false; + } + + @Override + public void endVisit(OracleExitStatement 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 7d80475054..08a52ff7aa 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 @@ -38,6 +38,8 @@ import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.QueryPartitio import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.ReturnRowsClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleErrorLoggingClause; 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.PartitionExtensionClause; import com.alibaba.druid.sql.dialect.oracle.ast.clause.SampleClause; @@ -84,9 +86,11 @@ 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.OracleCreateSequenceStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateTableStatement; 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.OracleFileSpecification; @@ -99,6 +103,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleIfStatement.ElseIf; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleInsertStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLabelStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLockTableStatement; +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.OracleMergeStatement.MergeInsertClause; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement.MergeUpdateClause; @@ -1652,15 +1657,15 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle public void endVisit(AsOfSnapshotClause x) { } - + @Override public boolean visit(OracleAlterViewStatement x) { return false; } - + @Override public void endVisit(OracleAlterViewStatement x) { - + } @Override @@ -1670,7 +1675,7 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle @Override public void endVisit(OracleAlterTableMoveTablespace x) { - + } @Override @@ -1680,16 +1685,17 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle @Override public void endVisit(OracleSizeExpr x) { - + } + @Override public boolean visit(OracleFileSpecification x) { return false; } - + @Override public void endVisit(OracleFileSpecification x) { - + } @Override @@ -1699,7 +1705,7 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle @Override public void endVisit(OracleAlterTablespaceAddDataFile x) { - + } @Override @@ -1709,7 +1715,7 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle @Override public void endVisit(OracleAlterTablespaceStatement x) { - + } @Override @@ -1719,6 +1725,56 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle @Override public void endVisit(OracleTruncateStatement x) { + + } + + @Override + public boolean visit(OracleCreateSequenceStatement x) { + return false; + } + + @Override + public void endVisit(OracleCreateSequenceStatement x) { + + } + + @Override + public boolean visit(OracleRangeValuesClause x) { + return false; + } + + @Override + public void endVisit(OracleRangeValuesClause x) { + + } + + @Override + public boolean visit(OraclePartitionByRangeClause x) { + return false; + } + + @Override + public void endVisit(OraclePartitionByRangeClause x) { + + } + + @Override + public boolean visit(OracleLoopStatement x) { + return true; + } + + @Override + public void endVisit(OracleLoopStatement x) { + + } + + @Override + public boolean visit(OracleExitStatement x) { + return true; + } + + @Override + public void endVisit(OracleExitStatement x) { } } 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 ba0beedfcf..ca5f6b1756 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -59,7 +59,6 @@ import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition; import com.alibaba.druid.sql.ast.statement.SQLPrimaryKey; import com.alibaba.druid.sql.ast.statement.SQLSelect; import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem; -import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OraclePrimaryKey; public class SQLExprParser extends SQLParser { diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java index 516aca0e8a..a1ebfa8051 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java @@ -95,7 +95,7 @@ public class SQLParser { lexer.nextToken(); } else if (lexer.token() == Token.YEAR || lexer.token() == Token.DAY || lexer.token() == Token.TIME || lexer.token() == Token.MONTH || lexer.token() == Token.CASE || lexer.token() == Token.AT - || lexer.token() == Token.TIMESTAMP) { + || lexer.token() == Token.TIMESTAMP || lexer.token() == Token.LOG) { alias = lexer.token.name(); lexer.nextToken(); } diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java index 7c44940454..da3805881d 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java @@ -202,6 +202,10 @@ public class SQLStatementParser extends SQLParser { 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) { @@ -288,11 +292,17 @@ public class SQLStatementParser extends SQLParser { return createTableParser.parseCrateTable(false); } else if (token == Token.INDEX || token == Token.UNIQUE) { return parseCreateIndex(false); + } else if (identifierEquals("SEQUENCE")) { + return parseCreateSequence(false); } 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()); } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java index 6e0d3e39da..a0e49480eb 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java @@ -66,32 +66,32 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { public final static String ATTR_COLUMN = "_column_"; private Mode mode; - + public TableStat getTableStat(String ident) { return getTableStat(ident, null); } - + public Column addColumn(String tableName, String columnName) { tableName = handleName(tableName); columnName = handleName(columnName); - + Column column = new Column(tableName, columnName); columns.add(column); return column; } public TableStat getTableStat(String tableName, String alias) { - if (variants.containsKey(tableName)){ + if (variants.containsKey(tableName)) { return null; } - + tableName = handleName(tableName); TableStat stat = tableStats.get(tableName); if (stat == null) { stat = new TableStat(); tableStats.put(new TableStat.Name(tableName), stat); if (alias != null) { - aliasMap.put(alias, tableName); + aliasMap.put(alias, tableName); } } return stat; @@ -100,9 +100,9 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { private String handleName(String ident) { ident = ident.replaceAll("\"", ""); ident = ident.replaceAll(" ", ""); - + ident = aliasWrap(ident); - + return ident; } @@ -323,6 +323,10 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { table = aliasMap.get(table); } + if (variants.containsKey(table)) { + return null; + } + if (table != null) { return new Column(table, column); } @@ -353,6 +357,10 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { if (table != null) { return new Column(table, column); } + + if (variants.containsKey(column)) { + return null; + } return new Column("UNKNOWN", column); } @@ -524,8 +532,13 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { protected String aliasWrap(String name) { Map aliasMap = getAliasMap(); - if (aliasMap.containsKey(name)) { - return aliasMap.get(name); + + if (aliasMap != null) { + for (Map.Entry entry : aliasMap.entrySet()) { + if (entry.getKey().equalsIgnoreCase(name)) { + return entry.getValue(); + } + } } return name; @@ -757,10 +770,14 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { setMode(x, Mode.Delete); - String ident = x.getTableName().toString(); - setCurrentTable(ident); + String tableName = x.getTableName().toString(); + setCurrentTable(tableName); - TableStat stat = getTableStat(ident); + if (x.getAlias() != null) { + this.aliasMap.put(x.getAlias(), tableName); + } + + TableStat stat = getTableStat(tableName); stat.incrementDeleteCount(); accept(x.getWhere()); @@ -802,13 +819,13 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { } String tableName = x.getName().toString(); - + TableStat stat = getTableStat(tableName); stat.incrementCreateCount(); setCurrentTable(x, tableName); accept(x.getTableElementList()); - + restoreCurrentTable(x); return false; diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest5.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest5.java new file mode 100644 index 0000000000..ada16ff093 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest5.java @@ -0,0 +1,59 @@ +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 OracleBlockTest5 extends OracleTest { + + public void test_0() throws Exception { + String sql = "declare l_cnt number; " + + // + "begin l_cnt := 0;" + + // + " for c1 in (select id || '' id" +// + " from escrow_trade" + // + " where out_order_id in" + // + " (select out_order_id from tab_ipay_out_order_ids)" + // + " ) " + // + " loop" + // + " update ipay_contract" + // + " set is_chargeback = 'N'" + // + " where out_ref = c1.id and is_chargeback <> 'N'; l_cnt := l_cnt + 1; if (mod(l_cnt, 200) = 0) then commit; end if; dbms_application_info.set_client_info(l_cnt || ' rows updated!'); end loop; commit; exception when others then raise;" + + " rollback; " + // + "end;;"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(3, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("escrow_trade"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("tab_ipay_out_order_ids"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("ipay_contract"))); + + Assert.assertEquals(7, visitor.getColumns().size()); + Assert.assertEquals(2, visitor.getConditions().size()); + +// Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("departments", "department_id"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest6.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest6.java new file mode 100644 index 0000000000..04cb90d0bf --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleBlockTest6.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 OracleBlockTest6 extends OracleTest { + + public void test_0() throws Exception { + String sql = "declare" + // + " l_line varchar2(32767);" + // + " l_done number;" + // + " l_buffer varchar2(32767) := '';" + // + " l_lengthbuffer number := 0;" + // + " l_lengthline number := 0; " + // + "begin" + // + " loop" + // + " dbms_output.get_line( l_line, l_done );" + // + " if (l_buffer is null) then" + // + " l_lengthbuffer := 0;" + // + " else" + // + " l_lengthbuffer := length(l_buffer);" + // + " end if;" + // + " if (l_line is null) then" + // + " l_lengthline := 0;" + // + " else" + // + " l_lengthline := length(l_line);" + // + " end if;" + // + " exit when l_lengthbuffer + l_lengthline > :maxbytes " + // + " OR l_lengthbuffer + l_lengthline > 32767 OR l_done = 1;" + // + " l_buffer := l_buffer || l_line || chr(10);" + // + " end loop;" + // + " :done := l_done;" + // + " :buffer := l_buffer;" + // + " :line := l_line; " + // + "end;"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(0, visitor.getTables().size()); + +// Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("escrow_trade"))); + + Assert.assertEquals(0, visitor.getColumns().size()); + Assert.assertEquals(0, visitor.getConditions().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("departments", "department_id"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateSequenceTest.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateSequenceTest.java new file mode 100644 index 0000000000..6c1e52207a --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateSequenceTest.java @@ -0,0 +1,49 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleCreateSequenceTest extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "CREATE SEQUENCE customers_seq" + // + " START WITH 1000" + // + " INCREMENT BY 1" + // + " NOCACHE" + // + " NOCYCLE;"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(0, visitor.getTables().size()); + + // Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("cdc.en_complaint_ipr_stat_fdt0"))); + + Assert.assertEquals(0, visitor.getColumns().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "*"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest10.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest10.java new file mode 100644 index 0000000000..4b865d6293 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest10.java @@ -0,0 +1,47 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleCreateTableTest10 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "create global temporary table sys.ora_temp_1_ds_16247 on commit preserve rows cache noparallel " + // + "as " + // + "select /*+ no_parallel(t) no_parallel_index(t) dbms_stats cursor_sharing_exact use_weak_name_resl dynamic_sampling(0) no_monitoring */\"OBJ#\",\"INTCOL#\",\"SAVTIME\",\"FLAGS\",\"NULL_CNT\",\"MINIMUM\",\"MAXIMUM\",\"DISTCNT\",\"DENSITY\",\"LOWVAL\",\"HIVAL\",\"AVGCLN\",\"SAMPLE_DISTCNT\",\"SAMPLE_SIZE\",\"TIMESTAMP#\",\"SPARE1\",\"SPARE2\",\"SPARE3\",\"SPARE4\",\"SPARE5\",\"SPARE6\",SYS_EXTRACT_UTC(\"SAVTIME\") SYS_DS_ALIAS_22 from \"SYS\".\"WRI$_OPTSTAT_HISTHEAD_HISTORY\" sample ( 5.8764601401) t where 1 = 2"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(2, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("sys.ora_temp_1_ds_16247"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("SYS.WRI$_OPTSTAT_HISTHEAD_HISTORY"))); + + Assert.assertEquals(21, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("SYS.WRI$_OPTSTAT_HISTHEAD_HISTORY", "OBJ#"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest11.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest11.java new file mode 100644 index 0000000000..dcb50288d7 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCreateTableTest11.java @@ -0,0 +1,83 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleCreateTableTest11 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "create table zfj_en_click(" + // + "P_M CHAR(6), KEYWORD VARCHAR2(256), " + // + "REGION_NAME VARCHAR2(100), " + // + "COUNTRY_ACCORD_NAME VARCHAR2(256), " + // + "P_NAME VARCHAR2(256), " + // + "P_VALUE VARCHAR2(256), " + // + "CLICK_CNT NUMBER" + // + ") " + // + "partition by range (p_m) " + // + "(" + // + "partition part_201108 values less than('201109')," + // + "partition part_201109 values less than('201110')," + // + "partition part_201110 values less than('201111'), " + // + "partition part_201111 values less than('201112'), " + // + "partition part_201112 values less than('201201'), " + // + "partition part_201201 values less than('201202'), " + // + "partition part_201202 values less than('201203'), " + // + "partition part_201203 values less than('201204'), " + // + "partition part_201204 values less than('201205'), " + // + "partition part_201205 values less than('201206'), " + // + "partition part_201206 values less than('201207'), " + // + "partition part_201207 values less than('201208'), " + // + "partition part_201208 values less than('201209'), " + // + "partition part_201209 values less than('201210'), " + // + "partition part_201210 values less than('201211'), " + // + "partition part_201211 values less than('201212'), " + // + "partition part_201212 values less than('201301'), " + // + "partition part_201301 values less than('201302'), " + // + "partition part_201302 values less than('201303'), " + // + "partition part_201303 values less than('201304'), " + // + "partition part_201304 values less than('201305'), " + // + "partition part_201305 values less than('201306'), " + // + "partition part_201306 values less than('201307') " + // + ") "; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("zfj_en_click"))); + + Assert.assertEquals(7, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("zfj_en_click", "P_M"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("zfj_en_click", "KEYWORD"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("zfj_en_click", "REGION_NAME"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("zfj_en_click", "COUNTRY_ACCORD_NAME"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("zfj_en_click", "P_NAME"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("zfj_en_click", "P_VALUE"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("zfj_en_click", "CLICK_CNT"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleDeleteTest.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleDeleteTest.java new file mode 100644 index 0000000000..1938f12e42 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleDeleteTest.java @@ -0,0 +1,46 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleDeleteTest extends OracleTest { + + public void test_0() throws Exception { + String sql = "delete from BILLING_LOG_MONITOR log where log.guid in (" + // + "'wb_xinmin.zhao_test121','wb_xinmin.zhao_test122'" + // + ",'wb_xinmin.zhao_test123','wb_xinmin.zhao_test124'" + ")"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + + Assert.assertEquals(1, visitor.getTables().size()); + Assert.assertEquals(1, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("BILLING_LOG_MONITOR"))); + // Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees"))); + // + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("BILLING_LOG_MONITOR", "guid"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "salary"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "commission_pct"))); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleExplainTest3.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleExplainTest3.java new file mode 100644 index 0000000000..7b54fda079 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleExplainTest3.java @@ -0,0 +1,45 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleExplainTest3 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "explain plan for select 'enaliint'||m.login_id from vaccount v, company c, member m where m.company_id = c.id and v.id = c.id and v.status = 'enabled' and (v.service_type = 'cgs' or v.service_type = 'tp' or v.service_type = 'hkgs' or v.service_type = 'twgs') and m.company_id > 0 and m.status = 'enabled' and m.gmt_create > c.gmt_modified"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(0, visitor.getTables().size()); + +// Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("\"DUAL\""))); + + Assert.assertEquals(0, visitor.getColumns().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "*"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "YEAR"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pivot_table", "order_mode"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleInsertTest8.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleInsertTest8.java new file mode 100644 index 0000000000..91e7fbada7 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleInsertTest8.java @@ -0,0 +1,50 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleInsertTest8 extends OracleTest { + + public void test_0() throws Exception { + String sql = "insert into AV_INFO_NEW (ID, GMT_CREATE, GMT_MODIFIED, COMPANY_ID, COMPANY_NAME_CN, COMPANY_NAME_EN, COMPANY_COUNTRY, " + + " COMPANY_PROVINCE, COMPANY_CITY, COMPANY_ADDR_CN, COMPANY_ADDR_EN, MEMBER_SEX, MEMBER_CN_NAME, MEMBER_FIRST_NAME, MEMBER_LAST_NAME," + + " MEMBER_PHONE_COUNTRY, MEMBER_PHONE_AREA, MEMBER_PHONE_NUMBER, MEMBER_JOB_TITLE_CN, MEMBER_JOB_TITLE_EN, MEMBER_DEPT_EN, " + + " MEMBER_DEPT_CN, LINK_EMAIL, STATUS, AV_PROVIDER, AV_ORIGIN)" + + " values (1000236058, sysdate, sysdate, 1300904670, '��������5''TW'" + + ", 'Yunnan', 'sadf', '4r7V', 'fdgtg', 'M', '�����info_name4', 'Fnameinfo_name4'" + + ", '33', '4444', '6666', '���fgsgsdfg', 'fggtgth', '�������������', null, 'zeus'" + ")"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + + Assert.assertEquals(9, visitor.getTables().size()); + Assert.assertEquals(42, visitor.getColumns().size()); + + // Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("raises"))); + // Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees"))); + // + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "employee_id"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "salary"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "commission_pct"))); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleInsertTest9.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleInsertTest9.java new file mode 100644 index 0000000000..859146fe1e --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleInsertTest9.java @@ -0,0 +1,48 @@ +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 OracleInsertTest9 extends OracleTest { + + public void test_0() throws Exception { + String sql = "INSERT INTO \"ZFJ_EN_CLICK\" \"A1\" (" + // + "\"P_M\",\"KEYWORD\",\"REGION_NAME\"," + // + "\"COUNTRY_ACCORD_NAME\",\"P_NAME\",\"P_VALUE\",\"CLICK_CNT\"" + // + ") " + "SELECT \"A2\".\"P_M\",\"A2\".\"KEYWORD\",\"A2\".\"REGION_NAME\"" + // + " ,\"A2\".\"COUNTRY_NAME\",\"A2\".\"P_NAME\",\"A2\".\"P_VALUE\",\"A2\".\"CLICK_CNT\" " + // + "FROM \"ZFJ_EN_CLICK_201202\"@! \"A2\""; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + + Assert.assertEquals(2, visitor.getTables().size()); + Assert.assertEquals(14, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("ZFJ_EN_CLICK"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("ZFJ_EN_CLICK_201202@!"))); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("ZFJ_EN_CLICK", "P_M"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "commission_pct"))); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest32.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest32.java new file mode 100644 index 0000000000..7e5b716c2d --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest32.java @@ -0,0 +1,45 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleSelectTest32 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "select * from ESCROW_LOGISTICS t -- where received_status <>'not_received ' and received_status <>'received' "; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("ESCROW_LOGISTICS"))); + + Assert.assertEquals(1, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("ESCROW_LOGISTICS", "*"))); + +// Assert.assertTrue(visitor.getOrderByColumns().contains(new TableStat.Column("employees", "last_name"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest33.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest33.java new file mode 100644 index 0000000000..ac3356f247 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest33.java @@ -0,0 +1,47 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleSelectTest33 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "SELECT /*+ Q1647000 NO_EXPAND ROWID(A1) */ " + // + "A1.\"PRODUCT_ID\",A1.\"SUMMARY\",A1.\"DESCRIPTION\",A1.\"DESCRIPTION2\" " + // + "FROM \"ALIBABA1949\".\"WS_PRODUCT_DETAIL\" PX_GRANULE(0, BLOCK_RANGE, DYNAMIC) A1"; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(1, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("ESCROW_LOGISTICS"))); + + Assert.assertEquals(1, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("ESCROW_LOGISTICS", "*"))); + +// Assert.assertTrue(visitor.getOrderByColumns().contains(new TableStat.Column("employees", "last_name"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest34.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest34.java new file mode 100644 index 0000000000..0504d3dc31 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest34.java @@ -0,0 +1,59 @@ +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 OracleSelectTest34 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "select t.logistics_no, t.event_date, t.country, t.province" + // + " , t.city,t.address, t.area_code,t.received_status " + // + "from wl_tracking t " + // + "where t.logistics_no in ( " + // + " select el.logistics_no " + // + " from escrow_logistics el" + // + " where rownum <= 20" + // + " and el.gmt_send between to_date ('2011-9-1', 'yyyy-mm-dd') " + // + " and to_date ('2011-11-30 23:59:59','yyyy-mm-dd hh24:mi:ss')" + // + " and el.received_status = 'received'" + // + " and el.goods_direction = 'send_goods'" + // + " and el.country = 'US'" + // + " and el.logistics_company in ('Hongkong Post Air Mail','Hongkong Post Air Parcel','China Post Air Mail','China Post Air Parcel')" + + " and el.recv_status_desc is null) and t.event_date is not null order by t.logistics_no, t.event_date"; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(2, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("wl_tracking"))); + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("escrow_logistics"))); + + Assert.assertEquals(15, visitor.getColumns().size()); + +// Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("ESCROW_LOGISTICS", "*"))); + + // Assert.assertTrue(visitor.getOrderByColumns().contains(new TableStat.Column("employees", "last_name"))); + } +} diff --git a/src/test/java/com/alibaba/druid/sql/TestMigrate.java b/src/test/java/com/alibaba/druid/sql/TestMigrate.java new file mode 100644 index 0000000000..5cd09494b9 --- /dev/null +++ b/src/test/java/com/alibaba/druid/sql/TestMigrate.java @@ -0,0 +1,346 @@ +package com.alibaba.druid.sql; + +import java.sql.Connection; +import java.sql.Date; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import junit.framework.Assert; +import oracle.jdbc.OracleStatement; + +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.fastjson.JSON; + +public class TestMigrate extends OracleTest { + + private String jdbcUrl; + private String user; + private String password; + private DruidDataSource dataSource; + + public void setUp() throws Exception { + jdbcUrl = "jdbc:oracle:thin:@10.20.149.18:1521:emdb"; + user = "wardon"; + password = "wardon"; + + dataSource = new DruidDataSource(); + dataSource.setInitialSize(1); + dataSource.setUrl(jdbcUrl); + dataSource.setUsername(user); + dataSource.setPassword(password); + dataSource.setMaxActive(50); + dataSource.setPoolPreparedStatements(true); + dataSource.setMaxOpenPreparedStatements(100); + } + + private int updateCount = 0; + + public void updateRecord(String sqlId, String result) throws Exception { + Connection conn = dataSource.getConnection(); + + PreparedStatement stmt = conn.prepareStatement("UPDATE db_day_sql_fulltext SET SQL_PARSE_RESULT = ? WHERE sql_id = ?"); + + stmt.setString(1, result); + stmt.setString(2, sqlId); + + int updateCount = stmt.executeUpdate(); + if (updateCount < 1) { + throw new Exception(); + } + + stmt.close(); + + conn.close(); + + System.out.println((this.updateCount++) + " : " + sqlId); + } + + + public void schemaStatInternal(Record r) throws Exception { + String sql = r.getSqlText(); + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + + Assert.assertEquals(1, statementList.size()); + // print(statementList); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + StringBuffer buf = new StringBuffer(); + buf.append("Tables : " + visitor.getTables().toString()); + buf.append("\nColumns : " + visitor.getColumns().toString()); + buf.append("\nCoditions : " + visitor.getConditions().toString()); + buf.append("\nrelationships " + visitor.getRelationships().toString()); + + System.out.println(buf.toString()); + + System.out.println(); + System.out.println(); + System.out.println(); + + updateRecord(r.getSqlId(), buf.toString()); + } + + public void clearResult() throws Exception { + Connection conn = dataSource.getConnection(); + + Statement stmt = conn.createStatement(); + + stmt.execute("DELETE FROM db_day_sql_fulltext"); + stmt.close(); + conn.close(); + } + + public void test_migrate() throws Exception { + Connection conn = dataSource.getConnection(); + + int count = 0; + { + String sql = "SELECT COUNT(*) FROM db_day_sqltext"; + Statement stmt = conn.createStatement(); + + ResultSet rs = stmt.executeQuery(sql); + rs.next(); + count = rs.getInt(1); + rs.close(); + stmt.close(); + } + System.out.println("COUNT : " + count); + + clearResult(); + + String sql = "SELECT SNAP_DATE, DBNAME, SQL_ID, PIECE, SQL_TEXT" + // + " , COMMAND_TYPE, LAST_SNAP_DATE, DB_PK, SQL_PARSE_RESULT " + // + " FROM db_day_sqltext " + // + " WHERE snap_date = trunc(sysdate) " + // + " ORDER BY db_pk, sql_id, piece"; + + Statement stmt = conn.createStatement(); + OracleStatement oracleStmt = stmt.unwrap(OracleStatement.class); + oracleStmt.setRowPrefetch(1000); + ResultSet rs = stmt.executeQuery(sql); + + List list = new ArrayList(); + Record r = null; + + String lastSqlId = null; + int i = 0; + int j = 0; + while (rs.next()) { + j++; + Date d1 = rs.getDate(1); + String s2 = rs.getString(2); + String sqlId = rs.getString(3); + + if (lastSqlId == null || !lastSqlId.equals(sqlId)) { + if (r != null) { + System.out.println((i++) + "/" + j + " : " + r.getSqlId()); + System.out.println(); + + try { + setInfo(r); + } catch (Throwable e) { + e.printStackTrace(); + } + + list.add(r); + if (list.size() > 100) { + insert(list); + list.clear(); + } + } + + r = new Record(); + r.setSnapshotDate(d1); + r.setDbName(s2); + r.setSqlId(sqlId); + r.setPiece(rs.getInt(4)); + r.setSqlText(rs.getString(5)); + + r.setCommandType(rs.getInt(6)); + r.setLastSnapshotDate(rs.getDate(7)); + r.setDbPk(rs.getLong(8)); + } else { + String part = rs.getString(5); + + if (part == null) { + continue; + } + + if (part != null) { + r.appendSqlText(part); + } + + } + lastSqlId = sqlId; + } + + insert(list); + rs.close(); + stmt.close(); + + conn.close(); + } + + public void setInfo(Record r) { + OracleStatementParser parser = new OracleStatementParser(r.getSqlText()); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + + Assert.assertEquals(1, statementList.size()); + // print(statementList); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + StringBuffer buf = new StringBuffer(); + buf.append("Tables : " + visitor.getTables().toString()); + buf.append("\nColumns : " + visitor.getColumns().toString()); + buf.append("\nCoditions : " + visitor.getConditions().toString()); + buf.append("\nrelationships " + visitor.getRelationships().toString()); + + r.setResult(buf.toString()); + + } + + public void insert(List list) throws Exception { + if (list.size() == 0) { + return; + } + + String sql = "INSERT INTO db_day_sql_fulltext " + // + "(SNAP_DATE, DBNAME, SQL_ID, PIECE, SQL_TEXT" + // + ", COMMAND_TYPE, LAST_SNAP_DATE, DB_PK, SQL_PARSE_RESULT)" + // + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; + Connection conn = dataSource.getConnection(); + + PreparedStatement stmt = conn.prepareStatement(sql); + + for (Record r : list) { + stmt.setDate(1, r.getSnapshotDate()); + stmt.setString(2, r.getDbName()); + stmt.setString(3, r.getSqlId()); + stmt.setInt(4, r.getPiece()); + stmt.setString(5, r.getSqlText()); + + stmt.setInt(6, r.getCommandType()); + stmt.setDate(7, r.getLastSnapshotDate()); + stmt.setLong(8, r.getDbPk()); + stmt.setString(9, r.getResult()); + + stmt.addBatch(); + } + stmt.executeBatch(); + + stmt.close(); + + conn.close(); + } + + public static class Record { + + private Date snapshotDate; + private String dbName; + private String sqlId; + private StringBuffer sqlText = new StringBuffer(); + private Integer piece; + private Integer commandType; + private Date lastSnapshotDate; + private Long dbPk; + private String result; + + public String getResult() { + return result; + } + + public void setResult(String result) { + this.result = result; + } + + public Date getSnapshotDate() { + return snapshotDate; + } + + public void setSnapshotDate(Date snapshotDate) { + this.snapshotDate = snapshotDate; + } + + public String getDbName() { + return dbName; + } + + public void setDbName(String dbName) { + this.dbName = dbName; + } + + public String getSqlId() { + return sqlId; + } + + public void setSqlId(String sqlId) { + this.sqlId = sqlId; + } + + public String getSqlText() { + return sqlText.toString(); + } + + public void setSqlText(String sqlText) { + if (sqlText == null) { + sqlText = ""; + } + this.sqlText = new StringBuffer(sqlText); + } + + public void appendSqlText(String sqlText) { + this.sqlText.append(sqlText); + } + + public Integer getPiece() { + return piece; + } + + public void setPiece(Integer piece) { + this.piece = piece; + } + + public Integer getCommandType() { + return commandType; + } + + public void setCommandType(Integer commandType) { + this.commandType = commandType; + } + + public Date getLastSnapshotDate() { + return lastSnapshotDate; + } + + public void setLastSnapshotDate(Date lastSnapshotDate) { + this.lastSnapshotDate = lastSnapshotDate; + } + + public Long getDbPk() { + return dbPk; + } + + public void setDbPk(Long dbPk) { + this.dbPk = dbPk; + } + + public String toString() { + return JSON.toJSONString(this); + } + } +} diff --git a/src/test/java/com/alibaba/druid/sql/TestTransform.java b/src/test/java/com/alibaba/druid/sql/TestTransform.java index e9d5169a1b..d40e3659fa 100644 --- a/src/test/java/com/alibaba/druid/sql/TestTransform.java +++ b/src/test/java/com/alibaba/druid/sql/TestTransform.java @@ -76,7 +76,7 @@ public class TestTransform extends OracleTest { System.out.println((this.updateCount++) + " : " + sqlId); } - public void f_test_transform() throws Exception { + public void test_transform() throws Exception { Connection conn = dataSource.getConnection(); @@ -131,7 +131,7 @@ public class TestTransform extends OracleTest { try { schemaStatInternal(r); } catch (Throwable e) { - // e.printStackTrace(); +// e.printStackTrace(); } } rs.close(); @@ -147,7 +147,7 @@ public class TestTransform extends OracleTest { try { schemaStatInternal(r); } catch (Exception e) { - e.printStackTrace(); +// e.printStackTrace(); } } }); @@ -155,6 +155,13 @@ public class TestTransform extends OracleTest { public void schemaStatInternal(Record r) throws Exception { String sql = r.getSqlText(); + + sql = sql.replaceAll("5'HK'", "5''HK'"); + sql = sql.replaceAll("5'TW'", "5''TW'"); + sql = sql.replaceAll("5'CN'", "5''CN'"); + sql = sql.replaceAll("\\Qnull, 'zeus')\\E", "', null, 'zeus')"); + sql = sql.replaceAll("\\Q--+use_hash(v c m)\\E", ""); + sql = sql.replaceAll("\\Q--+ordered use_hash(v c m)\\E", ""); OracleStatementParser parser = new OracleStatementParser(sql); List statementList = parser.parseStatementList(); @@ -191,7 +198,7 @@ public class TestTransform extends OracleTest { conn.close(); } - public void test_migrate() throws Exception { + public void f_test_migrate() throws Exception { Connection conn = dataSource.getConnection(); int count = 0; @@ -239,7 +246,7 @@ public class TestTransform extends OracleTest { try { setInfo(r); - } catch (Exception e) { + } catch (Throwable e) { e.printStackTrace(); } @@ -390,6 +397,9 @@ public class TestTransform extends OracleTest { } public void setSqlText(String sqlText) { + if (sqlText == null) { + sqlText = ""; + } this.sqlText = new StringBuffer(sqlText); }