From 915854c7c8456ad229d1ec9dc0ead7c39aae0c96 Mon Sep 17 00:00:00 2001 From: wenshao Date: Sun, 23 Apr 2017 16:26:06 +0800 Subject: [PATCH] refactor sql parser for oracle Hierarchical clause. --- .../ast/statement/SQLSelectQueryBlock.java | 46 +++++++++++++++++ .../ast/stmt/OracleSelectQueryBlock.java | 12 +---- .../oracle/parser/OracleSelectParser.java | 33 ++++--------- .../oracle/visitor/OracleASTVisitor.java | 5 -- .../visitor/OracleASTVisitorAdapter.java | 12 ----- .../oracle/visitor/OracleOutputVisitor.java | 49 +++++++------------ .../visitor/OracleSchemaStatVisitor.java | 12 ----- .../visitor/OracleASTVisitorAdapterTest.java | 2 - 8 files changed, 77 insertions(+), 94 deletions(-) diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectQueryBlock.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectQueryBlock.java index 2bba413ab8..48882933a4 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectQueryBlock.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectQueryBlock.java @@ -41,6 +41,12 @@ public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery protected SQLLimit limit; + // for oracle & oceanbase + protected SQLExpr startWith; + protected SQLExpr connectBy; + protected boolean prior = false; + protected boolean noCycle = false; + public SQLSelectQueryBlock(){ } @@ -198,12 +204,52 @@ public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery this.limit.setOffset(offset); } + public boolean isPrior() { + return prior; + } + + public void setPrior(boolean prior) { + this.prior = prior; + } + + public SQLExpr getStartWith() { + return this.startWith; + } + + public void setStartWith(SQLExpr startWith) { + if (startWith != null) { + startWith.setParent(this); + } + this.startWith = startWith; + } + + public SQLExpr getConnectBy() { + return this.connectBy; + } + + public void setConnectBy(SQLExpr connectBy) { + if (connectBy != null) { + connectBy.setParent(this); + } + this.connectBy = connectBy; + } + + public boolean isNoCycle() { + return this.noCycle; + } + + public void setNoCycle(boolean noCycle) { + this.noCycle = noCycle; + } + @Override protected void accept0(SQLASTVisitor visitor) { if (visitor.visit(this)) { acceptChild(visitor, this.selectList); acceptChild(visitor, this.from); acceptChild(visitor, this.where); + acceptChild(visitor, this.startWith); + acceptChild(visitor, this.connectBy); acceptChild(visitor, this.groupBy); } visitor.endVisit(this); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectQueryBlock.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectQueryBlock.java index 7f8031e645..d8cabbf2ed 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectQueryBlock.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectQueryBlock.java @@ -29,7 +29,6 @@ public class OracleSelectQueryBlock extends SQLSelectQueryBlock { private final List hints = new ArrayList(1); - private OracleSelectHierachicalQueryClause hierachicalQueryClause; private ModelClause modelClause; public OracleSelectQueryBlock(){ @@ -44,14 +43,6 @@ public class OracleSelectQueryBlock extends SQLSelectQueryBlock { this.modelClause = modelClause; } - public OracleSelectHierachicalQueryClause getHierachicalQueryClause() { - return this.hierachicalQueryClause; - } - - public void setHierachicalQueryClause(OracleSelectHierachicalQueryClause hierachicalQueryClause) { - this.hierachicalQueryClause = hierachicalQueryClause; - } - public List getHints() { return this.hints; } @@ -73,7 +64,8 @@ public class OracleSelectQueryBlock extends SQLSelectQueryBlock { acceptChild(visitor, this.into); acceptChild(visitor, this.from); acceptChild(visitor, this.where); - acceptChild(visitor, this.hierachicalQueryClause); + acceptChild(visitor, this.startWith); + acceptChild(visitor, this.connectBy); acceptChild(visitor, this.groupBy); acceptChild(visitor, this.modelClause); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java index d9544ac85d..d78b91c0eb 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java @@ -49,7 +49,6 @@ 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.stmt.OracleSelect; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectForUpdate; -import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectHierachicalQueryClause; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectJoin; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectPivot; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectQueryBlock; @@ -572,67 +571,55 @@ public class OracleSelectParser extends SQLSelectParser { } private void parseHierachical(OracleSelectQueryBlock queryBlock) { - OracleSelectHierachicalQueryClause hierachical = null; + if (lexer.token() == Token.CONNECT) { - hierachical = new OracleSelectHierachicalQueryClause(); lexer.nextToken(); accept(Token.BY); if (lexer.token() == Token.PRIOR) { lexer.nextToken(); - hierachical.setPrior(true); + queryBlock.setPrior(true); } if (identifierEquals("NOCYCLE")) { - hierachical.setNoCycle(true); + queryBlock.setNoCycle(true); lexer.nextToken(); if (lexer.token() == Token.PRIOR) { lexer.nextToken(); - hierachical.setPrior(true); + queryBlock.setPrior(true); } } - hierachical.setConnectBy(this.exprParser.expr()); + queryBlock.setConnectBy(this.exprParser.expr()); } if (lexer.token() == Token.START) { lexer.nextToken(); - if (hierachical == null) { - hierachical = new OracleSelectHierachicalQueryClause(); - } accept(Token.WITH); - hierachical.setStartWith(this.exprParser.expr()); + queryBlock.setStartWith(this.exprParser.expr()); } if (lexer.token() == Token.CONNECT) { - if (hierachical == null) { - hierachical = new OracleSelectHierachicalQueryClause(); - } - lexer.nextToken(); accept(Token.BY); if (lexer.token() == Token.PRIOR) { lexer.nextToken(); - hierachical.setPrior(true); + queryBlock.setPrior(true); } if (identifierEquals("NOCYCLE")) { - hierachical.setNoCycle(true); + queryBlock.setNoCycle(true); lexer.nextToken(); if (lexer.token() == Token.PRIOR) { lexer.nextToken(); - hierachical.setPrior(true); + queryBlock.setPrior(true); } } - hierachical.setConnectBy(this.exprParser.expr()); - } - - if (hierachical != null) { - queryBlock.setHierachicalQueryClause(hierachical); + queryBlock.setConnectBy(this.exprParser.expr()); } } 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 a1f7826291..c315544ffc 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 @@ -85,7 +85,6 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OraclePrimaryKey; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSavePointStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelect; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectForUpdate; -import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectHierachicalQueryClause; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectJoin; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectPivot; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectQueryBlock; @@ -119,8 +118,6 @@ public interface OracleASTVisitor extends SQLASTVisitor { void endVisit(OracleSelectForUpdate x); - void endVisit(OracleSelectHierachicalQueryClause x); - void endVisit(OracleSelectJoin x); void endVisit(OracleSelectPivot x); @@ -155,8 +152,6 @@ public interface OracleASTVisitor extends SQLASTVisitor { boolean visit(OracleSelectForUpdate x); - boolean visit(OracleSelectHierachicalQueryClause x); - boolean visit(OracleSelectJoin x); boolean visit(OracleSelectPivot x); 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 bcbfede91f..ff4effc6c5 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 @@ -94,7 +94,6 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OraclePrimaryKey; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSavePointStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelect; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectForUpdate; -import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectHierachicalQueryClause; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectJoin; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectPivot; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectPivot.Item; @@ -159,11 +158,6 @@ public class OracleASTVisitorAdapter extends SQLASTVisitorAdapter implements Ora } - @Override - public void endVisit(OracleSelectHierachicalQueryClause x) { - - } - @Override public void endVisit(OracleSelectJoin x) { @@ -252,12 +246,6 @@ public class OracleASTVisitorAdapter extends SQLASTVisitorAdapter implements Ora return true; } - @Override - public boolean visit(OracleSelectHierachicalQueryClause x) { - - return true; - } - @Override public boolean visit(OracleSelectJoin 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 3b1746c1a9..64cce5069b 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 @@ -110,7 +110,6 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OraclePrimaryKey; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSavePointStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelect; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectForUpdate; -import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectHierachicalQueryClause; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectJoin; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectPivot; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectPivot.Item; @@ -381,28 +380,6 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS return false; } - public boolean visit(OracleSelectHierachicalQueryClause x) { - if (x.getStartWith() != null) { - print0(ucase ? "START WITH " : "start with "); - x.getStartWith().accept(this); - println(); - } - - print0(ucase ? "CONNECT BY " : "connect by "); - - if (x.isNoCycle()) { - print0(ucase ? "NOCYCLE " : "nocycle "); - } - - if (x.isPrior()) { - print0(ucase ? "PRIOR " : "prior "); - } - - x.getConnectBy().accept(this); - - return false; - } - public boolean visit(OracleSelectJoin x) { x.getLeft().accept(this); @@ -550,9 +527,26 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS x.getWhere().accept(this); } - if (x.getHierachicalQueryClause() != null) { + SQLExpr startWith = x.getStartWith(), connectBy = x.getConnectBy(); + if (startWith != null || connectBy != null){ println(); - x.getHierachicalQueryClause().accept(this); + if (x.getStartWith() != null) { + print0(ucase ? "START WITH " : "start with "); + x.getStartWith().accept(this); + println(); + } + + print0(ucase ? "CONNECT BY " : "connect by "); + + if (x.isNoCycle()) { + print0(ucase ? "NOCYCLE " : "nocycle "); + } + + if (x.isPrior()) { + print0(ucase ? "PRIOR " : "prior "); + } + + x.getConnectBy().accept(this); } if (x.getGroupBy() != null) { @@ -785,11 +779,6 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS } - @Override - public void endVisit(OracleSelectHierachicalQueryClause x) { - - } - @Override public void endVisit(OracleSelectJoin 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 a4e6800068..972041568f 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 @@ -117,7 +117,6 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OraclePrimaryKey; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSavePointStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelect; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectForUpdate; -import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectHierachicalQueryClause; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectJoin; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectPivot; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectPivot.Item; @@ -378,11 +377,6 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle } - @Override - public void endVisit(OracleSelectHierachicalQueryClause x) { - - } - @Override public void endVisit(OracleSelectJoin x) { @@ -460,12 +454,6 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle return true; } - @Override - public boolean visit(OracleSelectHierachicalQueryClause x) { - - return true; - } - @Override public boolean visit(OracleSelectJoin x) { super.visit(x); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/visitor/OracleASTVisitorAdapterTest.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/visitor/OracleASTVisitorAdapterTest.java index 7438d73c6e..8d8d05c4df 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/visitor/OracleASTVisitorAdapterTest.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/visitor/OracleASTVisitorAdapterTest.java @@ -78,7 +78,6 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OraclePLSQLCommitStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OraclePrimaryKey; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSavePointStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectForUpdate; -import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectHierachicalQueryClause; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectPivot; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectQueryBlock; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectRestriction.CheckOption; @@ -102,7 +101,6 @@ public class OracleASTVisitorAdapterTest extends TestCase { new SQLDateExpr().accept(adapter); new OracleDbLinkExpr().accept(adapter); new OracleSelectForUpdate().accept(adapter); - new OracleSelectHierachicalQueryClause().accept(adapter); new OracleSelectPivot.Item().accept(adapter); new OracleSelectPivot().accept(adapter); new CheckOption().accept(adapter);